DPDK patches and discussions
 help / color / Atom feed
* [dpdk-dev] [PATCH] net/virtio: add link speed tuning
       [not found] <CGME20191212085020eucas1p1be6d915a6610edf182d2ab0294c2a903@eucas1p1.samsung.com>
@ 2019-12-12  8:50 ` Ivan Dyukov
       [not found]   ` <CGME20200329144330eucas1p13a2088777a9c1aa02bee18f2a56fb53c@eucas1p1.samsung.com>
                     ` (5 more replies)
  0 siblings, 6 replies; 359+ messages in thread
From: Ivan Dyukov @ 2019-12-12  8:50 UTC (permalink / raw)
  To: dev; +Cc: Ivan Dyukov

Some applications like pktgen use link_speed to calculate transmit
rate. It limits outcome traffic to hardcoded 10G.

This patch makes link_speed configurable at compile time.

Signed-off-by: Ivan Dyukov <i.dyukov@samsung.com>
---
 config/common_base                 |  1 +
 drivers/net/vhost/rte_eth_vhost.c  |  2 +-
 drivers/net/virtio/virtio_ethdev.c | 20 ++++++++++++++++----
 3 files changed, 18 insertions(+), 5 deletions(-)

diff --git a/config/common_base b/config/common_base
index 7dec7ed45..8589ca4ec 100644
--- a/config/common_base
+++ b/config/common_base
@@ -433,6 +433,7 @@ CONFIG_RTE_LIBRTE_AVP_DEBUG_BUFFERS=n
 # Compile burst-oriented VIRTIO PMD driver
 #
 CONFIG_RTE_LIBRTE_VIRTIO_PMD=y
+CONFIG_RTE_LIBRTE_VIRTIO_LINK_SPEED=10000
 CONFIG_RTE_LIBRTE_VIRTIO_DEBUG_RX=n
 CONFIG_RTE_LIBRTE_VIRTIO_DEBUG_TX=n
 CONFIG_RTE_LIBRTE_VIRTIO_DEBUG_DUMP=n
diff --git a/drivers/net/vhost/rte_eth_vhost.c b/drivers/net/vhost/rte_eth_vhost.c
index 46f01a7f4..38eaa5955 100644
--- a/drivers/net/vhost/rte_eth_vhost.c
+++ b/drivers/net/vhost/rte_eth_vhost.c
@@ -115,7 +115,7 @@ static struct internal_list_head internal_list =
 static pthread_mutex_t internal_list_lock = PTHREAD_MUTEX_INITIALIZER;
 
 static struct rte_eth_link pmd_link = {
-		.link_speed = 10000,
+		.link_speed = RTE_LIBRTE_VIRTIO_LINK_SPEED,
 		.link_duplex = ETH_LINK_FULL_DUPLEX,
 		.link_status = ETH_LINK_DOWN
 };
diff --git a/drivers/net/virtio/virtio_ethdev.c b/drivers/net/virtio/virtio_ethdev.c
index 044eb10a7..948091cc2 100644
--- a/drivers/net/virtio/virtio_ethdev.c
+++ b/drivers/net/virtio/virtio_ethdev.c
@@ -2371,7 +2371,7 @@ virtio_dev_link_update(struct rte_eth_dev *dev, __rte_unused int wait_to_complet
 
 	memset(&link, 0, sizeof(link));
 	link.link_duplex = ETH_LINK_FULL_DUPLEX;
-	link.link_speed  = ETH_SPEED_NUM_10G;
+	link.link_speed  = RTE_LIBRTE_VIRTIO_LINK_SPEED;
 	link.link_autoneg = ETH_LINK_FIXED;
 
 	if (!hw->started) {
@@ -2426,9 +2426,21 @@ virtio_dev_info_get(struct rte_eth_dev *dev, struct rte_eth_dev_info *dev_info)
 {
 	uint64_t tso_mask, host_features;
 	struct virtio_hw *hw = dev->data->dev_private;
-
-	dev_info->speed_capa = ETH_LINK_SPEED_10G; /* fake value */
-
+#if RTE_LIBRTE_VIRTIO_LINK_SPEED == ETH_LINK_SPEED_20G
+	dev_info->speed_capa = ETH_LINK_SPEED_20G;
+#elif RTE_LIBRTE_VIRTIO_LINK_SPEED == ETH_SPEED_NUM_25G
+	dev_info->speed_capa = ETH_LINK_SPEED_25G;
+#elif RTE_LIBRTE_VIRTIO_LINK_SPEED == ETH_SPEED_NUM_40G
+	dev_info->speed_capa = ETH_LINK_SPEED_40G;
+#elif RTE_LIBRTE_VIRTIO_LINK_SPEED == ETH_SPEED_NUM_50G
+	dev_info->speed_capa = ETH_LINK_SPEED_50G;
+#elif RTE_LIBRTE_VIRTIO_LINK_SPEED == ETH_SPEED_NUM_56G
+	dev_info->speed_capa = ETH_LINK_SPEED_56G;
+#elif RTE_LIBRTE_VIRTIO_LINK_SPEED == ETH_SPEED_NUM_100G
+	dev_info->speed_capa = ETH_LINK_SPEED_100G;
+#else
+	dev_info->speed_capa = ETH_LINK_SPEED_10G;
+#endif
 	dev_info->max_rx_queues =
 		RTE_MIN(hw->max_queue_pairs, VIRTIO_MAX_RX_QUEUES);
 	dev_info->max_tx_queues =
-- 
2.17.1


^ permalink raw reply	[flat|nested] 359+ messages in thread

* [dpdk-dev] [PATCH v7 0/5] net/virtio: add link speed devarg
       [not found]   ` <CGME20200329144330eucas1p13a2088777a9c1aa02bee18f2a56fb53c@eucas1p1.samsung.com>
@ 2020-03-29 14:42     ` Ivan Dyukov
       [not found]       ` <CGME20200329144333eucas1p2aa754e8de8f2ba01da656821c76eae9f@eucas1p2.samsung.com>
                         ` (4 more replies)
  0 siblings, 5 replies; 359+ messages in thread
From: Ivan Dyukov @ 2020-03-29 14:42 UTC (permalink / raw)
  To: dev, maxime.coquelin, i.dyukov, tiwei.bie, amorenoz,
	zhihong.wang, xiaolong.ye

v7 chagnes:
* rebased to latest master
* added support of VIRTIO_NET_F_SPEED_DUPLEX

v6 changes:
* fix code style

v5 changes:
* fixed code style
* fixed commit message and logging text

v4 changes:
* link_speed renamed to speed devarg
* speed devarg is added to virtio-user driver

v3 changes:
* link_speed devarg is added to virtio documentation


^ permalink raw reply	[flat|nested] 359+ messages in thread

* [dpdk-dev] [PATCH v7 1/5] net/virtio: refactor devargs parsing
       [not found]       ` <CGME20200329144333eucas1p2aa754e8de8f2ba01da656821c76eae9f@eucas1p2.samsung.com>
@ 2020-03-29 14:42         ` Ivan Dyukov
  0 siblings, 0 replies; 359+ messages in thread
From: Ivan Dyukov @ 2020-03-29 14:42 UTC (permalink / raw)
  To: dev, maxime.coquelin, i.dyukov, tiwei.bie, amorenoz,
	zhihong.wang, xiaolong.ye

refactor vdpa specific devargs parsing to more generic way

Signed-off-by: Ivan Dyukov <i.dyukov@samsung.com>
---
 drivers/net/virtio/virtio_ethdev.c | 34 +++++++++++++++++++++---------
 1 file changed, 24 insertions(+), 10 deletions(-)

diff --git a/drivers/net/virtio/virtio_ethdev.c b/drivers/net/virtio/virtio_ethdev.c
index f9d0ea70d..870ff7801 100644
--- a/drivers/net/virtio/virtio_ethdev.c
+++ b/drivers/net/virtio/virtio_ethdev.c
@@ -1957,16 +1957,18 @@ eth_virtio_dev_uninit(struct rte_eth_dev *eth_dev)
 }
 
 static int vdpa_check_handler(__rte_unused const char *key,
-		const char *value, __rte_unused void *opaque)
+		const char *value, void *ret_val)
 {
-	if (strcmp(value, "1"))
-		return -1;
+	if (strcmp(value, "1") == 0)
+		*(int *)ret_val = 1;
+	else
+		*(int *)ret_val = 0;
 
 	return 0;
 }
 
 static int
-vdpa_mode_selected(struct rte_devargs *devargs)
+virtio_dev_devargs_parse(struct rte_devargs *devargs, int *vdpa)
 {
 	struct rte_kvargs *kvlist;
 	const char *key = "vdpa";
@@ -1982,12 +1984,16 @@ vdpa_mode_selected(struct rte_devargs *devargs)
 	if (!rte_kvargs_count(kvlist, key))
 		goto exit;
 
-	/* vdpa mode selected when there's a key-value pair: vdpa=1 */
-	if (rte_kvargs_process(kvlist, key,
-				vdpa_check_handler, NULL) < 0) {
-		goto exit;
+	if (vdpa) {
+		/* vdpa mode selected when there's a key-value pair:
+		 * vdpa=1
+		 */
+		ret = rte_kvargs_process(kvlist, key,
+				vdpa_check_handler, vdpa);
+		if (ret < 0)
+			goto exit;
 	}
-	ret = 1;
+
 
 exit:
 	rte_kvargs_free(kvlist);
@@ -1997,8 +2003,16 @@ vdpa_mode_selected(struct rte_devargs *devargs)
 static int eth_virtio_pci_probe(struct rte_pci_driver *pci_drv __rte_unused,
 	struct rte_pci_device *pci_dev)
 {
+	int vdpa = 0;
+	int ret = 0;
+
+	ret = virtio_dev_devargs_parse(pci_dev->device.devargs, &vdpa);
+	if (ret < 0) {
+		PMD_INIT_LOG(ERR, "devargs parsing is failed");
+		return ret;
+	}
 	/* virtio pmd skips probe if device needs to work in vdpa mode */
-	if (vdpa_mode_selected(pci_dev->device.devargs))
+	if (vdpa == 1)
 		return 1;
 
 	return rte_eth_dev_pci_generic_probe(pci_dev, sizeof(struct virtio_hw),
-- 
2.17.1


^ permalink raw reply	[flat|nested] 359+ messages in thread

* [dpdk-dev] [PATCH v7 2/5] net/virtio: add link speed devarg
       [not found]       ` <CGME20200329144335eucas1p1b3962cf40116e2da679b99c26f3f8ed7@eucas1p1.samsung.com>
@ 2020-03-29 14:42         ` Ivan Dyukov
  0 siblings, 0 replies; 359+ messages in thread
From: Ivan Dyukov @ 2020-03-29 14:42 UTC (permalink / raw)
  To: dev, maxime.coquelin, i.dyukov, tiwei.bie, amorenoz,
	zhihong.wang, xiaolong.ye

Some applications like pktgen use link speed to calculate
transmission rate. It limits outcome traffic to hardcoded 10G.

This patch adds speed devarg which allows to configure
link speed of virtio device.

Signed-off-by: Ivan Dyukov <i.dyukov@samsung.com>
---
 doc/guides/nics/virtio.rst         |  7 +++
 drivers/net/virtio/virtio_ethdev.c | 97 +++++++++++++++++++++++++-----
 drivers/net/virtio/virtio_pci.h    |  1 +
 3 files changed, 89 insertions(+), 16 deletions(-)

diff --git a/doc/guides/nics/virtio.rst b/doc/guides/nics/virtio.rst
index d1f5fb898..0341907ef 100644
--- a/doc/guides/nics/virtio.rst
+++ b/doc/guides/nics/virtio.rst
@@ -356,6 +356,13 @@ Below devargs are supported by the PCI virtio driver:
     a virtio device needs to work in vDPA mode.
     (Default: 0 (disabled))
 
+#.  ``speed``:
+
+    It is used to specify link speed of virtio device. Link speed is a part of
+    link status structure. It could be requested by application using
+    rte_eth_link_get_nowait function.
+    (Default: 10000 (10G))
+
 Below devargs are supported by the virtio-user vdev:
 
 #.  ``path``:
diff --git a/drivers/net/virtio/virtio_ethdev.c b/drivers/net/virtio/virtio_ethdev.c
index 870ff7801..fe0e292ef 100644
--- a/drivers/net/virtio/virtio_ethdev.c
+++ b/drivers/net/virtio/virtio_ethdev.c
@@ -45,6 +45,10 @@ static int virtio_dev_promiscuous_enable(struct rte_eth_dev *dev);
 static int virtio_dev_promiscuous_disable(struct rte_eth_dev *dev);
 static int virtio_dev_allmulticast_enable(struct rte_eth_dev *dev);
 static int virtio_dev_allmulticast_disable(struct rte_eth_dev *dev);
+static uint32_t virtio_dev_speed_capa_get(uint32_t speed);
+static int virtio_dev_devargs_parse(struct rte_devargs *devargs,
+	int *vdpa,
+	uint32_t *speed);
 static int virtio_dev_info_get(struct rte_eth_dev *dev,
 				struct rte_eth_dev_info *dev_info);
 static int virtio_dev_link_update(struct rte_eth_dev *dev,
@@ -1861,6 +1865,7 @@ int
 eth_virtio_dev_init(struct rte_eth_dev *eth_dev)
 {
 	struct virtio_hw *hw = eth_dev->data->dev_private;
+	uint32_t speed = ETH_SPEED_NUM_10G;
 	int ret;
 
 	if (sizeof(struct virtio_net_hdr_mrg_rxbuf) > RTE_PKTMBUF_HEADROOM) {
@@ -1886,7 +1891,11 @@ eth_virtio_dev_init(struct rte_eth_dev *eth_dev)
 
 		return 0;
 	}
-
+	ret = virtio_dev_devargs_parse(eth_dev->device->devargs,
+		 NULL, &speed);
+	if (ret < 0)
+		return ret;
+	hw->speed = speed;
 	/*
 	 * Pass the information to the rte_eth_dev_close() that it should also
 	 * release the private port resources.
@@ -1956,6 +1965,7 @@ eth_virtio_dev_uninit(struct rte_eth_dev *eth_dev)
 	return 0;
 }
 
+
 static int vdpa_check_handler(__rte_unused const char *key,
 		const char *value, void *ret_val)
 {
@@ -1967,33 +1977,89 @@ static int vdpa_check_handler(__rte_unused const char *key,
 	return 0;
 }
 
+
+static uint32_t
+virtio_dev_speed_capa_get(uint32_t speed)
+{
+	switch (speed) {
+	case ETH_SPEED_NUM_10G:
+		return ETH_LINK_SPEED_10G;
+	case ETH_SPEED_NUM_20G:
+		return ETH_LINK_SPEED_20G;
+	case ETH_SPEED_NUM_25G:
+		return ETH_LINK_SPEED_25G;
+	case ETH_SPEED_NUM_40G:
+		return ETH_LINK_SPEED_40G;
+	case ETH_SPEED_NUM_50G:
+		return ETH_LINK_SPEED_50G;
+	case ETH_SPEED_NUM_56G:
+		return ETH_LINK_SPEED_56G;
+	case ETH_SPEED_NUM_100G:
+		return ETH_LINK_SPEED_100G;
+	default:
+		return 0;
+	}
+}
+
+
+#define VIRTIO_ARG_SPEED      "speed"
+#define VIRTIO_ARG_VDPA       "vdpa"
+
+
+static int
+link_speed_handler(const char *key __rte_unused,
+		const char *value, void *ret_val)
+{
+	uint32_t val;
+	if (!value || !ret_val)
+		return -EINVAL;
+	val = strtoul(value, NULL, 0);
+	/* validate input */
+	if (virtio_dev_speed_capa_get(val) == 0)
+		return -EINVAL;
+	*(uint32_t *)ret_val = val;
+
+	return 0;
+}
+
+
 static int
-virtio_dev_devargs_parse(struct rte_devargs *devargs, int *vdpa)
+virtio_dev_devargs_parse(struct rte_devargs *devargs, int *vdpa,
+	uint32_t *speed)
 {
 	struct rte_kvargs *kvlist;
-	const char *key = "vdpa";
 	int ret = 0;
 
 	if (devargs == NULL)
 		return 0;
 
 	kvlist = rte_kvargs_parse(devargs->args, NULL);
-	if (kvlist == NULL)
+	if (kvlist == NULL) {
+		PMD_INIT_LOG(ERR, "error when parsing param");
 		return 0;
-
-	if (!rte_kvargs_count(kvlist, key))
-		goto exit;
-
-	if (vdpa) {
+	}
+	if (vdpa && rte_kvargs_count(kvlist, VIRTIO_ARG_VDPA) == 1) {
 		/* vdpa mode selected when there's a key-value pair:
 		 * vdpa=1
 		 */
-		ret = rte_kvargs_process(kvlist, key,
+		ret = rte_kvargs_process(kvlist, VIRTIO_ARG_VDPA,
 				vdpa_check_handler, vdpa);
-		if (ret < 0)
+		if (ret < 0) {
+			PMD_INIT_LOG(ERR, "Failed to parse %s",
+				VIRTIO_ARG_VDPA);
 			goto exit;
+		}
+	}
+	if (speed && rte_kvargs_count(kvlist, VIRTIO_ARG_SPEED) == 1) {
+		ret = rte_kvargs_process(kvlist,
+					VIRTIO_ARG_SPEED,
+					link_speed_handler, speed);
+		if (ret < 0) {
+			PMD_INIT_LOG(ERR, "Failed to parse %s",
+					VIRTIO_ARG_SPEED);
+			goto exit;
+		}
 	}
-
 
 exit:
 	rte_kvargs_free(kvlist);
@@ -2006,7 +2072,7 @@ static int eth_virtio_pci_probe(struct rte_pci_driver *pci_drv __rte_unused,
 	int vdpa = 0;
 	int ret = 0;
 
-	ret = virtio_dev_devargs_parse(pci_dev->device.devargs, &vdpa);
+	ret = virtio_dev_devargs_parse(pci_dev->device.devargs, &vdpa, NULL);
 	if (ret < 0) {
 		PMD_INIT_LOG(ERR, "devargs parsing is failed");
 		return ret;
@@ -2385,7 +2451,7 @@ virtio_dev_link_update(struct rte_eth_dev *dev, __rte_unused int wait_to_complet
 
 	memset(&link, 0, sizeof(link));
 	link.link_duplex = ETH_LINK_FULL_DUPLEX;
-	link.link_speed  = ETH_SPEED_NUM_10G;
+	link.link_speed  = hw->speed;
 	link.link_autoneg = ETH_LINK_FIXED;
 
 	if (!hw->started) {
@@ -2440,8 +2506,7 @@ virtio_dev_info_get(struct rte_eth_dev *dev, struct rte_eth_dev_info *dev_info)
 {
 	uint64_t tso_mask, host_features;
 	struct virtio_hw *hw = dev->data->dev_private;
-
-	dev_info->speed_capa = ETH_LINK_SPEED_10G; /* fake value */
+	dev_info->speed_capa = virtio_dev_speed_capa_get(hw->speed);
 
 	dev_info->max_rx_queues =
 		RTE_MIN(hw->max_queue_pairs, VIRTIO_MAX_RX_QUEUES);
diff --git a/drivers/net/virtio/virtio_pci.h b/drivers/net/virtio/virtio_pci.h
index 7433d2f08..ed98e11c3 100644
--- a/drivers/net/virtio/virtio_pci.h
+++ b/drivers/net/virtio/virtio_pci.h
@@ -259,6 +259,7 @@ struct virtio_hw {
 	uint16_t    port_id;
 	uint8_t     mac_addr[RTE_ETHER_ADDR_LEN];
 	uint32_t    notify_off_multiplier;
+	uint32_t    speed;  /* link speed in MB */
 	uint8_t     *isr;
 	uint16_t    *notify_base;
 	struct virtio_pci_common_cfg *common_cfg;
-- 
2.17.1


^ permalink raw reply	[flat|nested] 359+ messages in thread

* [dpdk-dev] [PATCH v7 3/5] net/virtio-user: fix devargs parsing
       [not found]       ` <CGME20200329144337eucas1p2cc22be55d036822bf52dc69149d538af@eucas1p2.samsung.com>
@ 2020-03-29 14:42         ` Ivan Dyukov
  0 siblings, 0 replies; 359+ messages in thread
From: Ivan Dyukov @ 2020-03-29 14:42 UTC (permalink / raw)
  To: dev, maxime.coquelin, i.dyukov, tiwei.bie, amorenoz,
	zhihong.wang, xiaolong.ye

strtoull returns 0 if it fails to parse input string. It's ignored
in get_integer_arg.

This patch handles error cases for strtoull function.

Signed-off-by: Ivan Dyukov <i.dyukov@samsung.com>
---
 drivers/net/virtio/virtio_user_ethdev.c | 13 +++++++++----
 1 file changed, 9 insertions(+), 4 deletions(-)

diff --git a/drivers/net/virtio/virtio_user_ethdev.c b/drivers/net/virtio/virtio_user_ethdev.c
index e61af4068..a79f68a36 100644
--- a/drivers/net/virtio/virtio_user_ethdev.c
+++ b/drivers/net/virtio/virtio_user_ethdev.c
@@ -477,12 +477,17 @@ static int
 get_integer_arg(const char *key __rte_unused,
 		const char *value, void *extra_args)
 {
+	uint64_t integer = 0;
 	if (!value || !extra_args)
 		return -EINVAL;
-
-	*(uint64_t *)extra_args = strtoull(value, NULL, 0);
-
-	return 0;
+	errno = 0;
+	integer = strtoull(value, NULL, 0);
+	/* extra_args keeps default value, it should be replaced
+	 * only in case of successful parsing of the 'value' arg
+	 */
+	if (errno == 0)
+		*(uint64_t *)extra_args = integer;
+	return -errno;
 }
 
 static struct rte_eth_dev *
-- 
2.17.1


^ permalink raw reply	[flat|nested] 359+ messages in thread

* [dpdk-dev] [PATCH v7 4/5] net/virtio-user: adding link speed devarg
       [not found]       ` <CGME20200329144338eucas1p1842eae4822199508ae611b4ee3b60441@eucas1p1.samsung.com>
@ 2020-03-29 14:42         ` Ivan Dyukov
  0 siblings, 0 replies; 359+ messages in thread
From: Ivan Dyukov @ 2020-03-29 14:42 UTC (permalink / raw)
  To: dev, maxime.coquelin, i.dyukov, tiwei.bie, amorenoz,
	zhihong.wang, xiaolong.ye

virtio driver already parses speed devarg. virtio-user should add
it to list of valid devargs and call eth_virtio_dev_init function
which init speed value.

eth_virtio_dev_init already is called from virtio_user_pmd_probe
function. The only change is required to enable speed devargs:
adding speed to list of valid devargs.

Signed-off-by: Ivan Dyukov <i.dyukov@samsung.com>
---
 doc/guides/nics/virtio.rst              | 8 ++++++++
 drivers/net/virtio/virtio_user_ethdev.c | 5 ++++-
 2 files changed, 12 insertions(+), 1 deletion(-)

diff --git a/doc/guides/nics/virtio.rst b/doc/guides/nics/virtio.rst
index 0341907ef..6286286db 100644
--- a/doc/guides/nics/virtio.rst
+++ b/doc/guides/nics/virtio.rst
@@ -410,6 +410,14 @@ Below devargs are supported by the virtio-user vdev:
     It is used to enable virtio device packed virtqueue feature.
     (Default: 0 (disabled))
 
+#.  ``speed``:
+
+    It is used to specify link speed of virtio device. Link speed is a part of
+    link status structure. It could be requested by application using
+    rte_eth_link_get_nowait function.
+    (Default: 10000 (10G))
+
+
 Virtio paths Selection and Usage
 --------------------------------
 
diff --git a/drivers/net/virtio/virtio_user_ethdev.c b/drivers/net/virtio/virtio_user_ethdev.c
index a79f68a36..5b32d30fa 100644
--- a/drivers/net/virtio/virtio_user_ethdev.c
+++ b/drivers/net/virtio/virtio_user_ethdev.c
@@ -450,6 +450,8 @@ static const char *valid_args[] = {
 	VIRTIO_USER_ARG_IN_ORDER,
 #define VIRTIO_USER_ARG_PACKED_VQ      "packed_vq"
 	VIRTIO_USER_ARG_PACKED_VQ,
+#define VIRTIO_USER_ARG_SPEED          "speed"
+	VIRTIO_USER_ARG_SPEED,
 	NULL
 };
 
@@ -782,4 +784,5 @@ RTE_PMD_REGISTER_PARAM_STRING(net_virtio_user,
 	"server=<0|1> "
 	"mrg_rxbuf=<0|1> "
 	"in_order=<0|1> "
-	"packed_vq=<0|1>");
+	"packed_vq=<0|1> "
+	"speed=<int>");
-- 
2.17.1


^ permalink raw reply	[flat|nested] 359+ messages in thread

* [dpdk-dev] [PATCH v7 5/5] net/virtio: Support of VIRTIO_NET_F_SPEED_DUPLEX
       [not found]       ` <CGME20200329144339eucas1p19f866f53b24156a01ef54ec5e6bb8926@eucas1p1.samsung.com>
@ 2020-03-29 14:42         ` Ivan Dyukov
  0 siblings, 0 replies; 359+ messages in thread
From: Ivan Dyukov @ 2020-03-29 14:42 UTC (permalink / raw)
  To: dev, maxime.coquelin, i.dyukov, tiwei.bie, amorenoz,
	zhihong.wang, xiaolong.ye

This patch adds a support of VIRTIO_NET_F_SPEED_DUPLEX feature
for virtio driver.

There are few ways to specify speed of the link:
   'speed' devarg
   negotiate speed from qemu via VIRTIO_NET_F_SPEED_DUPLEX
The highest priority is devarg. If devarg is not specified,
drivers tries to negotiate it from qemu.

Signed-off-by: Ivan Dyukov <i.dyukov@samsung.com>
---
 drivers/net/virtio/virtio_ethdev.c | 26 +++++++++++++++++++++++---
 drivers/net/virtio/virtio_ethdev.h |  3 ++-
 drivers/net/virtio/virtio_pci.h    | 16 ++++++++++++++++
 3 files changed, 41 insertions(+), 4 deletions(-)

diff --git a/drivers/net/virtio/virtio_ethdev.c b/drivers/net/virtio/virtio_ethdev.c
index fe0e292ef..8a6e1933a 100644
--- a/drivers/net/virtio/virtio_ethdev.c
+++ b/drivers/net/virtio/virtio_ethdev.c
@@ -1662,7 +1662,8 @@ virtio_configure_intr(struct rte_eth_dev *dev)
 
 	return 0;
 }
-
+#define SPEED_UNKNOWN    0xffffffff
+#define DUPLEX_UNKNOWN   0xff
 /* reset device and renegotiate features if needed */
 static int
 virtio_init_device(struct rte_eth_dev *eth_dev, uint64_t req_features)
@@ -1718,6 +1719,25 @@ virtio_init_device(struct rte_eth_dev *eth_dev, uint64_t req_features)
 		     hw->mac_addr[0], hw->mac_addr[1], hw->mac_addr[2],
 		     hw->mac_addr[3], hw->mac_addr[4], hw->mac_addr[5]);
 
+	if (hw->speed == SPEED_UNKNOWN) {
+		if (vtpci_with_feature(hw, VIRTIO_NET_F_SPEED_DUPLEX)) {
+			config = &local_config;
+			vtpci_read_dev_config(hw,
+				offsetof(struct virtio_net_config, speed),
+				&config->speed, sizeof(config->speed));
+			vtpci_read_dev_config(hw,
+				offsetof(struct virtio_net_config, duplex),
+				&config->duplex, sizeof(config->duplex));
+			hw->speed = config->speed;
+			hw->duplex = config->duplex;
+		}
+	}
+	if (hw->speed == SPEED_UNKNOWN)
+		hw->speed = ETH_SPEED_NUM_10G;
+	if (hw->duplex == DUPLEX_UNKNOWN)
+		hw->duplex = ETH_LINK_FULL_DUPLEX;
+	PMD_INIT_LOG(DEBUG, "link speed = %d, duplex = %d",
+		hw->speed, hw->duplex);
 	if (vtpci_with_feature(hw, VIRTIO_NET_F_CTRL_VQ)) {
 		config = &local_config;
 
@@ -1865,7 +1885,7 @@ int
 eth_virtio_dev_init(struct rte_eth_dev *eth_dev)
 {
 	struct virtio_hw *hw = eth_dev->data->dev_private;
-	uint32_t speed = ETH_SPEED_NUM_10G;
+	uint32_t speed = SPEED_UNKNOWN;
 	int ret;
 
 	if (sizeof(struct virtio_net_hdr_mrg_rxbuf) > RTE_PKTMBUF_HEADROOM) {
@@ -2450,7 +2470,7 @@ virtio_dev_link_update(struct rte_eth_dev *dev, __rte_unused int wait_to_complet
 	struct virtio_hw *hw = dev->data->dev_private;
 
 	memset(&link, 0, sizeof(link));
-	link.link_duplex = ETH_LINK_FULL_DUPLEX;
+	link.link_duplex = hw->duplex;
 	link.link_speed  = hw->speed;
 	link.link_autoneg = ETH_LINK_FIXED;
 
diff --git a/drivers/net/virtio/virtio_ethdev.h b/drivers/net/virtio/virtio_ethdev.h
index cd8947656..febaf17a8 100644
--- a/drivers/net/virtio/virtio_ethdev.h
+++ b/drivers/net/virtio/virtio_ethdev.h
@@ -37,7 +37,8 @@
 	 1ULL << VIRTIO_F_RING_PACKED	  |	\
 	 1ULL << VIRTIO_F_IOMMU_PLATFORM  |	\
 	 1ULL << VIRTIO_F_ORDER_PLATFORM  |	\
-	 1ULL << VIRTIO_F_NOTIFICATION_DATA)
+	 1ULL << VIRTIO_F_NOTIFICATION_DATA | \
+	 1ULL << VIRTIO_NET_F_SPEED_DUPLEX)
 
 #define VIRTIO_PMD_SUPPORTED_GUEST_FEATURES	\
 	(VIRTIO_PMD_DEFAULT_GUEST_FEATURES |	\
diff --git a/drivers/net/virtio/virtio_pci.h b/drivers/net/virtio/virtio_pci.h
index ed98e11c3..1da3df940 100644
--- a/drivers/net/virtio/virtio_pci.h
+++ b/drivers/net/virtio/virtio_pci.h
@@ -141,6 +141,9 @@ struct virtnet_ctl;
  */
 #define VIRTIO_F_NOTIFICATION_DATA 38
 
+/* Device set linkspeed and duplex */
+#define VIRTIO_NET_F_SPEED_DUPLEX 63
+
 /* The Guest publishes the used index for which it expects an interrupt
  * at the end of the avail ring. Host should ignore the avail->flags field. */
 /* The Host publishes the avail index for which it expects a kick
@@ -260,6 +263,7 @@ struct virtio_hw {
 	uint8_t     mac_addr[RTE_ETHER_ADDR_LEN];
 	uint32_t    notify_off_multiplier;
 	uint32_t    speed;  /* link speed in MB */
+	uint8_t     duplex;
 	uint8_t     *isr;
 	uint16_t    *notify_base;
 	struct virtio_pci_common_cfg *common_cfg;
@@ -306,6 +310,18 @@ struct virtio_net_config {
 	uint16_t   status;
 	uint16_t   max_virtqueue_pairs;
 	uint16_t   mtu;
+	/*
+ 	 * speed, in units of 1Mb. All values 0 to INT_MAX are legal.
+	 * Any other value stands for unknown.
+	 */
+	uint32_t speed;
+	/*
+	 * 0x00 - half duplex
+	 * 0x01 - full duplex
+	 * Any other value stands for unknown.
+	 */
+	uint8_t duplex;
+
 } __attribute__((packed));
 
 /*
-- 
2.17.1


^ permalink raw reply	[flat|nested] 359+ messages in thread

* [dpdk-dev] [PATCH v8 0/5] net/virtio: add link speed devarg
       [not found]   ` <CGME20200330075825eucas1p2ea21598ea8ff13d8d8e0ea39c27a8a1e@eucas1p2.samsung.com>
@ 2020-03-30  7:57     ` Ivan Dyukov
       [not found]       ` <CGME20200330075827eucas1p2b4718ecf08cc7d20227befb4ce3a5675@eucas1p2.samsung.com>
                         ` (5 more replies)
  0 siblings, 6 replies; 359+ messages in thread
From: Ivan Dyukov @ 2020-03-30  7:57 UTC (permalink / raw)
  To: dev, maxime.coquelin, i.dyukov, tiwei.bie, amorenoz,
	zhihong.wang, xiaolong.ye


v8 changes:
* fix code style

v7 chagnes:
* rebased to latest master
* added support of VIRTIO_NET_F_SPEED_DUPLEX

v6 changes:
* fix code style

v5 changes:
* fixed code style
* fixed commit message and logging text

v4 changes:
* link_speed renamed to speed devarg
* speed devarg is added to virtio-user driver

v3 changes:
* link_speed devarg is added to virtio documentation



^ permalink raw reply	[flat|nested] 359+ messages in thread

* [dpdk-dev] [PATCH v8 1/5] net/virtio: refactor devargs parsing
       [not found]       ` <CGME20200330075827eucas1p2b4718ecf08cc7d20227befb4ce3a5675@eucas1p2.samsung.com>
@ 2020-03-30  7:57         ` Ivan Dyukov
  0 siblings, 0 replies; 359+ messages in thread
From: Ivan Dyukov @ 2020-03-30  7:57 UTC (permalink / raw)
  To: dev, maxime.coquelin, i.dyukov, tiwei.bie, amorenoz,
	zhihong.wang, xiaolong.ye

refactor vdpa specific devargs parsing to more generic way

Signed-off-by: Ivan Dyukov <i.dyukov@samsung.com>
---
 drivers/net/virtio/virtio_ethdev.c | 34 +++++++++++++++++++++---------
 1 file changed, 24 insertions(+), 10 deletions(-)

diff --git a/drivers/net/virtio/virtio_ethdev.c b/drivers/net/virtio/virtio_ethdev.c
index f9d0ea70d..870ff7801 100644
--- a/drivers/net/virtio/virtio_ethdev.c
+++ b/drivers/net/virtio/virtio_ethdev.c
@@ -1957,16 +1957,18 @@ eth_virtio_dev_uninit(struct rte_eth_dev *eth_dev)
 }
 
 static int vdpa_check_handler(__rte_unused const char *key,
-		const char *value, __rte_unused void *opaque)
+		const char *value, void *ret_val)
 {
-	if (strcmp(value, "1"))
-		return -1;
+	if (strcmp(value, "1") == 0)
+		*(int *)ret_val = 1;
+	else
+		*(int *)ret_val = 0;
 
 	return 0;
 }
 
 static int
-vdpa_mode_selected(struct rte_devargs *devargs)
+virtio_dev_devargs_parse(struct rte_devargs *devargs, int *vdpa)
 {
 	struct rte_kvargs *kvlist;
 	const char *key = "vdpa";
@@ -1982,12 +1984,16 @@ vdpa_mode_selected(struct rte_devargs *devargs)
 	if (!rte_kvargs_count(kvlist, key))
 		goto exit;
 
-	/* vdpa mode selected when there's a key-value pair: vdpa=1 */
-	if (rte_kvargs_process(kvlist, key,
-				vdpa_check_handler, NULL) < 0) {
-		goto exit;
+	if (vdpa) {
+		/* vdpa mode selected when there's a key-value pair:
+		 * vdpa=1
+		 */
+		ret = rte_kvargs_process(kvlist, key,
+				vdpa_check_handler, vdpa);
+		if (ret < 0)
+			goto exit;
 	}
-	ret = 1;
+
 
 exit:
 	rte_kvargs_free(kvlist);
@@ -1997,8 +2003,16 @@ vdpa_mode_selected(struct rte_devargs *devargs)
 static int eth_virtio_pci_probe(struct rte_pci_driver *pci_drv __rte_unused,
 	struct rte_pci_device *pci_dev)
 {
+	int vdpa = 0;
+	int ret = 0;
+
+	ret = virtio_dev_devargs_parse(pci_dev->device.devargs, &vdpa);
+	if (ret < 0) {
+		PMD_INIT_LOG(ERR, "devargs parsing is failed");
+		return ret;
+	}
 	/* virtio pmd skips probe if device needs to work in vdpa mode */
-	if (vdpa_mode_selected(pci_dev->device.devargs))
+	if (vdpa == 1)
 		return 1;
 
 	return rte_eth_dev_pci_generic_probe(pci_dev, sizeof(struct virtio_hw),
-- 
2.17.1


^ permalink raw reply	[flat|nested] 359+ messages in thread

* [dpdk-dev] [PATCH v8 2/5] net/virtio: add link speed devarg
       [not found]       ` <CGME20200330075829eucas1p1b21f029dafd6056b950bdd810fe8458e@eucas1p1.samsung.com>
@ 2020-03-30  7:57         ` Ivan Dyukov
  2020-04-01 10:57           ` Thomas Monjalon
  0 siblings, 1 reply; 359+ messages in thread
From: Ivan Dyukov @ 2020-03-30  7:57 UTC (permalink / raw)
  To: dev, maxime.coquelin, i.dyukov, tiwei.bie, amorenoz,
	zhihong.wang, xiaolong.ye

Some applications like pktgen use link speed to calculate
transmission rate. It limits outcome traffic to hardcoded 10G.

This patch adds speed devarg which allows to configure
link speed of virtio device.

Signed-off-by: Ivan Dyukov <i.dyukov@samsung.com>
---
 doc/guides/nics/virtio.rst         |  7 +++
 drivers/net/virtio/virtio_ethdev.c | 97 +++++++++++++++++++++++++-----
 drivers/net/virtio/virtio_pci.h    |  1 +
 3 files changed, 89 insertions(+), 16 deletions(-)

diff --git a/doc/guides/nics/virtio.rst b/doc/guides/nics/virtio.rst
index d1f5fb898..0341907ef 100644
--- a/doc/guides/nics/virtio.rst
+++ b/doc/guides/nics/virtio.rst
@@ -356,6 +356,13 @@ Below devargs are supported by the PCI virtio driver:
     a virtio device needs to work in vDPA mode.
     (Default: 0 (disabled))
 
+#.  ``speed``:
+
+    It is used to specify link speed of virtio device. Link speed is a part of
+    link status structure. It could be requested by application using
+    rte_eth_link_get_nowait function.
+    (Default: 10000 (10G))
+
 Below devargs are supported by the virtio-user vdev:
 
 #.  ``path``:
diff --git a/drivers/net/virtio/virtio_ethdev.c b/drivers/net/virtio/virtio_ethdev.c
index 870ff7801..fe0e292ef 100644
--- a/drivers/net/virtio/virtio_ethdev.c
+++ b/drivers/net/virtio/virtio_ethdev.c
@@ -45,6 +45,10 @@ static int virtio_dev_promiscuous_enable(struct rte_eth_dev *dev);
 static int virtio_dev_promiscuous_disable(struct rte_eth_dev *dev);
 static int virtio_dev_allmulticast_enable(struct rte_eth_dev *dev);
 static int virtio_dev_allmulticast_disable(struct rte_eth_dev *dev);
+static uint32_t virtio_dev_speed_capa_get(uint32_t speed);
+static int virtio_dev_devargs_parse(struct rte_devargs *devargs,
+	int *vdpa,
+	uint32_t *speed);
 static int virtio_dev_info_get(struct rte_eth_dev *dev,
 				struct rte_eth_dev_info *dev_info);
 static int virtio_dev_link_update(struct rte_eth_dev *dev,
@@ -1861,6 +1865,7 @@ int
 eth_virtio_dev_init(struct rte_eth_dev *eth_dev)
 {
 	struct virtio_hw *hw = eth_dev->data->dev_private;
+	uint32_t speed = ETH_SPEED_NUM_10G;
 	int ret;
 
 	if (sizeof(struct virtio_net_hdr_mrg_rxbuf) > RTE_PKTMBUF_HEADROOM) {
@@ -1886,7 +1891,11 @@ eth_virtio_dev_init(struct rte_eth_dev *eth_dev)
 
 		return 0;
 	}
-
+	ret = virtio_dev_devargs_parse(eth_dev->device->devargs,
+		 NULL, &speed);
+	if (ret < 0)
+		return ret;
+	hw->speed = speed;
 	/*
 	 * Pass the information to the rte_eth_dev_close() that it should also
 	 * release the private port resources.
@@ -1956,6 +1965,7 @@ eth_virtio_dev_uninit(struct rte_eth_dev *eth_dev)
 	return 0;
 }
 
+
 static int vdpa_check_handler(__rte_unused const char *key,
 		const char *value, void *ret_val)
 {
@@ -1967,33 +1977,89 @@ static int vdpa_check_handler(__rte_unused const char *key,
 	return 0;
 }
 
+
+static uint32_t
+virtio_dev_speed_capa_get(uint32_t speed)
+{
+	switch (speed) {
+	case ETH_SPEED_NUM_10G:
+		return ETH_LINK_SPEED_10G;
+	case ETH_SPEED_NUM_20G:
+		return ETH_LINK_SPEED_20G;
+	case ETH_SPEED_NUM_25G:
+		return ETH_LINK_SPEED_25G;
+	case ETH_SPEED_NUM_40G:
+		return ETH_LINK_SPEED_40G;
+	case ETH_SPEED_NUM_50G:
+		return ETH_LINK_SPEED_50G;
+	case ETH_SPEED_NUM_56G:
+		return ETH_LINK_SPEED_56G;
+	case ETH_SPEED_NUM_100G:
+		return ETH_LINK_SPEED_100G;
+	default:
+		return 0;
+	}
+}
+
+
+#define VIRTIO_ARG_SPEED      "speed"
+#define VIRTIO_ARG_VDPA       "vdpa"
+
+
+static int
+link_speed_handler(const char *key __rte_unused,
+		const char *value, void *ret_val)
+{
+	uint32_t val;
+	if (!value || !ret_val)
+		return -EINVAL;
+	val = strtoul(value, NULL, 0);
+	/* validate input */
+	if (virtio_dev_speed_capa_get(val) == 0)
+		return -EINVAL;
+	*(uint32_t *)ret_val = val;
+
+	return 0;
+}
+
+
 static int
-virtio_dev_devargs_parse(struct rte_devargs *devargs, int *vdpa)
+virtio_dev_devargs_parse(struct rte_devargs *devargs, int *vdpa,
+	uint32_t *speed)
 {
 	struct rte_kvargs *kvlist;
-	const char *key = "vdpa";
 	int ret = 0;
 
 	if (devargs == NULL)
 		return 0;
 
 	kvlist = rte_kvargs_parse(devargs->args, NULL);
-	if (kvlist == NULL)
+	if (kvlist == NULL) {
+		PMD_INIT_LOG(ERR, "error when parsing param");
 		return 0;
-
-	if (!rte_kvargs_count(kvlist, key))
-		goto exit;
-
-	if (vdpa) {
+	}
+	if (vdpa && rte_kvargs_count(kvlist, VIRTIO_ARG_VDPA) == 1) {
 		/* vdpa mode selected when there's a key-value pair:
 		 * vdpa=1
 		 */
-		ret = rte_kvargs_process(kvlist, key,
+		ret = rte_kvargs_process(kvlist, VIRTIO_ARG_VDPA,
 				vdpa_check_handler, vdpa);
-		if (ret < 0)
+		if (ret < 0) {
+			PMD_INIT_LOG(ERR, "Failed to parse %s",
+				VIRTIO_ARG_VDPA);
 			goto exit;
+		}
+	}
+	if (speed && rte_kvargs_count(kvlist, VIRTIO_ARG_SPEED) == 1) {
+		ret = rte_kvargs_process(kvlist,
+					VIRTIO_ARG_SPEED,
+					link_speed_handler, speed);
+		if (ret < 0) {
+			PMD_INIT_LOG(ERR, "Failed to parse %s",
+					VIRTIO_ARG_SPEED);
+			goto exit;
+		}
 	}
-
 
 exit:
 	rte_kvargs_free(kvlist);
@@ -2006,7 +2072,7 @@ static int eth_virtio_pci_probe(struct rte_pci_driver *pci_drv __rte_unused,
 	int vdpa = 0;
 	int ret = 0;
 
-	ret = virtio_dev_devargs_parse(pci_dev->device.devargs, &vdpa);
+	ret = virtio_dev_devargs_parse(pci_dev->device.devargs, &vdpa, NULL);
 	if (ret < 0) {
 		PMD_INIT_LOG(ERR, "devargs parsing is failed");
 		return ret;
@@ -2385,7 +2451,7 @@ virtio_dev_link_update(struct rte_eth_dev *dev, __rte_unused int wait_to_complet
 
 	memset(&link, 0, sizeof(link));
 	link.link_duplex = ETH_LINK_FULL_DUPLEX;
-	link.link_speed  = ETH_SPEED_NUM_10G;
+	link.link_speed  = hw->speed;
 	link.link_autoneg = ETH_LINK_FIXED;
 
 	if (!hw->started) {
@@ -2440,8 +2506,7 @@ virtio_dev_info_get(struct rte_eth_dev *dev, struct rte_eth_dev_info *dev_info)
 {
 	uint64_t tso_mask, host_features;
 	struct virtio_hw *hw = dev->data->dev_private;
-
-	dev_info->speed_capa = ETH_LINK_SPEED_10G; /* fake value */
+	dev_info->speed_capa = virtio_dev_speed_capa_get(hw->speed);
 
 	dev_info->max_rx_queues =
 		RTE_MIN(hw->max_queue_pairs, VIRTIO_MAX_RX_QUEUES);
diff --git a/drivers/net/virtio/virtio_pci.h b/drivers/net/virtio/virtio_pci.h
index 7433d2f08..ed98e11c3 100644
--- a/drivers/net/virtio/virtio_pci.h
+++ b/drivers/net/virtio/virtio_pci.h
@@ -259,6 +259,7 @@ struct virtio_hw {
 	uint16_t    port_id;
 	uint8_t     mac_addr[RTE_ETHER_ADDR_LEN];
 	uint32_t    notify_off_multiplier;
+	uint32_t    speed;  /* link speed in MB */
 	uint8_t     *isr;
 	uint16_t    *notify_base;
 	struct virtio_pci_common_cfg *common_cfg;
-- 
2.17.1


^ permalink raw reply	[flat|nested] 359+ messages in thread

* [dpdk-dev] [PATCH v8 3/5] net/virtio-user: fix devargs parsing
       [not found]       ` <CGME20200330075831eucas1p22cd157c9ba83fa3b6c0fa85ba37f1bb4@eucas1p2.samsung.com>
@ 2020-03-30  7:58         ` Ivan Dyukov
  0 siblings, 0 replies; 359+ messages in thread
From: Ivan Dyukov @ 2020-03-30  7:58 UTC (permalink / raw)
  To: dev, maxime.coquelin, i.dyukov, tiwei.bie, amorenoz,
	zhihong.wang, xiaolong.ye

strtoull returns 0 if it fails to parse input string. It's ignored
in get_integer_arg.

This patch handles error cases for strtoull function.

Signed-off-by: Ivan Dyukov <i.dyukov@samsung.com>
---
 drivers/net/virtio/virtio_user_ethdev.c | 13 +++++++++----
 1 file changed, 9 insertions(+), 4 deletions(-)

diff --git a/drivers/net/virtio/virtio_user_ethdev.c b/drivers/net/virtio/virtio_user_ethdev.c
index e61af4068..a79f68a36 100644
--- a/drivers/net/virtio/virtio_user_ethdev.c
+++ b/drivers/net/virtio/virtio_user_ethdev.c
@@ -477,12 +477,17 @@ static int
 get_integer_arg(const char *key __rte_unused,
 		const char *value, void *extra_args)
 {
+	uint64_t integer = 0;
 	if (!value || !extra_args)
 		return -EINVAL;
-
-	*(uint64_t *)extra_args = strtoull(value, NULL, 0);
-
-	return 0;
+	errno = 0;
+	integer = strtoull(value, NULL, 0);
+	/* extra_args keeps default value, it should be replaced
+	 * only in case of successful parsing of the 'value' arg
+	 */
+	if (errno == 0)
+		*(uint64_t *)extra_args = integer;
+	return -errno;
 }
 
 static struct rte_eth_dev *
-- 
2.17.1


^ permalink raw reply	[flat|nested] 359+ messages in thread

* [dpdk-dev] [PATCH v8 4/5] net/virtio-user: adding link speed devarg
       [not found]       ` <CGME20200330075832eucas1p295cdf00368bb91a1ecec202f1cd3624a@eucas1p2.samsung.com>
@ 2020-03-30  7:58         ` Ivan Dyukov
  0 siblings, 0 replies; 359+ messages in thread
From: Ivan Dyukov @ 2020-03-30  7:58 UTC (permalink / raw)
  To: dev, maxime.coquelin, i.dyukov, tiwei.bie, amorenoz,
	zhihong.wang, xiaolong.ye

virtio driver already parses speed devarg. virtio-user should add
it to list of valid devargs and call eth_virtio_dev_init function
which init speed value.

eth_virtio_dev_init already is called from virtio_user_pmd_probe
function. The only change is required to enable speed devargs:
adding speed to list of valid devargs.

Signed-off-by: Ivan Dyukov <i.dyukov@samsung.com>
---
 doc/guides/nics/virtio.rst              | 8 ++++++++
 drivers/net/virtio/virtio_user_ethdev.c | 5 ++++-
 2 files changed, 12 insertions(+), 1 deletion(-)

diff --git a/doc/guides/nics/virtio.rst b/doc/guides/nics/virtio.rst
index 0341907ef..6286286db 100644
--- a/doc/guides/nics/virtio.rst
+++ b/doc/guides/nics/virtio.rst
@@ -410,6 +410,14 @@ Below devargs are supported by the virtio-user vdev:
     It is used to enable virtio device packed virtqueue feature.
     (Default: 0 (disabled))
 
+#.  ``speed``:
+
+    It is used to specify link speed of virtio device. Link speed is a part of
+    link status structure. It could be requested by application using
+    rte_eth_link_get_nowait function.
+    (Default: 10000 (10G))
+
+
 Virtio paths Selection and Usage
 --------------------------------
 
diff --git a/drivers/net/virtio/virtio_user_ethdev.c b/drivers/net/virtio/virtio_user_ethdev.c
index a79f68a36..5b32d30fa 100644
--- a/drivers/net/virtio/virtio_user_ethdev.c
+++ b/drivers/net/virtio/virtio_user_ethdev.c
@@ -450,6 +450,8 @@ static const char *valid_args[] = {
 	VIRTIO_USER_ARG_IN_ORDER,
 #define VIRTIO_USER_ARG_PACKED_VQ      "packed_vq"
 	VIRTIO_USER_ARG_PACKED_VQ,
+#define VIRTIO_USER_ARG_SPEED          "speed"
+	VIRTIO_USER_ARG_SPEED,
 	NULL
 };
 
@@ -782,4 +784,5 @@ RTE_PMD_REGISTER_PARAM_STRING(net_virtio_user,
 	"server=<0|1> "
 	"mrg_rxbuf=<0|1> "
 	"in_order=<0|1> "
-	"packed_vq=<0|1>");
+	"packed_vq=<0|1> "
+	"speed=<int>");
-- 
2.17.1


^ permalink raw reply	[flat|nested] 359+ messages in thread

* [dpdk-dev] [PATCH v8 5/5] net/virtio: Support of VIRTIO_NET_F_SPEED_DUPLEX
       [not found]       ` <CGME20200330075834eucas1p2892713fbbd1b13d9f65e5efc9d25d9a8@eucas1p2.samsung.com>
@ 2020-03-30  7:58         ` Ivan Dyukov
  0 siblings, 0 replies; 359+ messages in thread
From: Ivan Dyukov @ 2020-03-30  7:58 UTC (permalink / raw)
  To: dev, maxime.coquelin, i.dyukov, tiwei.bie, amorenoz,
	zhihong.wang, xiaolong.ye

This patch adds a support of VIRTIO_NET_F_SPEED_DUPLEX feature
for virtio driver.

There are few ways to specify speed of the link:
   'speed' devarg
   negotiate speed from qemu via VIRTIO_NET_F_SPEED_DUPLEX
The highest priority is devarg. If devarg is not specified,
drivers tries to negotiate it from qemu.

Signed-off-by: Ivan Dyukov <i.dyukov@samsung.com>
---
 drivers/net/virtio/virtio_ethdev.c | 26 +++++++++++++++++++++++---
 drivers/net/virtio/virtio_ethdev.h |  3 ++-
 drivers/net/virtio/virtio_pci.h    | 16 ++++++++++++++++
 3 files changed, 41 insertions(+), 4 deletions(-)

diff --git a/drivers/net/virtio/virtio_ethdev.c b/drivers/net/virtio/virtio_ethdev.c
index fe0e292ef..8a6e1933a 100644
--- a/drivers/net/virtio/virtio_ethdev.c
+++ b/drivers/net/virtio/virtio_ethdev.c
@@ -1662,7 +1662,8 @@ virtio_configure_intr(struct rte_eth_dev *dev)
 
 	return 0;
 }
-
+#define SPEED_UNKNOWN    0xffffffff
+#define DUPLEX_UNKNOWN   0xff
 /* reset device and renegotiate features if needed */
 static int
 virtio_init_device(struct rte_eth_dev *eth_dev, uint64_t req_features)
@@ -1718,6 +1719,25 @@ virtio_init_device(struct rte_eth_dev *eth_dev, uint64_t req_features)
 		     hw->mac_addr[0], hw->mac_addr[1], hw->mac_addr[2],
 		     hw->mac_addr[3], hw->mac_addr[4], hw->mac_addr[5]);
 
+	if (hw->speed == SPEED_UNKNOWN) {
+		if (vtpci_with_feature(hw, VIRTIO_NET_F_SPEED_DUPLEX)) {
+			config = &local_config;
+			vtpci_read_dev_config(hw,
+				offsetof(struct virtio_net_config, speed),
+				&config->speed, sizeof(config->speed));
+			vtpci_read_dev_config(hw,
+				offsetof(struct virtio_net_config, duplex),
+				&config->duplex, sizeof(config->duplex));
+			hw->speed = config->speed;
+			hw->duplex = config->duplex;
+		}
+	}
+	if (hw->speed == SPEED_UNKNOWN)
+		hw->speed = ETH_SPEED_NUM_10G;
+	if (hw->duplex == DUPLEX_UNKNOWN)
+		hw->duplex = ETH_LINK_FULL_DUPLEX;
+	PMD_INIT_LOG(DEBUG, "link speed = %d, duplex = %d",
+		hw->speed, hw->duplex);
 	if (vtpci_with_feature(hw, VIRTIO_NET_F_CTRL_VQ)) {
 		config = &local_config;
 
@@ -1865,7 +1885,7 @@ int
 eth_virtio_dev_init(struct rte_eth_dev *eth_dev)
 {
 	struct virtio_hw *hw = eth_dev->data->dev_private;
-	uint32_t speed = ETH_SPEED_NUM_10G;
+	uint32_t speed = SPEED_UNKNOWN;
 	int ret;
 
 	if (sizeof(struct virtio_net_hdr_mrg_rxbuf) > RTE_PKTMBUF_HEADROOM) {
@@ -2450,7 +2470,7 @@ virtio_dev_link_update(struct rte_eth_dev *dev, __rte_unused int wait_to_complet
 	struct virtio_hw *hw = dev->data->dev_private;
 
 	memset(&link, 0, sizeof(link));
-	link.link_duplex = ETH_LINK_FULL_DUPLEX;
+	link.link_duplex = hw->duplex;
 	link.link_speed  = hw->speed;
 	link.link_autoneg = ETH_LINK_FIXED;
 
diff --git a/drivers/net/virtio/virtio_ethdev.h b/drivers/net/virtio/virtio_ethdev.h
index cd8947656..febaf17a8 100644
--- a/drivers/net/virtio/virtio_ethdev.h
+++ b/drivers/net/virtio/virtio_ethdev.h
@@ -37,7 +37,8 @@
 	 1ULL << VIRTIO_F_RING_PACKED	  |	\
 	 1ULL << VIRTIO_F_IOMMU_PLATFORM  |	\
 	 1ULL << VIRTIO_F_ORDER_PLATFORM  |	\
-	 1ULL << VIRTIO_F_NOTIFICATION_DATA)
+	 1ULL << VIRTIO_F_NOTIFICATION_DATA | \
+	 1ULL << VIRTIO_NET_F_SPEED_DUPLEX)
 
 #define VIRTIO_PMD_SUPPORTED_GUEST_FEATURES	\
 	(VIRTIO_PMD_DEFAULT_GUEST_FEATURES |	\
diff --git a/drivers/net/virtio/virtio_pci.h b/drivers/net/virtio/virtio_pci.h
index ed98e11c3..bd89357e4 100644
--- a/drivers/net/virtio/virtio_pci.h
+++ b/drivers/net/virtio/virtio_pci.h
@@ -141,6 +141,9 @@ struct virtnet_ctl;
  */
 #define VIRTIO_F_NOTIFICATION_DATA 38
 
+/* Device set linkspeed and duplex */
+#define VIRTIO_NET_F_SPEED_DUPLEX 63
+
 /* The Guest publishes the used index for which it expects an interrupt
  * at the end of the avail ring. Host should ignore the avail->flags field. */
 /* The Host publishes the avail index for which it expects a kick
@@ -260,6 +263,7 @@ struct virtio_hw {
 	uint8_t     mac_addr[RTE_ETHER_ADDR_LEN];
 	uint32_t    notify_off_multiplier;
 	uint32_t    speed;  /* link speed in MB */
+	uint8_t     duplex;
 	uint8_t     *isr;
 	uint16_t    *notify_base;
 	struct virtio_pci_common_cfg *common_cfg;
@@ -306,6 +310,18 @@ struct virtio_net_config {
 	uint16_t   status;
 	uint16_t   max_virtqueue_pairs;
 	uint16_t   mtu;
+	/*
+	 * speed, in units of 1Mb. All values 0 to INT_MAX are legal.
+	 * Any other value stands for unknown.
+	 */
+	uint32_t speed;
+	/*
+	 * 0x00 - half duplex
+	 * 0x01 - full duplex
+	 * Any other value stands for unknown.
+	 */
+	uint8_t duplex;
+
 } __attribute__((packed));
 
 /*
-- 
2.17.1


^ permalink raw reply	[flat|nested] 359+ messages in thread

* Re: [dpdk-dev] [PATCH v8 2/5] net/virtio: add link speed devarg
  2020-03-30  7:57         ` [dpdk-dev] [PATCH v8 2/5] net/virtio: add link speed devarg Ivan Dyukov
@ 2020-04-01 10:57           ` Thomas Monjalon
  2020-04-02  9:18             ` Ivan Dyukov
  0 siblings, 1 reply; 359+ messages in thread
From: Thomas Monjalon @ 2020-04-01 10:57 UTC (permalink / raw)
  To: Ivan Dyukov
  Cc: dev, maxime.coquelin, i.dyukov, tiwei.bie, amorenoz,
	zhihong.wang, xiaolong.ye, Morten Brørup

30/03/2020 09:57, Ivan Dyukov:
> Some applications like pktgen use link speed to calculate
> transmission rate. It limits outcome traffic to hardcoded 10G.
> 
> This patch adds speed devarg which allows to configure
> link speed of virtio device.

Is it really a good idea to fake such information?
Shouldn't it be managed differently in the application instead?



^ permalink raw reply	[flat|nested] 359+ messages in thread

* Re: [dpdk-dev] [PATCH v8 2/5] net/virtio: add link speed devarg
  2020-04-01 10:57           ` Thomas Monjalon
@ 2020-04-02  9:18             ` Ivan Dyukov
  2020-04-02 17:33               ` Thomas Monjalon
  0 siblings, 1 reply; 359+ messages in thread
From: Ivan Dyukov @ 2020-04-02  9:18 UTC (permalink / raw)
  To: Thomas Monjalon
  Cc: dev, maxime.coquelin, tiwei.bie, amorenoz, zhihong.wang,
	xiaolong.ye, Morten Brørup

Hello Thomas,

01.04.2020 13:57, Thomas Monjalon пишет:
> 30/03/2020 09:57, Ivan Dyukov:
>> Some applications like pktgen use link speed to calculate
>> transmission rate. It limits outcome traffic to hardcoded 10G.
>>
>> This patch adds speed devarg which allows to configure
>> link speed of virtio device.
> Is it really a good idea to fake such information?
> Shouldn't it be managed differently in the application instead?
>
>
>
This is main stream of net devices. Device provides speed to 
application. Application calculates the packet rate. In case of virtio, 
speed is not limited by device. It could be specified by user. This 
patch just gives this posibility to user.


Best regards,

Ivan.



^ permalink raw reply	[flat|nested] 359+ messages in thread

* Re: [dpdk-dev] [PATCH v8 2/5] net/virtio: add link speed devarg
  2020-04-02  9:18             ` Ivan Dyukov
@ 2020-04-02 17:33               ` Thomas Monjalon
  2020-04-02 20:29                 ` Ivan Dyukov
  0 siblings, 1 reply; 359+ messages in thread
From: Thomas Monjalon @ 2020-04-02 17:33 UTC (permalink / raw)
  To: Ivan Dyukov
  Cc: dev, maxime.coquelin, tiwei.bie, amorenoz, zhihong.wang,
	xiaolong.ye, Morten Brørup, ferruh.yigit, arybchenko

02/04/2020 11:18, Ivan Dyukov:
> Hello Thomas,
> 
> 01.04.2020 13:57, Thomas Monjalon пишет:
> > 30/03/2020 09:57, Ivan Dyukov:
> >> Some applications like pktgen use link speed to calculate
> >> transmission rate. It limits outcome traffic to hardcoded 10G.
> >>
> >> This patch adds speed devarg which allows to configure
> >> link speed of virtio device.
> > Is it really a good idea to fake such information?
> > Shouldn't it be managed differently in the application instead?
> >
> >
> >
> This is main stream of net devices. Device provides speed to 
> application. Application calculates the packet rate. In case of virtio, 
> speed is not limited by device. It could be specified by user. This 
> patch just gives this posibility to user.

The other possibility is to return 0 meaning unknown speed.
I don't see why this information should be saved in the driver space.
The user can give this information to the application,
it would look more correct to me.
Note: the application is controlling the devargs passed to the driver,
so it can intercept such information.

I understand it is easier to have the speed info at the same place
in all cases. But it avoids differentiating what is a reliable info,
and what is user-provided info.



^ permalink raw reply	[flat|nested] 359+ messages in thread

* Re: [dpdk-dev] [PATCH v8 2/5] net/virtio: add link speed devarg
  2020-04-02 17:33               ` Thomas Monjalon
@ 2020-04-02 20:29                 ` Ivan Dyukov
  0 siblings, 0 replies; 359+ messages in thread
From: Ivan Dyukov @ 2020-04-02 20:29 UTC (permalink / raw)
  To: Thomas Monjalon
  Cc: dev, maxime.coquelin, Vladimir Kuramshin, amorenoz, zhihong.wang,
	xiaolong.ye, Morten Brørup, ferruh.yigit, arybchenko

02.04.2020 20:33, Thomas Monjalon пишет:
> 02/04/2020 11:18, Ivan Dyukov:
>> Hello Thomas,
>>
>> 01.04.2020 13:57, Thomas Monjalon пишет:
>>> 30/03/2020 09:57, Ivan Dyukov:
>>>> Some applications like pktgen use link speed to calculate
>>>> transmission rate. It limits outcome traffic to hardcoded 10G.
>>>>
>>>> This patch adds speed devarg which allows to configure
>>>> link speed of virtio device.
>>> Is it really a good idea to fake such information?
>>> Shouldn't it be managed differently in the application instead?
>>>
>>>
>>>
>> This is main stream of net devices. Device provides speed to
>> application. Application calculates the packet rate. In case of virtio,
>> speed is not limited by device. It could be specified by user. This
>> patch just gives this posibility to user.
> The other possibility is to return 0 meaning unknown speed.
Yep. Right. Linux kernel virtio is implemented same way. They return -1, 
if user haven't specified other.

Legacy dpdk virtio code was always returned 10G speed before my patchset 
and I just keep this value to

prevent breakages in applications like pktgen.

> I don't see why this information should be saved in the driver space.

The speed could be provided by qemu. Please see 5th patch in my 
patchset. It's not good idea to smash

this code accross application and driver side.

> The user can give this information to the application,
> it would look more correct to me.
> Note: the application is controlling the devargs passed to the driver,
> so it can intercept such information.

These changes are specific only for virtio driver. If application will 
treat speed argument, then

it also should check that current driver is virtio and same code will be 
duplicated in every application.


>
> I understand it is easier to have the speed info at the same place
> in all cases. But it avoids differentiating what is a reliable info,
> and what is user-provided info.
>
>
>


^ permalink raw reply	[flat|nested] 359+ messages in thread

* [dpdk-dev] [PATCH v9 0/5] net/virtio: add link speed devarg
       [not found]   ` <CGME20200406085911eucas1p21c560c2b5908872e457e5f83ea9824fd@eucas1p2.samsung.com>
@ 2020-04-06  8:57     ` " Ivan Dyukov
       [not found]       ` <CGME20200406085914eucas1p2e20a40d2cf7a3536fff12f44a75164bb@eucas1p2.samsung.com>
                         ` (4 more replies)
  0 siblings, 5 replies; 359+ messages in thread
From: Ivan Dyukov @ 2020-04-06  8:57 UTC (permalink / raw)
  To: dev, maxime.coquelin, i.dyukov, v.kuramshin, amorenoz,
	zhihong.wang, xiaolong.ye, mb

doc/guides/nics/virtio.rst              |  15 +++++++++++++++
drivers/net/virtio/virtio_ethdev.c      | 144 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++--------------------
drivers/net/virtio/virtio_ethdev.h      |   3 ++-
drivers/net/virtio/virtio_pci.h         |  16 ++++++++++++++++
drivers/net/virtio/virtio_user_ethdev.c |  18 +++++++++++++-----
lib/librte_ethdev/rte_ethdev.h          |  27 ++++++++++++++-------------
6 files changed, 184 insertions(+), 39 deletions(-)

v9 chagnes:
* [PATCH 2/5] remove limited set of acceptable speeds [10G, 20G, 40G, 56G, 100G], now all natural numbers are acceptable
* [PATCH 2/5] returns speed_capa as maximum available capability for specified speed
* [PATCH 5/5] remove duplex negotiation
* [PATCH 5/5] set default speed to 0xffffffff

v8 changes:
* fix code style

v7 chagnes:
* rebased to latest master
* added support of VIRTIO_NET_F_SPEED_DUPLEX

v6 changes:
* fix code style

v5 changes:
* fixed code style
* fixed commit message and logging text

v4 changes:
* link_speed renamed to speed devarg
* speed devarg is added to virtio-user driver

v3 changes:
* link_speed devarg is added to virtio documentation



^ permalink raw reply	[flat|nested] 359+ messages in thread

* [dpdk-dev] [PATCH v9 1/5] net/virtio: refactor devargs parsing
       [not found]       ` <CGME20200406085914eucas1p2e20a40d2cf7a3536fff12f44a75164bb@eucas1p2.samsung.com>
@ 2020-04-06  8:57         ` Ivan Dyukov
  2020-04-15 14:53           ` Maxime Coquelin
  0 siblings, 1 reply; 359+ messages in thread
From: Ivan Dyukov @ 2020-04-06  8:57 UTC (permalink / raw)
  To: dev, maxime.coquelin, i.dyukov, v.kuramshin, amorenoz,
	zhihong.wang, xiaolong.ye, mb

refactor vdpa specific devargs parsing to more generic way

Signed-off-by: Ivan Dyukov <i.dyukov@samsung.com>
---
 drivers/net/virtio/virtio_ethdev.c | 34 +++++++++++++++++++++---------
 1 file changed, 24 insertions(+), 10 deletions(-)

diff --git a/drivers/net/virtio/virtio_ethdev.c b/drivers/net/virtio/virtio_ethdev.c
index f9d0ea70d..870ff7801 100644
--- a/drivers/net/virtio/virtio_ethdev.c
+++ b/drivers/net/virtio/virtio_ethdev.c
@@ -1957,16 +1957,18 @@ eth_virtio_dev_uninit(struct rte_eth_dev *eth_dev)
 }
 
 static int vdpa_check_handler(__rte_unused const char *key,
-		const char *value, __rte_unused void *opaque)
+		const char *value, void *ret_val)
 {
-	if (strcmp(value, "1"))
-		return -1;
+	if (strcmp(value, "1") == 0)
+		*(int *)ret_val = 1;
+	else
+		*(int *)ret_val = 0;
 
 	return 0;
 }
 
 static int
-vdpa_mode_selected(struct rte_devargs *devargs)
+virtio_dev_devargs_parse(struct rte_devargs *devargs, int *vdpa)
 {
 	struct rte_kvargs *kvlist;
 	const char *key = "vdpa";
@@ -1982,12 +1984,16 @@ vdpa_mode_selected(struct rte_devargs *devargs)
 	if (!rte_kvargs_count(kvlist, key))
 		goto exit;
 
-	/* vdpa mode selected when there's a key-value pair: vdpa=1 */
-	if (rte_kvargs_process(kvlist, key,
-				vdpa_check_handler, NULL) < 0) {
-		goto exit;
+	if (vdpa) {
+		/* vdpa mode selected when there's a key-value pair:
+		 * vdpa=1
+		 */
+		ret = rte_kvargs_process(kvlist, key,
+				vdpa_check_handler, vdpa);
+		if (ret < 0)
+			goto exit;
 	}
-	ret = 1;
+
 
 exit:
 	rte_kvargs_free(kvlist);
@@ -1997,8 +2003,16 @@ vdpa_mode_selected(struct rte_devargs *devargs)
 static int eth_virtio_pci_probe(struct rte_pci_driver *pci_drv __rte_unused,
 	struct rte_pci_device *pci_dev)
 {
+	int vdpa = 0;
+	int ret = 0;
+
+	ret = virtio_dev_devargs_parse(pci_dev->device.devargs, &vdpa);
+	if (ret < 0) {
+		PMD_INIT_LOG(ERR, "devargs parsing is failed");
+		return ret;
+	}
 	/* virtio pmd skips probe if device needs to work in vdpa mode */
-	if (vdpa_mode_selected(pci_dev->device.devargs))
+	if (vdpa == 1)
 		return 1;
 
 	return rte_eth_dev_pci_generic_probe(pci_dev, sizeof(struct virtio_hw),
-- 
2.17.1


^ permalink raw reply	[flat|nested] 359+ messages in thread

* [dpdk-dev] [PATCH v9 2/5] net/virtio: add link speed devarg
       [not found]       ` <CGME20200406085916eucas1p1e4b9a43f89e63e71aa877adca6046dc4@eucas1p1.samsung.com>
@ 2020-04-06  8:58         ` Ivan Dyukov
  2020-04-15 15:06           ` Maxime Coquelin
  0 siblings, 1 reply; 359+ messages in thread
From: Ivan Dyukov @ 2020-04-06  8:58 UTC (permalink / raw)
  To: dev, maxime.coquelin, i.dyukov, v.kuramshin, amorenoz,
	zhihong.wang, xiaolong.ye, mb

Some applications like pktgen use link speed to calculate
transmission rate. It limits outcome traffic to hardcoded 10G.

This patch adds speed devarg which allows to configure
link speed of virtio device.

Signed-off-by: Ivan Dyukov <i.dyukov@samsung.com>
---
 doc/guides/nics/virtio.rst         |   7 ++
 drivers/net/virtio/virtio_ethdev.c | 108 ++++++++++++++++++++++++-----
 drivers/net/virtio/virtio_pci.h    |   1 +
 3 files changed, 100 insertions(+), 16 deletions(-)

diff --git a/doc/guides/nics/virtio.rst b/doc/guides/nics/virtio.rst
index d1f5fb898..e579c6aa9 100644
--- a/doc/guides/nics/virtio.rst
+++ b/doc/guides/nics/virtio.rst
@@ -356,6 +356,13 @@ Below devargs are supported by the PCI virtio driver:
     a virtio device needs to work in vDPA mode.
     (Default: 0 (disabled))
 
+#.  ``speed``:
+
+    It is used to specify link speed of virtio device, in units of 1Mb.
+    Link speed is a part of link status structure. It could be requested
+    by application using rte_eth_link_get_nowait function.
+    (Default: 10000 (10G))
+
 Below devargs are supported by the virtio-user vdev:
 
 #.  ``path``:
diff --git a/drivers/net/virtio/virtio_ethdev.c b/drivers/net/virtio/virtio_ethdev.c
index 870ff7801..eb46a5a11 100644
--- a/drivers/net/virtio/virtio_ethdev.c
+++ b/drivers/net/virtio/virtio_ethdev.c
@@ -45,6 +45,10 @@ static int virtio_dev_promiscuous_enable(struct rte_eth_dev *dev);
 static int virtio_dev_promiscuous_disable(struct rte_eth_dev *dev);
 static int virtio_dev_allmulticast_enable(struct rte_eth_dev *dev);
 static int virtio_dev_allmulticast_disable(struct rte_eth_dev *dev);
+static uint32_t virtio_dev_speed_capa_get(uint32_t speed);
+static int virtio_dev_devargs_parse(struct rte_devargs *devargs,
+	int *vdpa,
+	uint32_t *speed);
 static int virtio_dev_info_get(struct rte_eth_dev *dev,
 				struct rte_eth_dev_info *dev_info);
 static int virtio_dev_link_update(struct rte_eth_dev *dev,
@@ -1861,6 +1865,7 @@ int
 eth_virtio_dev_init(struct rte_eth_dev *eth_dev)
 {
 	struct virtio_hw *hw = eth_dev->data->dev_private;
+	uint32_t speed = ETH_SPEED_NUM_10G;
 	int ret;
 
 	if (sizeof(struct virtio_net_hdr_mrg_rxbuf) > RTE_PKTMBUF_HEADROOM) {
@@ -1886,7 +1891,11 @@ eth_virtio_dev_init(struct rte_eth_dev *eth_dev)
 
 		return 0;
 	}
-
+	ret = virtio_dev_devargs_parse(eth_dev->device->devargs,
+		 NULL, &speed);
+	if (ret < 0)
+		return ret;
+	hw->speed = speed;
 	/*
 	 * Pass the information to the rte_eth_dev_close() that it should also
 	 * release the private port resources.
@@ -1956,6 +1965,7 @@ eth_virtio_dev_uninit(struct rte_eth_dev *eth_dev)
 	return 0;
 }
 
+
 static int vdpa_check_handler(__rte_unused const char *key,
 		const char *value, void *ret_val)
 {
@@ -1967,33 +1977,100 @@ static int vdpa_check_handler(__rte_unused const char *key,
 	return 0;
 }
 
+
+static uint32_t
+virtio_dev_speed_capa_get(uint32_t speed)
+{
+	struct speed_caps {
+		uint32_t min_speed;
+		uint32_t speed_capa;
+	};
+	struct speed_caps caps[] = {
+		{ETH_SPEED_NUM_10M,    ETH_LINK_SPEED_10M},
+		{ETH_SPEED_NUM_100M,   ETH_LINK_SPEED_100M},
+		{ETH_SPEED_NUM_1G,     ETH_LINK_SPEED_1G},
+		{ETH_SPEED_NUM_2_5G,   ETH_LINK_SPEED_2_5G},
+		{ETH_SPEED_NUM_5G,     ETH_LINK_SPEED_5G},
+		{ETH_SPEED_NUM_10G,    ETH_LINK_SPEED_10G},
+		{ETH_SPEED_NUM_20G,    ETH_LINK_SPEED_20G},
+		{ETH_SPEED_NUM_25G,    ETH_LINK_SPEED_25G},
+		{ETH_SPEED_NUM_40G,    ETH_LINK_SPEED_40G},
+		{ETH_SPEED_NUM_50G,    ETH_LINK_SPEED_50G},
+		{ETH_SPEED_NUM_56G,    ETH_LINK_SPEED_56G},
+		{ETH_SPEED_NUM_100G,   ETH_LINK_SPEED_100G}
+	};
+	const uint32_t caps_size = sizeof(caps) / sizeof(struct speed_caps);
+	uint32_t speed_capa = ETH_LINK_SPEED_AUTONEG;
+	if (speed != ETH_SPEED_NUM_UNKNOWN) {
+		/* find maximum suitable speed capability */
+		for (uint32_t i = 0; i < caps_size; i++) {
+			if (speed >= caps[i].min_speed)
+				speed_capa = caps[i].speed_capa;
+		}
+	}
+	return speed_capa;
+}
+
+
+#define VIRTIO_ARG_SPEED      "speed"
+#define VIRTIO_ARG_VDPA       "vdpa"
+
+
+static int
+link_speed_handler(const char *key __rte_unused,
+		const char *value, void *ret_val)
+{
+	uint32_t val;
+	if (!value || !ret_val)
+		return -EINVAL;
+	errno = 0;
+	val = strtoul(value, NULL, 0);
+	/* validate input */
+	if (errno != 0)
+		return -EINVAL;
+	*(uint32_t *)ret_val = val;
+
+	return 0;
+}
+
+
 static int
-virtio_dev_devargs_parse(struct rte_devargs *devargs, int *vdpa)
+virtio_dev_devargs_parse(struct rte_devargs *devargs, int *vdpa,
+	uint32_t *speed)
 {
 	struct rte_kvargs *kvlist;
-	const char *key = "vdpa";
 	int ret = 0;
 
 	if (devargs == NULL)
 		return 0;
 
 	kvlist = rte_kvargs_parse(devargs->args, NULL);
-	if (kvlist == NULL)
+	if (kvlist == NULL) {
+		PMD_INIT_LOG(ERR, "error when parsing param");
 		return 0;
-
-	if (!rte_kvargs_count(kvlist, key))
-		goto exit;
-
-	if (vdpa) {
+	}
+	if (vdpa && rte_kvargs_count(kvlist, VIRTIO_ARG_VDPA) == 1) {
 		/* vdpa mode selected when there's a key-value pair:
 		 * vdpa=1
 		 */
-		ret = rte_kvargs_process(kvlist, key,
+		ret = rte_kvargs_process(kvlist, VIRTIO_ARG_VDPA,
 				vdpa_check_handler, vdpa);
-		if (ret < 0)
+		if (ret < 0) {
+			PMD_INIT_LOG(ERR, "Failed to parse %s",
+				VIRTIO_ARG_VDPA);
 			goto exit;
+		}
+	}
+	if (speed && rte_kvargs_count(kvlist, VIRTIO_ARG_SPEED) == 1) {
+		ret = rte_kvargs_process(kvlist,
+					VIRTIO_ARG_SPEED,
+					link_speed_handler, speed);
+		if (ret < 0) {
+			PMD_INIT_LOG(ERR, "Failed to parse %s",
+					VIRTIO_ARG_SPEED);
+			goto exit;
+		}
 	}
-
 
 exit:
 	rte_kvargs_free(kvlist);
@@ -2006,7 +2083,7 @@ static int eth_virtio_pci_probe(struct rte_pci_driver *pci_drv __rte_unused,
 	int vdpa = 0;
 	int ret = 0;
 
-	ret = virtio_dev_devargs_parse(pci_dev->device.devargs, &vdpa);
+	ret = virtio_dev_devargs_parse(pci_dev->device.devargs, &vdpa, NULL);
 	if (ret < 0) {
 		PMD_INIT_LOG(ERR, "devargs parsing is failed");
 		return ret;
@@ -2385,7 +2462,7 @@ virtio_dev_link_update(struct rte_eth_dev *dev, __rte_unused int wait_to_complet
 
 	memset(&link, 0, sizeof(link));
 	link.link_duplex = ETH_LINK_FULL_DUPLEX;
-	link.link_speed  = ETH_SPEED_NUM_10G;
+	link.link_speed  = hw->speed;
 	link.link_autoneg = ETH_LINK_FIXED;
 
 	if (!hw->started) {
@@ -2440,8 +2517,7 @@ virtio_dev_info_get(struct rte_eth_dev *dev, struct rte_eth_dev_info *dev_info)
 {
 	uint64_t tso_mask, host_features;
 	struct virtio_hw *hw = dev->data->dev_private;
-
-	dev_info->speed_capa = ETH_LINK_SPEED_10G; /* fake value */
+	dev_info->speed_capa = virtio_dev_speed_capa_get(hw->speed);
 
 	dev_info->max_rx_queues =
 		RTE_MIN(hw->max_queue_pairs, VIRTIO_MAX_RX_QUEUES);
diff --git a/drivers/net/virtio/virtio_pci.h b/drivers/net/virtio/virtio_pci.h
index 7433d2f08..ed98e11c3 100644
--- a/drivers/net/virtio/virtio_pci.h
+++ b/drivers/net/virtio/virtio_pci.h
@@ -259,6 +259,7 @@ struct virtio_hw {
 	uint16_t    port_id;
 	uint8_t     mac_addr[RTE_ETHER_ADDR_LEN];
 	uint32_t    notify_off_multiplier;
+	uint32_t    speed;  /* link speed in MB */
 	uint8_t     *isr;
 	uint16_t    *notify_base;
 	struct virtio_pci_common_cfg *common_cfg;
-- 
2.17.1


^ permalink raw reply	[flat|nested] 359+ messages in thread

* [dpdk-dev] [PATCH v9 3/5] net/virtio-user: fix devargs parsing
       [not found]       ` <CGME20200406085918eucas1p200d058b72ac3e35b61dd1a119b9fcb55@eucas1p2.samsung.com>
@ 2020-04-06  8:58         ` Ivan Dyukov
  2020-04-15 15:09           ` Maxime Coquelin
  0 siblings, 1 reply; 359+ messages in thread
From: Ivan Dyukov @ 2020-04-06  8:58 UTC (permalink / raw)
  To: dev, maxime.coquelin, i.dyukov, v.kuramshin, amorenoz,
	zhihong.wang, xiaolong.ye, mb

strtoull returns 0 if it fails to parse input string. It's ignored
in get_integer_arg.

This patch handles error cases for strtoull function.

Signed-off-by: Ivan Dyukov <i.dyukov@samsung.com>
---
 drivers/net/virtio/virtio_user_ethdev.c | 13 +++++++++----
 1 file changed, 9 insertions(+), 4 deletions(-)

diff --git a/drivers/net/virtio/virtio_user_ethdev.c b/drivers/net/virtio/virtio_user_ethdev.c
index e61af4068..a79f68a36 100644
--- a/drivers/net/virtio/virtio_user_ethdev.c
+++ b/drivers/net/virtio/virtio_user_ethdev.c
@@ -477,12 +477,17 @@ static int
 get_integer_arg(const char *key __rte_unused,
 		const char *value, void *extra_args)
 {
+	uint64_t integer = 0;
 	if (!value || !extra_args)
 		return -EINVAL;
-
-	*(uint64_t *)extra_args = strtoull(value, NULL, 0);
-
-	return 0;
+	errno = 0;
+	integer = strtoull(value, NULL, 0);
+	/* extra_args keeps default value, it should be replaced
+	 * only in case of successful parsing of the 'value' arg
+	 */
+	if (errno == 0)
+		*(uint64_t *)extra_args = integer;
+	return -errno;
 }
 
 static struct rte_eth_dev *
-- 
2.17.1


^ permalink raw reply	[flat|nested] 359+ messages in thread

* [dpdk-dev] [PATCH v9 4/5] net/virtio-user: adding link speed devarg
       [not found]       ` <CGME20200406085920eucas1p12f4a35578c4c741ee3d933120d25348e@eucas1p1.samsung.com>
@ 2020-04-06  8:58         ` Ivan Dyukov
  2020-04-15 15:10           ` Maxime Coquelin
  0 siblings, 1 reply; 359+ messages in thread
From: Ivan Dyukov @ 2020-04-06  8:58 UTC (permalink / raw)
  To: dev, maxime.coquelin, i.dyukov, v.kuramshin, amorenoz,
	zhihong.wang, xiaolong.ye, mb

virtio driver already parses speed devarg. virtio-user should add
it to list of valid devargs and call eth_virtio_dev_init function
which init speed value.

eth_virtio_dev_init already is called from virtio_user_pmd_probe
function. The only change is required to enable speed devargs:
adding speed to list of valid devargs.

Signed-off-by: Ivan Dyukov <i.dyukov@samsung.com>
---
 doc/guides/nics/virtio.rst              | 8 ++++++++
 drivers/net/virtio/virtio_user_ethdev.c | 5 ++++-
 2 files changed, 12 insertions(+), 1 deletion(-)

diff --git a/doc/guides/nics/virtio.rst b/doc/guides/nics/virtio.rst
index e579c6aa9..e70b6653b 100644
--- a/doc/guides/nics/virtio.rst
+++ b/doc/guides/nics/virtio.rst
@@ -410,6 +410,14 @@ Below devargs are supported by the virtio-user vdev:
     It is used to enable virtio device packed virtqueue feature.
     (Default: 0 (disabled))
 
+#.  ``speed``:
+
+    It is used to specify link speed of virtio device, in units of 1Mb.
+    Link speed is a part of link status structure. It could be requested
+    by application using rte_eth_link_get_nowait function.
+    (Default: 10000 (10G))
+
+
 Virtio paths Selection and Usage
 --------------------------------
 
diff --git a/drivers/net/virtio/virtio_user_ethdev.c b/drivers/net/virtio/virtio_user_ethdev.c
index a79f68a36..5b32d30fa 100644
--- a/drivers/net/virtio/virtio_user_ethdev.c
+++ b/drivers/net/virtio/virtio_user_ethdev.c
@@ -450,6 +450,8 @@ static const char *valid_args[] = {
 	VIRTIO_USER_ARG_IN_ORDER,
 #define VIRTIO_USER_ARG_PACKED_VQ      "packed_vq"
 	VIRTIO_USER_ARG_PACKED_VQ,
+#define VIRTIO_USER_ARG_SPEED          "speed"
+	VIRTIO_USER_ARG_SPEED,
 	NULL
 };
 
@@ -782,4 +784,5 @@ RTE_PMD_REGISTER_PARAM_STRING(net_virtio_user,
 	"server=<0|1> "
 	"mrg_rxbuf=<0|1> "
 	"in_order=<0|1> "
-	"packed_vq=<0|1>");
+	"packed_vq=<0|1> "
+	"speed=<int>");
-- 
2.17.1


^ permalink raw reply	[flat|nested] 359+ messages in thread

* [dpdk-dev] [PATCH v9 5/5] net/virtio: Support of VIRTIO_NET_F_SPEED_DUPLEX
       [not found]       ` <CGME20200406085922eucas1p2e1d78ccf211ba26ced03d466970b9b70@eucas1p2.samsung.com>
@ 2020-04-06  8:58         ` Ivan Dyukov
  2020-04-15 15:17           ` Maxime Coquelin
  0 siblings, 1 reply; 359+ messages in thread
From: Ivan Dyukov @ 2020-04-06  8:58 UTC (permalink / raw)
  To: dev, maxime.coquelin, i.dyukov, v.kuramshin, amorenoz,
	zhihong.wang, xiaolong.ye, mb

This patch adds a support of VIRTIO_NET_F_SPEED_DUPLEX feature
for virtio driver. Set default speed to 0xffffffff and default
duplex to 0xff

There are few ways to specify speed of the link:
   'speed' devarg
   negotiate speed from qemu via VIRTIO_NET_F_SPEED_DUPLEX
The highest priority is devarg. If devarg is not specified,
drivers tries to negotiate it from qemu.

Signed-off-by: Ivan Dyukov <i.dyukov@samsung.com>
---
 doc/guides/nics/virtio.rst         |  4 ++--
 drivers/net/virtio/virtio_ethdev.c | 16 +++++++++++++++-
 drivers/net/virtio/virtio_ethdev.h |  3 ++-
 drivers/net/virtio/virtio_pci.h    | 15 +++++++++++++++
 lib/librte_ethdev/rte_ethdev.h     | 27 ++++++++++++++-------------
 5 files changed, 48 insertions(+), 17 deletions(-)

diff --git a/doc/guides/nics/virtio.rst b/doc/guides/nics/virtio.rst
index e70b6653b..06c7a19aa 100644
--- a/doc/guides/nics/virtio.rst
+++ b/doc/guides/nics/virtio.rst
@@ -361,7 +361,7 @@ Below devargs are supported by the PCI virtio driver:
     It is used to specify link speed of virtio device, in units of 1Mb.
     Link speed is a part of link status structure. It could be requested
     by application using rte_eth_link_get_nowait function.
-    (Default: 10000 (10G))
+    (Default: 0xffffffff (unknown))
 
 Below devargs are supported by the virtio-user vdev:
 
@@ -415,7 +415,7 @@ Below devargs are supported by the virtio-user vdev:
     It is used to specify link speed of virtio device, in units of 1Mb.
     Link speed is a part of link status structure. It could be requested
     by application using rte_eth_link_get_nowait function.
-    (Default: 10000 (10G))
+    (Default: 0xffffffff (unknown))
 
 
 Virtio paths Selection and Usage
diff --git a/drivers/net/virtio/virtio_ethdev.c b/drivers/net/virtio/virtio_ethdev.c
index eb46a5a11..0137efcc5 100644
--- a/drivers/net/virtio/virtio_ethdev.c
+++ b/drivers/net/virtio/virtio_ethdev.c
@@ -1718,6 +1718,20 @@ virtio_init_device(struct rte_eth_dev *eth_dev, uint64_t req_features)
 		     hw->mac_addr[0], hw->mac_addr[1], hw->mac_addr[2],
 		     hw->mac_addr[3], hw->mac_addr[4], hw->mac_addr[5]);
 
+	if (vtpci_with_feature(hw, VIRTIO_NET_F_SPEED_DUPLEX)) {
+		config = &local_config;
+		/* if speed is not specified in devargs */
+		if (hw->speed == ETH_SPEED_NUM_UNKNOWN) {
+			vtpci_read_dev_config(hw,
+				offsetof(struct virtio_net_config, speed),
+				&config->speed, sizeof(config->speed));
+			hw->speed = config->speed;
+		}
+	}
+
+	PMD_INIT_LOG(DEBUG, "link speed = %u%s",
+		hw->speed, hw->speed == ETH_SPEED_NUM_UNKNOWN ?
+		"(UNKNOWN)" : "");
 	if (vtpci_with_feature(hw, VIRTIO_NET_F_CTRL_VQ)) {
 		config = &local_config;
 
@@ -1865,7 +1879,7 @@ int
 eth_virtio_dev_init(struct rte_eth_dev *eth_dev)
 {
 	struct virtio_hw *hw = eth_dev->data->dev_private;
-	uint32_t speed = ETH_SPEED_NUM_10G;
+	uint32_t speed = ETH_SPEED_NUM_UNKNOWN;
 	int ret;
 
 	if (sizeof(struct virtio_net_hdr_mrg_rxbuf) > RTE_PKTMBUF_HEADROOM) {
diff --git a/drivers/net/virtio/virtio_ethdev.h b/drivers/net/virtio/virtio_ethdev.h
index cd8947656..febaf17a8 100644
--- a/drivers/net/virtio/virtio_ethdev.h
+++ b/drivers/net/virtio/virtio_ethdev.h
@@ -37,7 +37,8 @@
 	 1ULL << VIRTIO_F_RING_PACKED	  |	\
 	 1ULL << VIRTIO_F_IOMMU_PLATFORM  |	\
 	 1ULL << VIRTIO_F_ORDER_PLATFORM  |	\
-	 1ULL << VIRTIO_F_NOTIFICATION_DATA)
+	 1ULL << VIRTIO_F_NOTIFICATION_DATA | \
+	 1ULL << VIRTIO_NET_F_SPEED_DUPLEX)
 
 #define VIRTIO_PMD_SUPPORTED_GUEST_FEATURES	\
 	(VIRTIO_PMD_DEFAULT_GUEST_FEATURES |	\
diff --git a/drivers/net/virtio/virtio_pci.h b/drivers/net/virtio/virtio_pci.h
index ed98e11c3..2948760ab 100644
--- a/drivers/net/virtio/virtio_pci.h
+++ b/drivers/net/virtio/virtio_pci.h
@@ -141,6 +141,9 @@ struct virtnet_ctl;
  */
 #define VIRTIO_F_NOTIFICATION_DATA 38
 
+/* Device set linkspeed and duplex */
+#define VIRTIO_NET_F_SPEED_DUPLEX 63
+
 /* The Guest publishes the used index for which it expects an interrupt
  * at the end of the avail ring. Host should ignore the avail->flags field. */
 /* The Host publishes the avail index for which it expects a kick
@@ -306,6 +309,18 @@ struct virtio_net_config {
 	uint16_t   status;
 	uint16_t   max_virtqueue_pairs;
 	uint16_t   mtu;
+	/*
+	 * speed, in units of 1Mb. All values 0 to INT_MAX are legal.
+	 * Any other value stands for unknown.
+	 */
+	uint32_t speed;
+	/*
+	 * 0x00 - half duplex
+	 * 0x01 - full duplex
+	 * Any other value stands for unknown.
+	 */
+	uint8_t duplex;
+
 } __attribute__((packed));
 
 /*
diff --git a/lib/librte_ethdev/rte_ethdev.h b/lib/librte_ethdev/rte_ethdev.h
index d1a593ad1..a15ea572e 100644
--- a/lib/librte_ethdev/rte_ethdev.h
+++ b/lib/librte_ethdev/rte_ethdev.h
@@ -287,19 +287,20 @@ struct rte_eth_stats {
 /**
  * Ethernet numeric link speeds in Mbps
  */
-#define ETH_SPEED_NUM_NONE         0 /**< Not defined */
-#define ETH_SPEED_NUM_10M         10 /**<  10 Mbps */
-#define ETH_SPEED_NUM_100M       100 /**< 100 Mbps */
-#define ETH_SPEED_NUM_1G        1000 /**<   1 Gbps */
-#define ETH_SPEED_NUM_2_5G      2500 /**< 2.5 Gbps */
-#define ETH_SPEED_NUM_5G        5000 /**<   5 Gbps */
-#define ETH_SPEED_NUM_10G      10000 /**<  10 Gbps */
-#define ETH_SPEED_NUM_20G      20000 /**<  20 Gbps */
-#define ETH_SPEED_NUM_25G      25000 /**<  25 Gbps */
-#define ETH_SPEED_NUM_40G      40000 /**<  40 Gbps */
-#define ETH_SPEED_NUM_50G      50000 /**<  50 Gbps */
-#define ETH_SPEED_NUM_56G      56000 /**<  56 Gbps */
-#define ETH_SPEED_NUM_100G    100000 /**< 100 Gbps */
+#define ETH_SPEED_NUM_NONE             0 /**< Not defined */
+#define ETH_SPEED_NUM_10M             10 /**<  10 Mbps */
+#define ETH_SPEED_NUM_100M           100 /**< 100 Mbps */
+#define ETH_SPEED_NUM_1G            1000 /**<   1 Gbps */
+#define ETH_SPEED_NUM_2_5G          2500 /**< 2.5 Gbps */
+#define ETH_SPEED_NUM_5G            5000 /**<   5 Gbps */
+#define ETH_SPEED_NUM_10G          10000 /**<  10 Gbps */
+#define ETH_SPEED_NUM_20G          20000 /**<  20 Gbps */
+#define ETH_SPEED_NUM_25G          25000 /**<  25 Gbps */
+#define ETH_SPEED_NUM_40G          40000 /**<  40 Gbps */
+#define ETH_SPEED_NUM_50G          50000 /**<  50 Gbps */
+#define ETH_SPEED_NUM_56G          56000 /**<  56 Gbps */
+#define ETH_SPEED_NUM_100G        100000 /**< 100 Gbps */
+#define ETH_SPEED_NUM_UNKNOWN 0xffffffff /**< Unknown */
 
 /**
  * A structure used to retrieve link-level information of an Ethernet port.
-- 
2.17.1


^ permalink raw reply	[flat|nested] 359+ messages in thread

* Re: [dpdk-dev] [PATCH v9 1/5] net/virtio: refactor devargs parsing
  2020-04-06  8:57         ` [dpdk-dev] [PATCH v9 1/5] net/virtio: refactor devargs parsing Ivan Dyukov
@ 2020-04-15 14:53           ` Maxime Coquelin
  0 siblings, 0 replies; 359+ messages in thread
From: Maxime Coquelin @ 2020-04-15 14:53 UTC (permalink / raw)
  To: Ivan Dyukov, dev, v.kuramshin, amorenoz, zhihong.wang, xiaolong.ye, mb



On 4/6/20 10:57 AM, Ivan Dyukov wrote:
> refactor vdpa specific devargs parsing to more generic way
> 
> Signed-off-by: Ivan Dyukov <i.dyukov@samsung.com>
> ---
>  drivers/net/virtio/virtio_ethdev.c | 34 +++++++++++++++++++++---------
>  1 file changed, 24 insertions(+), 10 deletions(-)
> 

Reviewed-by: Maxime Coquelin <maxime.coquelin@redhat.com>

Thanks,
Maxime


^ permalink raw reply	[flat|nested] 359+ messages in thread

* Re: [dpdk-dev] [PATCH v9 2/5] net/virtio: add link speed devarg
  2020-04-06  8:58         ` [dpdk-dev] [PATCH v9 2/5] net/virtio: add link speed devarg Ivan Dyukov
@ 2020-04-15 15:06           ` Maxime Coquelin
  0 siblings, 0 replies; 359+ messages in thread
From: Maxime Coquelin @ 2020-04-15 15:06 UTC (permalink / raw)
  To: Ivan Dyukov, dev, v.kuramshin, amorenoz, zhihong.wang, xiaolong.ye, mb



On 4/6/20 10:58 AM, Ivan Dyukov wrote:
> Some applications like pktgen use link speed to calculate
> transmission rate. It limits outcome traffic to hardcoded 10G.
> 
> This patch adds speed devarg which allows to configure
> link speed of virtio device.
> 
> Signed-off-by: Ivan Dyukov <i.dyukov@samsung.com>
> ---
>  doc/guides/nics/virtio.rst         |   7 ++
>  drivers/net/virtio/virtio_ethdev.c | 108 ++++++++++++++++++++++++-----
>  drivers/net/virtio/virtio_pci.h    |   1 +
>  3 files changed, 100 insertions(+), 16 deletions(-)
> 

Reviewed-by: Maxime Coquelin <maxime.coquelin@redhat.com>

Thanks,
Maxime


^ permalink raw reply	[flat|nested] 359+ messages in thread

* Re: [dpdk-dev] [PATCH v9 3/5] net/virtio-user: fix devargs parsing
  2020-04-06  8:58         ` [dpdk-dev] [PATCH v9 3/5] net/virtio-user: fix devargs parsing Ivan Dyukov
@ 2020-04-15 15:09           ` Maxime Coquelin
  0 siblings, 0 replies; 359+ messages in thread
From: Maxime Coquelin @ 2020-04-15 15:09 UTC (permalink / raw)
  To: Ivan Dyukov, dev, v.kuramshin, amorenoz, zhihong.wang, xiaolong.ye, mb
  Cc: stable



On 4/6/20 10:58 AM, Ivan Dyukov wrote:
> strtoull returns 0 if it fails to parse input string. It's ignored
> in get_integer_arg.
> 
> This patch handles error cases for strtoull function.

Fixes: ce2eabdd43ec ("net/virtio-user: add virtual device")
Cc: stable@dpdk.org

> 
> Signed-off-by: Ivan Dyukov <i.dyukov@samsung.com>
> ---
>  drivers/net/virtio/virtio_user_ethdev.c | 13 +++++++++----
>  1 file changed, 9 insertions(+), 4 deletions(-)
> 
> diff --git a/drivers/net/virtio/virtio_user_ethdev.c b/drivers/net/virtio/virtio_user_ethdev.c
> index e61af4068..a79f68a36 100644
> --- a/drivers/net/virtio/virtio_user_ethdev.c
> +++ b/drivers/net/virtio/virtio_user_ethdev.c
> @@ -477,12 +477,17 @@ static int
>  get_integer_arg(const char *key __rte_unused,
>  		const char *value, void *extra_args)
>  {
> +	uint64_t integer = 0;
>  	if (!value || !extra_args)
>  		return -EINVAL;
> -
> -	*(uint64_t *)extra_args = strtoull(value, NULL, 0);
> -
> -	return 0;
> +	errno = 0;
> +	integer = strtoull(value, NULL, 0);
> +	/* extra_args keeps default value, it should be replaced
> +	 * only in case of successful parsing of the 'value' arg
> +	 */
> +	if (errno == 0)
> +		*(uint64_t *)extra_args = integer;
> +	return -errno;
>  }
>  
>  static struct rte_eth_dev *
> 

I will fix the commit message when applying.

Reviewed-by: Maxime Coquelin <maxime.coquelin@redhat.com>

Thanks,
Maxime


^ permalink raw reply	[flat|nested] 359+ messages in thread

* Re: [dpdk-dev] [PATCH v9 4/5] net/virtio-user: adding link speed devarg
  2020-04-06  8:58         ` [dpdk-dev] [PATCH v9 4/5] net/virtio-user: adding link speed devarg Ivan Dyukov
@ 2020-04-15 15:10           ` Maxime Coquelin
  0 siblings, 0 replies; 359+ messages in thread
From: Maxime Coquelin @ 2020-04-15 15:10 UTC (permalink / raw)
  To: Ivan Dyukov, dev, v.kuramshin, amorenoz, zhihong.wang, xiaolong.ye, mb



On 4/6/20 10:58 AM, Ivan Dyukov wrote:
> virtio driver already parses speed devarg. virtio-user should add
> it to list of valid devargs and call eth_virtio_dev_init function
> which init speed value.
> 
> eth_virtio_dev_init already is called from virtio_user_pmd_probe
> function. The only change is required to enable speed devargs:
> adding speed to list of valid devargs.
> 
> Signed-off-by: Ivan Dyukov <i.dyukov@samsung.com>
> ---
>  doc/guides/nics/virtio.rst              | 8 ++++++++
>  drivers/net/virtio/virtio_user_ethdev.c | 5 ++++-
>  2 files changed, 12 insertions(+), 1 deletion(-)
> 

Reviewed-by: Maxime Coquelin <maxime.coquelin@redhat.com>

Thanks,
Maxime


^ permalink raw reply	[flat|nested] 359+ messages in thread

* Re: [dpdk-dev] [PATCH v9 5/5] net/virtio: Support of VIRTIO_NET_F_SPEED_DUPLEX
  2020-04-06  8:58         ` [dpdk-dev] [PATCH v9 5/5] net/virtio: Support of VIRTIO_NET_F_SPEED_DUPLEX Ivan Dyukov
@ 2020-04-15 15:17           ` Maxime Coquelin
  0 siblings, 0 replies; 359+ messages in thread
From: Maxime Coquelin @ 2020-04-15 15:17 UTC (permalink / raw)
  To: Ivan Dyukov, dev, v.kuramshin, amorenoz, zhihong.wang, xiaolong.ye, mb

Hi Ivan,

On 4/6/20 10:58 AM, Ivan Dyukov wrote:
> This patch adds a support of VIRTIO_NET_F_SPEED_DUPLEX feature
> for virtio driver. Set default speed to 0xffffffff and default
> duplex to 0xff
> 
> There are few ways to specify speed of the link:
s/few/two/
>    'speed' devarg
>    negotiate speed from qemu via VIRTIO_NET_F_SPEED_DUPLEX

Thanks for taking care of that, I appreciate it.
It should be used soon with vDPA.

> The highest priority is devarg. If devarg is not specified,
> drivers tries to negotiate it from qemu.
> 
> Signed-off-by: Ivan Dyukov <i.dyukov@samsung.com>
> ---
>  doc/guides/nics/virtio.rst         |  4 ++--
>  drivers/net/virtio/virtio_ethdev.c | 16 +++++++++++++++-
>  drivers/net/virtio/virtio_ethdev.h |  3 ++-
>  drivers/net/virtio/virtio_pci.h    | 15 +++++++++++++++
>  lib/librte_ethdev/rte_ethdev.h     | 27 ++++++++++++++-------------
>  5 files changed, 48 insertions(+), 17 deletions(-)
> 
> diff --git a/doc/guides/nics/virtio.rst b/doc/guides/nics/virtio.rst
> index e70b6653b..06c7a19aa 100644
> --- a/doc/guides/nics/virtio.rst
> +++ b/doc/guides/nics/virtio.rst
> @@ -361,7 +361,7 @@ Below devargs are supported by the PCI virtio driver:
>      It is used to specify link speed of virtio device, in units of 1Mb.
>      Link speed is a part of link status structure. It could be requested
>      by application using rte_eth_link_get_nowait function.
> -    (Default: 10000 (10G))
> +    (Default: 0xffffffff (unknown))

I think the Default should be changed in the initial patch, not in the
last one.

>  
>  Below devargs are supported by the virtio-user vdev:
>  
> @@ -415,7 +415,7 @@ Below devargs are supported by the virtio-user vdev:
>      It is used to specify link speed of virtio device, in units of 1Mb.
>      Link speed is a part of link status structure. It could be requested
>      by application using rte_eth_link_get_nowait function.
> -    (Default: 10000 (10G))
> +    (Default: 0xffffffff (unknown))
>  
>  
>  Virtio paths Selection and Usage
> diff --git a/drivers/net/virtio/virtio_ethdev.c b/drivers/net/virtio/virtio_ethdev.c
> index eb46a5a11..0137efcc5 100644
> --- a/drivers/net/virtio/virtio_ethdev.c
> +++ b/drivers/net/virtio/virtio_ethdev.c
> @@ -1718,6 +1718,20 @@ virtio_init_device(struct rte_eth_dev *eth_dev, uint64_t req_features)
>  		     hw->mac_addr[0], hw->mac_addr[1], hw->mac_addr[2],
>  		     hw->mac_addr[3], hw->mac_addr[4], hw->mac_addr[5]);
>  
> +	if (vtpci_with_feature(hw, VIRTIO_NET_F_SPEED_DUPLEX)) {
> +		config = &local_config;
> +		/* if speed is not specified in devargs */
> +		if (hw->speed == ETH_SPEED_NUM_UNKNOWN) {
> +			vtpci_read_dev_config(hw,
> +				offsetof(struct virtio_net_config, speed),
> +				&config->speed, sizeof(config->speed));
> +			hw->speed = config->speed;
> +		}
> +	}
> +
> +	PMD_INIT_LOG(DEBUG, "link speed = %u%s",
> +		hw->speed, hw->speed == ETH_SPEED_NUM_UNKNOWN ?
> +		"(UNKNOWN)" : "");
>  	if (vtpci_with_feature(hw, VIRTIO_NET_F_CTRL_VQ)) {
>  		config = &local_config;
>  
> @@ -1865,7 +1879,7 @@ int
>  eth_virtio_dev_init(struct rte_eth_dev *eth_dev)
>  {
>  	struct virtio_hw *hw = eth_dev->data->dev_private;
> -	uint32_t speed = ETH_SPEED_NUM_10G;
> +	uint32_t speed = ETH_SPEED_NUM_UNKNOWN;
>  	int ret;
>  
>  	if (sizeof(struct virtio_net_hdr_mrg_rxbuf) > RTE_PKTMBUF_HEADROOM) {
> diff --git a/drivers/net/virtio/virtio_ethdev.h b/drivers/net/virtio/virtio_ethdev.h
> index cd8947656..febaf17a8 100644
> --- a/drivers/net/virtio/virtio_ethdev.h
> +++ b/drivers/net/virtio/virtio_ethdev.h
> @@ -37,7 +37,8 @@
>  	 1ULL << VIRTIO_F_RING_PACKED	  |	\
>  	 1ULL << VIRTIO_F_IOMMU_PLATFORM  |	\
>  	 1ULL << VIRTIO_F_ORDER_PLATFORM  |	\
> -	 1ULL << VIRTIO_F_NOTIFICATION_DATA)
> +	 1ULL << VIRTIO_F_NOTIFICATION_DATA | \
> +	 1ULL << VIRTIO_NET_F_SPEED_DUPLEX)
>  
>  #define VIRTIO_PMD_SUPPORTED_GUEST_FEATURES	\
>  	(VIRTIO_PMD_DEFAULT_GUEST_FEATURES |	\
> diff --git a/drivers/net/virtio/virtio_pci.h b/drivers/net/virtio/virtio_pci.h
> index ed98e11c3..2948760ab 100644
> --- a/drivers/net/virtio/virtio_pci.h
> +++ b/drivers/net/virtio/virtio_pci.h
> @@ -141,6 +141,9 @@ struct virtnet_ctl;
>   */
>  #define VIRTIO_F_NOTIFICATION_DATA 38
>  
> +/* Device set linkspeed and duplex */
> +#define VIRTIO_NET_F_SPEED_DUPLEX 63
> +
>  /* The Guest publishes the used index for which it expects an interrupt
>   * at the end of the avail ring. Host should ignore the avail->flags field. */
>  /* The Host publishes the avail index for which it expects a kick
> @@ -306,6 +309,18 @@ struct virtio_net_config {
>  	uint16_t   status;
>  	uint16_t   max_virtqueue_pairs;
>  	uint16_t   mtu;
> +	/*
> +	 * speed, in units of 1Mb. All values 0 to INT_MAX are legal.
> +	 * Any other value stands for unknown.
> +	 */
> +	uint32_t speed;
> +	/*
> +	 * 0x00 - half duplex
> +	 * 0x01 - full duplex
> +	 * Any other value stands for unknown.
> +	 */
> +	uint8_t duplex;
> +
>  } __attribute__((packed));
>  
>  /*

Below change should be in a dedicated patch, and I would prefer it to be
the first patch in the series.

> diff --git a/lib/librte_ethdev/rte_ethdev.h b/lib/librte_ethdev/rte_ethdev.h
> index d1a593ad1..a15ea572e 100644
> --- a/lib/librte_ethdev/rte_ethdev.h
> +++ b/lib/librte_ethdev/rte_ethdev.h
> @@ -287,19 +287,20 @@ struct rte_eth_stats {
>  /**
>   * Ethernet numeric link speeds in Mbps
>   */
> -#define ETH_SPEED_NUM_NONE         0 /**< Not defined */
> -#define ETH_SPEED_NUM_10M         10 /**<  10 Mbps */
> -#define ETH_SPEED_NUM_100M       100 /**< 100 Mbps */
> -#define ETH_SPEED_NUM_1G        1000 /**<   1 Gbps */
> -#define ETH_SPEED_NUM_2_5G      2500 /**< 2.5 Gbps */
> -#define ETH_SPEED_NUM_5G        5000 /**<   5 Gbps */
> -#define ETH_SPEED_NUM_10G      10000 /**<  10 Gbps */
> -#define ETH_SPEED_NUM_20G      20000 /**<  20 Gbps */
> -#define ETH_SPEED_NUM_25G      25000 /**<  25 Gbps */
> -#define ETH_SPEED_NUM_40G      40000 /**<  40 Gbps */
> -#define ETH_SPEED_NUM_50G      50000 /**<  50 Gbps */
> -#define ETH_SPEED_NUM_56G      56000 /**<  56 Gbps */
> -#define ETH_SPEED_NUM_100G    100000 /**< 100 Gbps */
> +#define ETH_SPEED_NUM_NONE             0 /**< Not defined */
> +#define ETH_SPEED_NUM_10M             10 /**<  10 Mbps */
> +#define ETH_SPEED_NUM_100M           100 /**< 100 Mbps */
> +#define ETH_SPEED_NUM_1G            1000 /**<   1 Gbps */
> +#define ETH_SPEED_NUM_2_5G          2500 /**< 2.5 Gbps */
> +#define ETH_SPEED_NUM_5G            5000 /**<   5 Gbps */
> +#define ETH_SPEED_NUM_10G          10000 /**<  10 Gbps */
> +#define ETH_SPEED_NUM_20G          20000 /**<  20 Gbps */
> +#define ETH_SPEED_NUM_25G          25000 /**<  25 Gbps */
> +#define ETH_SPEED_NUM_40G          40000 /**<  40 Gbps */
> +#define ETH_SPEED_NUM_50G          50000 /**<  50 Gbps */
> +#define ETH_SPEED_NUM_56G          56000 /**<  56 Gbps */
> +#define ETH_SPEED_NUM_100G        100000 /**< 100 Gbps */
> +#define ETH_SPEED_NUM_UNKNOWN 0xffffffff /**< Unknown */
>  
>  /**
>   * A structure used to retrieve link-level information of an Ethernet port.
> 

Thanks,
Maxime


^ permalink raw reply	[flat|nested] 359+ messages in thread

* [dpdk-dev] [PATCH v10 0/6] net/virtio: add link speed devarg
       [not found]   ` <CGME20200415200437eucas1p2d57f1d9d3e924fc4425538e19bd2c95a@eucas1p2.samsung.com>
@ 2020-04-15 20:03     ` Ivan Dyukov
       [not found]       ` <CGME20200415200440eucas1p2b403294b5d61d79bce402bc4a3f96de3@eucas1p2.samsung.com>
                         ` (5 more replies)
  0 siblings, 6 replies; 359+ messages in thread
From: Ivan Dyukov @ 2020-04-15 20:03 UTC (permalink / raw)
  To: dev, maxime.coquelin, i.dyukov, v.kuramshin, amorenoz,
	zhihong.wang, xiaolong.ye, mb

 doc/guides/nics/virtio.rst              |  15 +++++++++++++++
 drivers/net/virtio/virtio_ethdev.c      | 143 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++--------------------
 drivers/net/virtio/virtio_ethdev.h      |   3 ++-
 drivers/net/virtio/virtio_pci.h         |  16 ++++++++++++++++
 drivers/net/virtio/virtio_user_ethdev.c |  18 +++++++++++++-----
 lib/librte_ethdev/rte_ethdev.h          |  27 ++++++++++++++-------------
 6 files changed, 183 insertions(+), 39 deletions(-)

v10 changes:
* [PATCH 1/6] unknown speed is moved to first patch
* [PATCH 3/6] rebased to latest changes
* [PATCH 4/6] updated commit message
* [PATCH 6/6] rebased to latest changes

v9 chagnes:
* [PATCH 2/5] remove limited set of acceptable speeds [10G, 20G, 40G, 56G, 100G], now all natural numbers are acceptable
* [PATCH 2/5] returns speed_capa as maximum available capability for specified speed
* [PATCH 5/5] remove duplex negotiation
* [PATCH 5/5] set default speed to 0xffffffff

v8 changes:
* fix code style

v7 chagnes:
* rebased to latest master
* added support of VIRTIO_NET_F_SPEED_DUPLEX

v6 changes:
* fix code style

v5 changes:
* fixed code style
* fixed commit message and logging text

v4 changes:
* link_speed renamed to speed devarg
* speed devarg is added to virtio-user driver

v3 changes:
* link_speed devarg is added to virtio documentation


^ permalink raw reply	[flat|nested] 359+ messages in thread

* [dpdk-dev] [PATCH v10 1/6] net/virtio: replace default virtio speed
       [not found]       ` <CGME20200415200440eucas1p2b403294b5d61d79bce402bc4a3f96de3@eucas1p2.samsung.com>
@ 2020-04-15 20:03         ` Ivan Dyukov
  0 siblings, 0 replies; 359+ messages in thread
From: Ivan Dyukov @ 2020-04-15 20:03 UTC (permalink / raw)
  To: dev, maxime.coquelin, i.dyukov, v.kuramshin, amorenoz,
	zhihong.wang, xiaolong.ye, mb

This patch set speed to unknown

Signed-off-by: Ivan Dyukov <i.dyukov@samsung.com>
---
 drivers/net/virtio/virtio_ethdev.c |  4 ++--
 lib/librte_ethdev/rte_ethdev.h     | 27 ++++++++++++++-------------
 2 files changed, 16 insertions(+), 15 deletions(-)

diff --git a/drivers/net/virtio/virtio_ethdev.c b/drivers/net/virtio/virtio_ethdev.c
index f9d0ea70d..e98a76ea2 100644
--- a/drivers/net/virtio/virtio_ethdev.c
+++ b/drivers/net/virtio/virtio_ethdev.c
@@ -2371,7 +2371,7 @@ virtio_dev_link_update(struct rte_eth_dev *dev, __rte_unused int wait_to_complet
 
 	memset(&link, 0, sizeof(link));
 	link.link_duplex = ETH_LINK_FULL_DUPLEX;
-	link.link_speed  = ETH_SPEED_NUM_10G;
+	link.link_speed  = ETH_SPEED_NUM_UNKNOWN;
 	link.link_autoneg = ETH_LINK_FIXED;
 
 	if (!hw->started) {
@@ -2427,7 +2427,7 @@ virtio_dev_info_get(struct rte_eth_dev *dev, struct rte_eth_dev_info *dev_info)
 	uint64_t tso_mask, host_features;
 	struct virtio_hw *hw = dev->data->dev_private;
 
-	dev_info->speed_capa = ETH_LINK_SPEED_10G; /* fake value */
+	dev_info->speed_capa = ETH_LINK_SPEED_AUTONEG; /* fake value */
 
 	dev_info->max_rx_queues =
 		RTE_MIN(hw->max_queue_pairs, VIRTIO_MAX_RX_QUEUES);
diff --git a/lib/librte_ethdev/rte_ethdev.h b/lib/librte_ethdev/rte_ethdev.h
index d1a593ad1..a15ea572e 100644
--- a/lib/librte_ethdev/rte_ethdev.h
+++ b/lib/librte_ethdev/rte_ethdev.h
@@ -287,19 +287,20 @@ struct rte_eth_stats {
 /**
  * Ethernet numeric link speeds in Mbps
  */
-#define ETH_SPEED_NUM_NONE         0 /**< Not defined */
-#define ETH_SPEED_NUM_10M         10 /**<  10 Mbps */
-#define ETH_SPEED_NUM_100M       100 /**< 100 Mbps */
-#define ETH_SPEED_NUM_1G        1000 /**<   1 Gbps */
-#define ETH_SPEED_NUM_2_5G      2500 /**< 2.5 Gbps */
-#define ETH_SPEED_NUM_5G        5000 /**<   5 Gbps */
-#define ETH_SPEED_NUM_10G      10000 /**<  10 Gbps */
-#define ETH_SPEED_NUM_20G      20000 /**<  20 Gbps */
-#define ETH_SPEED_NUM_25G      25000 /**<  25 Gbps */
-#define ETH_SPEED_NUM_40G      40000 /**<  40 Gbps */
-#define ETH_SPEED_NUM_50G      50000 /**<  50 Gbps */
-#define ETH_SPEED_NUM_56G      56000 /**<  56 Gbps */
-#define ETH_SPEED_NUM_100G    100000 /**< 100 Gbps */
+#define ETH_SPEED_NUM_NONE             0 /**< Not defined */
+#define ETH_SPEED_NUM_10M             10 /**<  10 Mbps */
+#define ETH_SPEED_NUM_100M           100 /**< 100 Mbps */
+#define ETH_SPEED_NUM_1G            1000 /**<   1 Gbps */
+#define ETH_SPEED_NUM_2_5G          2500 /**< 2.5 Gbps */
+#define ETH_SPEED_NUM_5G            5000 /**<   5 Gbps */
+#define ETH_SPEED_NUM_10G          10000 /**<  10 Gbps */
+#define ETH_SPEED_NUM_20G          20000 /**<  20 Gbps */
+#define ETH_SPEED_NUM_25G          25000 /**<  25 Gbps */
+#define ETH_SPEED_NUM_40G          40000 /**<  40 Gbps */
+#define ETH_SPEED_NUM_50G          50000 /**<  50 Gbps */
+#define ETH_SPEED_NUM_56G          56000 /**<  56 Gbps */
+#define ETH_SPEED_NUM_100G        100000 /**< 100 Gbps */
+#define ETH_SPEED_NUM_UNKNOWN 0xffffffff /**< Unknown */
 
 /**
  * A structure used to retrieve link-level information of an Ethernet port.
-- 
2.17.1


^ permalink raw reply	[flat|nested] 359+ messages in thread

* [dpdk-dev] [PATCH v10 2/6] net/virtio: refactor devargs parsing
       [not found]       ` <CGME20200415200441eucas1p2e08269b40c2bfbda7a1c44e1cf984248@eucas1p2.samsung.com>
@ 2020-04-15 20:03         ` Ivan Dyukov
  0 siblings, 0 replies; 359+ messages in thread
From: Ivan Dyukov @ 2020-04-15 20:03 UTC (permalink / raw)
  To: dev, maxime.coquelin, i.dyukov, v.kuramshin, amorenoz,
	zhihong.wang, xiaolong.ye, mb

refactor vdpa specific devargs parsing to more generic way

Signed-off-by: Ivan Dyukov <i.dyukov@samsung.com>
---
 drivers/net/virtio/virtio_ethdev.c | 34 +++++++++++++++++++++---------
 1 file changed, 24 insertions(+), 10 deletions(-)

diff --git a/drivers/net/virtio/virtio_ethdev.c b/drivers/net/virtio/virtio_ethdev.c
index e98a76ea2..60195ab3c 100644
--- a/drivers/net/virtio/virtio_ethdev.c
+++ b/drivers/net/virtio/virtio_ethdev.c
@@ -1957,16 +1957,18 @@ eth_virtio_dev_uninit(struct rte_eth_dev *eth_dev)
 }
 
 static int vdpa_check_handler(__rte_unused const char *key,
-		const char *value, __rte_unused void *opaque)
+		const char *value, void *ret_val)
 {
-	if (strcmp(value, "1"))
-		return -1;
+	if (strcmp(value, "1") == 0)
+		*(int *)ret_val = 1;
+	else
+		*(int *)ret_val = 0;
 
 	return 0;
 }
 
 static int
-vdpa_mode_selected(struct rte_devargs *devargs)
+virtio_dev_devargs_parse(struct rte_devargs *devargs, int *vdpa)
 {
 	struct rte_kvargs *kvlist;
 	const char *key = "vdpa";
@@ -1982,12 +1984,16 @@ vdpa_mode_selected(struct rte_devargs *devargs)
 	if (!rte_kvargs_count(kvlist, key))
 		goto exit;
 
-	/* vdpa mode selected when there's a key-value pair: vdpa=1 */
-	if (rte_kvargs_process(kvlist, key,
-				vdpa_check_handler, NULL) < 0) {
-		goto exit;
+	if (vdpa) {
+		/* vdpa mode selected when there's a key-value pair:
+		 * vdpa=1
+		 */
+		ret = rte_kvargs_process(kvlist, key,
+				vdpa_check_handler, vdpa);
+		if (ret < 0)
+			goto exit;
 	}
-	ret = 1;
+
 
 exit:
 	rte_kvargs_free(kvlist);
@@ -1997,8 +2003,16 @@ vdpa_mode_selected(struct rte_devargs *devargs)
 static int eth_virtio_pci_probe(struct rte_pci_driver *pci_drv __rte_unused,
 	struct rte_pci_device *pci_dev)
 {
+	int vdpa = 0;
+	int ret = 0;
+
+	ret = virtio_dev_devargs_parse(pci_dev->device.devargs, &vdpa);
+	if (ret < 0) {
+		PMD_INIT_LOG(ERR, "devargs parsing is failed");
+		return ret;
+	}
 	/* virtio pmd skips probe if device needs to work in vdpa mode */
-	if (vdpa_mode_selected(pci_dev->device.devargs))
+	if (vdpa == 1)
 		return 1;
 
 	return rte_eth_dev_pci_generic_probe(pci_dev, sizeof(struct virtio_hw),
-- 
2.17.1


^ permalink raw reply	[flat|nested] 359+ messages in thread

* [dpdk-dev] [PATCH v10 3/6] net/virtio: add link speed devarg
       [not found]       ` <CGME20200415200443eucas1p1d131bd52589c9f43d552c398fb3c10c3@eucas1p1.samsung.com>
@ 2020-04-15 20:03         ` Ivan Dyukov
  0 siblings, 0 replies; 359+ messages in thread
From: Ivan Dyukov @ 2020-04-15 20:03 UTC (permalink / raw)
  To: dev, maxime.coquelin, i.dyukov, v.kuramshin, amorenoz,
	zhihong.wang, xiaolong.ye, mb

Default value of link speed is 0xffffffff (Unknown)

This patch adds speed devarg which allows to configure
link speed of virtio device.

Signed-off-by: Ivan Dyukov <i.dyukov@samsung.com>
---
 doc/guides/nics/virtio.rst         |   7 ++
 drivers/net/virtio/virtio_ethdev.c | 107 ++++++++++++++++++++++++-----
 drivers/net/virtio/virtio_pci.h    |   1 +
 3 files changed, 99 insertions(+), 16 deletions(-)

diff --git a/doc/guides/nics/virtio.rst b/doc/guides/nics/virtio.rst
index d1f5fb898..55bc6a267 100644
--- a/doc/guides/nics/virtio.rst
+++ b/doc/guides/nics/virtio.rst
@@ -356,6 +356,13 @@ Below devargs are supported by the PCI virtio driver:
     a virtio device needs to work in vDPA mode.
     (Default: 0 (disabled))
 
+#.  ``speed``:
+
+    It is used to specify link speed of virtio device, in units of 1Mb.
+    Link speed is a part of link status structure. It could be requested
+    by application using rte_eth_link_get_nowait function.
+    (Default: 0xffffffff (Unknown))
+
 Below devargs are supported by the virtio-user vdev:
 
 #.  ``path``:
diff --git a/drivers/net/virtio/virtio_ethdev.c b/drivers/net/virtio/virtio_ethdev.c
index 60195ab3c..306241d37 100644
--- a/drivers/net/virtio/virtio_ethdev.c
+++ b/drivers/net/virtio/virtio_ethdev.c
@@ -45,6 +45,10 @@ static int virtio_dev_promiscuous_enable(struct rte_eth_dev *dev);
 static int virtio_dev_promiscuous_disable(struct rte_eth_dev *dev);
 static int virtio_dev_allmulticast_enable(struct rte_eth_dev *dev);
 static int virtio_dev_allmulticast_disable(struct rte_eth_dev *dev);
+static uint32_t virtio_dev_speed_capa_get(uint32_t speed);
+static int virtio_dev_devargs_parse(struct rte_devargs *devargs,
+	int *vdpa,
+	uint32_t *speed);
 static int virtio_dev_info_get(struct rte_eth_dev *dev,
 				struct rte_eth_dev_info *dev_info);
 static int virtio_dev_link_update(struct rte_eth_dev *dev,
@@ -1861,6 +1865,7 @@ int
 eth_virtio_dev_init(struct rte_eth_dev *eth_dev)
 {
 	struct virtio_hw *hw = eth_dev->data->dev_private;
+	uint32_t speed = ETH_SPEED_NUM_UNKNOWN;
 	int ret;
 
 	if (sizeof(struct virtio_net_hdr_mrg_rxbuf) > RTE_PKTMBUF_HEADROOM) {
@@ -1886,7 +1891,11 @@ eth_virtio_dev_init(struct rte_eth_dev *eth_dev)
 
 		return 0;
 	}
-
+	ret = virtio_dev_devargs_parse(eth_dev->device->devargs,
+		 NULL, &speed);
+	if (ret < 0)
+		return ret;
+	hw->speed = speed;
 	/*
 	 * Pass the information to the rte_eth_dev_close() that it should also
 	 * release the private port resources.
@@ -1967,33 +1976,100 @@ static int vdpa_check_handler(__rte_unused const char *key,
 	return 0;
 }
 
+
+static uint32_t
+virtio_dev_speed_capa_get(uint32_t speed)
+{
+	struct speed_caps {
+		uint32_t min_speed;
+		uint32_t speed_capa;
+	};
+	struct speed_caps caps[] = {
+		{ETH_SPEED_NUM_10M,    ETH_LINK_SPEED_10M},
+		{ETH_SPEED_NUM_100M,   ETH_LINK_SPEED_100M},
+		{ETH_SPEED_NUM_1G,     ETH_LINK_SPEED_1G},
+		{ETH_SPEED_NUM_2_5G,   ETH_LINK_SPEED_2_5G},
+		{ETH_SPEED_NUM_5G,     ETH_LINK_SPEED_5G},
+		{ETH_SPEED_NUM_10G,    ETH_LINK_SPEED_10G},
+		{ETH_SPEED_NUM_20G,    ETH_LINK_SPEED_20G},
+		{ETH_SPEED_NUM_25G,    ETH_LINK_SPEED_25G},
+		{ETH_SPEED_NUM_40G,    ETH_LINK_SPEED_40G},
+		{ETH_SPEED_NUM_50G,    ETH_LINK_SPEED_50G},
+		{ETH_SPEED_NUM_56G,    ETH_LINK_SPEED_56G},
+		{ETH_SPEED_NUM_100G,   ETH_LINK_SPEED_100G}
+	};
+	const uint32_t caps_size = sizeof(caps) / sizeof(struct speed_caps);
+	uint32_t speed_capa = ETH_LINK_SPEED_AUTONEG;
+	if (speed != ETH_SPEED_NUM_UNKNOWN) {
+		/* find maximum suitable speed capability */
+		for (uint32_t i = 0; i < caps_size; i++) {
+			if (speed >= caps[i].min_speed)
+				speed_capa = caps[i].speed_capa;
+		}
+	}
+	return speed_capa;
+}
+
+
+#define VIRTIO_ARG_SPEED      "speed"
+#define VIRTIO_ARG_VDPA       "vdpa"
+
+
 static int
-virtio_dev_devargs_parse(struct rte_devargs *devargs, int *vdpa)
+link_speed_handler(const char *key __rte_unused,
+		const char *value, void *ret_val)
+{
+	uint32_t val;
+	if (!value || !ret_val)
+		return -EINVAL;
+	errno = 0;
+	val = strtoul(value, NULL, 0);
+	/* validate input */
+	if (errno != 0)
+		return -EINVAL;
+	*(uint32_t *)ret_val = val;
+
+	return 0;
+}
+
+
+static int
+virtio_dev_devargs_parse(struct rte_devargs *devargs, int *vdpa,
+	uint32_t *speed)
 {
 	struct rte_kvargs *kvlist;
-	const char *key = "vdpa";
 	int ret = 0;
 
 	if (devargs == NULL)
 		return 0;
 
 	kvlist = rte_kvargs_parse(devargs->args, NULL);
-	if (kvlist == NULL)
+	if (kvlist == NULL) {
+		PMD_INIT_LOG(ERR, "error when parsing param");
 		return 0;
-
-	if (!rte_kvargs_count(kvlist, key))
-		goto exit;
-
-	if (vdpa) {
+	}
+	if (vdpa && rte_kvargs_count(kvlist, VIRTIO_ARG_VDPA) == 1) {
 		/* vdpa mode selected when there's a key-value pair:
 		 * vdpa=1
 		 */
-		ret = rte_kvargs_process(kvlist, key,
+		ret = rte_kvargs_process(kvlist, VIRTIO_ARG_VDPA,
 				vdpa_check_handler, vdpa);
-		if (ret < 0)
+		if (ret < 0) {
+			PMD_INIT_LOG(ERR, "Failed to parse %s",
+				VIRTIO_ARG_VDPA);
 			goto exit;
+		}
+	}
+	if (speed && rte_kvargs_count(kvlist, VIRTIO_ARG_SPEED) == 1) {
+		ret = rte_kvargs_process(kvlist,
+					VIRTIO_ARG_SPEED,
+					link_speed_handler, speed);
+		if (ret < 0) {
+			PMD_INIT_LOG(ERR, "Failed to parse %s",
+					VIRTIO_ARG_SPEED);
+			goto exit;
+		}
 	}
-
 
 exit:
 	rte_kvargs_free(kvlist);
@@ -2006,7 +2082,7 @@ static int eth_virtio_pci_probe(struct rte_pci_driver *pci_drv __rte_unused,
 	int vdpa = 0;
 	int ret = 0;
 
-	ret = virtio_dev_devargs_parse(pci_dev->device.devargs, &vdpa);
+	ret = virtio_dev_devargs_parse(pci_dev->device.devargs, &vdpa, NULL);
 	if (ret < 0) {
 		PMD_INIT_LOG(ERR, "devargs parsing is failed");
 		return ret;
@@ -2385,7 +2461,7 @@ virtio_dev_link_update(struct rte_eth_dev *dev, __rte_unused int wait_to_complet
 
 	memset(&link, 0, sizeof(link));
 	link.link_duplex = ETH_LINK_FULL_DUPLEX;
-	link.link_speed  = ETH_SPEED_NUM_UNKNOWN;
+	link.link_speed  = hw->speed;
 	link.link_autoneg = ETH_LINK_FIXED;
 
 	if (!hw->started) {
@@ -2440,8 +2516,7 @@ virtio_dev_info_get(struct rte_eth_dev *dev, struct rte_eth_dev_info *dev_info)
 {
 	uint64_t tso_mask, host_features;
 	struct virtio_hw *hw = dev->data->dev_private;
-
-	dev_info->speed_capa = ETH_LINK_SPEED_AUTONEG; /* fake value */
+	dev_info->speed_capa = virtio_dev_speed_capa_get(hw->speed);
 
 	dev_info->max_rx_queues =
 		RTE_MIN(hw->max_queue_pairs, VIRTIO_MAX_RX_QUEUES);
diff --git a/drivers/net/virtio/virtio_pci.h b/drivers/net/virtio/virtio_pci.h
index 7433d2f08..ed98e11c3 100644
--- a/drivers/net/virtio/virtio_pci.h
+++ b/drivers/net/virtio/virtio_pci.h
@@ -259,6 +259,7 @@ struct virtio_hw {
 	uint16_t    port_id;
 	uint8_t     mac_addr[RTE_ETHER_ADDR_LEN];
 	uint32_t    notify_off_multiplier;
+	uint32_t    speed;  /* link speed in MB */
 	uint8_t     *isr;
 	uint16_t    *notify_base;
 	struct virtio_pci_common_cfg *common_cfg;
-- 
2.17.1


^ permalink raw reply	[flat|nested] 359+ messages in thread

* [dpdk-dev] [PATCH v10 4/6] net/virtio-user: fix devargs parsing
       [not found]       ` <CGME20200415200445eucas1p2406d3f5b1794958c8345741c83d2000e@eucas1p2.samsung.com>
@ 2020-04-15 20:03         ` Ivan Dyukov
  0 siblings, 0 replies; 359+ messages in thread
From: Ivan Dyukov @ 2020-04-15 20:03 UTC (permalink / raw)
  To: dev, maxime.coquelin, i.dyukov, v.kuramshin, amorenoz,
	zhihong.wang, xiaolong.ye, mb
  Cc: stable

strtoull returns 0 if it fails to parse input string. It's ignored
in get_integer_arg.

This patch handles error cases for strtoull function.

Fixes: ce2eabdd43ec ("net/virtio-user: add virtual device")
Cc: stable@dpdk.org
Signed-off-by: Ivan Dyukov <i.dyukov@samsung.com>
---
 drivers/net/virtio/virtio_user_ethdev.c | 13 +++++++++----
 1 file changed, 9 insertions(+), 4 deletions(-)

diff --git a/drivers/net/virtio/virtio_user_ethdev.c b/drivers/net/virtio/virtio_user_ethdev.c
index e61af4068..a79f68a36 100644
--- a/drivers/net/virtio/virtio_user_ethdev.c
+++ b/drivers/net/virtio/virtio_user_ethdev.c
@@ -477,12 +477,17 @@ static int
 get_integer_arg(const char *key __rte_unused,
 		const char *value, void *extra_args)
 {
+	uint64_t integer = 0;
 	if (!value || !extra_args)
 		return -EINVAL;
-
-	*(uint64_t *)extra_args = strtoull(value, NULL, 0);
-
-	return 0;
+	errno = 0;
+	integer = strtoull(value, NULL, 0);
+	/* extra_args keeps default value, it should be replaced
+	 * only in case of successful parsing of the 'value' arg
+	 */
+	if (errno == 0)
+		*(uint64_t *)extra_args = integer;
+	return -errno;
 }
 
 static struct rte_eth_dev *
-- 
2.17.1


^ permalink raw reply	[flat|nested] 359+ messages in thread

* [dpdk-dev] [PATCH v10 5/6] net/virtio-user: adding link speed devarg
       [not found]       ` <CGME20200415200447eucas1p29e0efc7384df496cc7390ad5aa4891ea@eucas1p2.samsung.com>
@ 2020-04-15 20:03         ` Ivan Dyukov
  0 siblings, 0 replies; 359+ messages in thread
From: Ivan Dyukov @ 2020-04-15 20:03 UTC (permalink / raw)
  To: dev, maxime.coquelin, i.dyukov, v.kuramshin, amorenoz,
	zhihong.wang, xiaolong.ye, mb

virtio driver already parses speed devarg. virtio-user should add
it to list of valid devargs and call eth_virtio_dev_init function
which init speed value.

eth_virtio_dev_init already is called from virtio_user_pmd_probe
function. The only change is required to enable speed devargs:
adding speed to list of valid devargs.

Signed-off-by: Ivan Dyukov <i.dyukov@samsung.com>
---
 doc/guides/nics/virtio.rst              | 8 ++++++++
 drivers/net/virtio/virtio_user_ethdev.c | 5 ++++-
 2 files changed, 12 insertions(+), 1 deletion(-)

diff --git a/doc/guides/nics/virtio.rst b/doc/guides/nics/virtio.rst
index 55bc6a267..451789705 100644
--- a/doc/guides/nics/virtio.rst
+++ b/doc/guides/nics/virtio.rst
@@ -410,6 +410,14 @@ Below devargs are supported by the virtio-user vdev:
     It is used to enable virtio device packed virtqueue feature.
     (Default: 0 (disabled))
 
+#.  ``speed``:
+
+    It is used to specify link speed of virtio device, in units of 1Mb.
+    Link speed is a part of link status structure. It could be requested
+    by application using rte_eth_link_get_nowait function.
+    (Default: 0xffffffff (Unknown))
+
+
 Virtio paths Selection and Usage
 --------------------------------
 
diff --git a/drivers/net/virtio/virtio_user_ethdev.c b/drivers/net/virtio/virtio_user_ethdev.c
index a79f68a36..5b32d30fa 100644
--- a/drivers/net/virtio/virtio_user_ethdev.c
+++ b/drivers/net/virtio/virtio_user_ethdev.c
@@ -450,6 +450,8 @@ static const char *valid_args[] = {
 	VIRTIO_USER_ARG_IN_ORDER,
 #define VIRTIO_USER_ARG_PACKED_VQ      "packed_vq"
 	VIRTIO_USER_ARG_PACKED_VQ,
+#define VIRTIO_USER_ARG_SPEED          "speed"
+	VIRTIO_USER_ARG_SPEED,
 	NULL
 };
 
@@ -782,4 +784,5 @@ RTE_PMD_REGISTER_PARAM_STRING(net_virtio_user,
 	"server=<0|1> "
 	"mrg_rxbuf=<0|1> "
 	"in_order=<0|1> "
-	"packed_vq=<0|1>");
+	"packed_vq=<0|1> "
+	"speed=<int>");
-- 
2.17.1


^ permalink raw reply	[flat|nested] 359+ messages in thread

* [dpdk-dev] [PATCH v10 6/6] net/virtio: Support of VIRTIO_NET_F_SPEED_DUPLEX
       [not found]       ` <CGME20200415200448eucas1p2ca449e8b15c2288adf202c7bf045fb9b@eucas1p2.samsung.com>
@ 2020-04-15 20:03         ` Ivan Dyukov
  0 siblings, 0 replies; 359+ messages in thread
From: Ivan Dyukov @ 2020-04-15 20:03 UTC (permalink / raw)
  To: dev, maxime.coquelin, i.dyukov, v.kuramshin, amorenoz,
	zhihong.wang, xiaolong.ye, mb
  Cc: Ivan Dyukov

This patch adds a support of VIRTIO_NET_F_SPEED_DUPLEX feature
for virtio driver.

There are two ways to specify speed of the link:
  * 'speed' devarg
  * negotiate speed from qemu via VIRTIO_NET_F_SPEED_DUPLEX
The highest priority is devarg. If devarg is not specified,
driver tries to negotiate it from qemu.

Signed-off-by: Ivan Dyukov <ivan.dyukov@gmail.com>
---
 drivers/net/virtio/virtio_ethdev.c | 14 ++++++++++++++
 drivers/net/virtio/virtio_ethdev.h |  3 ++-
 drivers/net/virtio/virtio_pci.h    | 15 +++++++++++++++
 3 files changed, 31 insertions(+), 1 deletion(-)

diff --git a/drivers/net/virtio/virtio_ethdev.c b/drivers/net/virtio/virtio_ethdev.c
index 306241d37..b08270714 100644
--- a/drivers/net/virtio/virtio_ethdev.c
+++ b/drivers/net/virtio/virtio_ethdev.c
@@ -1718,6 +1718,20 @@ virtio_init_device(struct rte_eth_dev *eth_dev, uint64_t req_features)
 		     hw->mac_addr[0], hw->mac_addr[1], hw->mac_addr[2],
 		     hw->mac_addr[3], hw->mac_addr[4], hw->mac_addr[5]);
 
+	if (vtpci_with_feature(hw, VIRTIO_NET_F_SPEED_DUPLEX)) {
+		config = &local_config;
+		/* if speed is not specified in devargs */
+		if (hw->speed == ETH_SPEED_NUM_UNKNOWN) {
+			vtpci_read_dev_config(hw,
+				offsetof(struct virtio_net_config, speed),
+				&config->speed, sizeof(config->speed));
+			hw->speed = config->speed;
+		}
+	}
+
+	PMD_INIT_LOG(DEBUG, "link speed = %u%s",
+		hw->speed, hw->speed == ETH_SPEED_NUM_UNKNOWN ?
+		"(UNKNOWN)" : "");
 	if (vtpci_with_feature(hw, VIRTIO_NET_F_CTRL_VQ)) {
 		config = &local_config;
 
diff --git a/drivers/net/virtio/virtio_ethdev.h b/drivers/net/virtio/virtio_ethdev.h
index cd8947656..febaf17a8 100644
--- a/drivers/net/virtio/virtio_ethdev.h
+++ b/drivers/net/virtio/virtio_ethdev.h
@@ -37,7 +37,8 @@
 	 1ULL << VIRTIO_F_RING_PACKED	  |	\
 	 1ULL << VIRTIO_F_IOMMU_PLATFORM  |	\
 	 1ULL << VIRTIO_F_ORDER_PLATFORM  |	\
-	 1ULL << VIRTIO_F_NOTIFICATION_DATA)
+	 1ULL << VIRTIO_F_NOTIFICATION_DATA | \
+	 1ULL << VIRTIO_NET_F_SPEED_DUPLEX)
 
 #define VIRTIO_PMD_SUPPORTED_GUEST_FEATURES	\
 	(VIRTIO_PMD_DEFAULT_GUEST_FEATURES |	\
diff --git a/drivers/net/virtio/virtio_pci.h b/drivers/net/virtio/virtio_pci.h
index ed98e11c3..2948760ab 100644
--- a/drivers/net/virtio/virtio_pci.h
+++ b/drivers/net/virtio/virtio_pci.h
@@ -141,6 +141,9 @@ struct virtnet_ctl;
  */
 #define VIRTIO_F_NOTIFICATION_DATA 38
 
+/* Device set linkspeed and duplex */
+#define VIRTIO_NET_F_SPEED_DUPLEX 63
+
 /* The Guest publishes the used index for which it expects an interrupt
  * at the end of the avail ring. Host should ignore the avail->flags field. */
 /* The Host publishes the avail index for which it expects a kick
@@ -306,6 +309,18 @@ struct virtio_net_config {
 	uint16_t   status;
 	uint16_t   max_virtqueue_pairs;
 	uint16_t   mtu;
+	/*
+	 * speed, in units of 1Mb. All values 0 to INT_MAX are legal.
+	 * Any other value stands for unknown.
+	 */
+	uint32_t speed;
+	/*
+	 * 0x00 - half duplex
+	 * 0x01 - full duplex
+	 * Any other value stands for unknown.
+	 */
+	uint8_t duplex;
+
 } __attribute__((packed));
 
 /*
-- 
2.17.1


^ permalink raw reply	[flat|nested] 359+ messages in thread

* [dpdk-dev] [PATCH v11 0/6] net/virtio: add link speed devarg
       [not found]   ` <CGME20200416055320eucas1p145da3f096ae1c9e3ee9c5473e95e79e3@eucas1p1.samsung.com>
@ 2020-04-16  5:53     ` Ivan Dyukov
       [not found]       ` <CGME20200416055324eucas1p10b466945b7290cc1e742dd594e95da23@eucas1p1.samsung.com>
                         ` (5 more replies)
  0 siblings, 6 replies; 359+ messages in thread
From: Ivan Dyukov @ 2020-04-16  5:53 UTC (permalink / raw)
  To: dev, maxime.coquelin, i.dyukov, v.kuramshin, amorenoz,
	zhihong.wang, xiaolong.ye, mb

 doc/guides/nics/virtio.rst              |  15 +++++++++++++++
 drivers/net/virtio/virtio_ethdev.c      | 143 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++--------------------
 drivers/net/virtio/virtio_ethdev.h      |   3 ++-
 drivers/net/virtio/virtio_pci.h         |  16 ++++++++++++++++
 drivers/net/virtio/virtio_user_ethdev.c |  18 +++++++++++++-----
 lib/librte_ethdev/rte_ethdev.h          |  27 ++++++++++++++-------------
 6 files changed, 183 insertions(+), 39 deletions(-)

v11 changes:
* [PATCH 6/6] changed sign-off

v10 changes:
* [PATCH 1/6] unknown speed is moved to first patch
* [PATCH 3/6] rebased to latest changes
* [PATCH 4/6] updated commit message
* [PATCH 6/6] rebased to latest changes

v9 chagnes:
* [PATCH 2/5] remove limited set of acceptable speeds [10G, 20G, 40G, 56G, 100G], now all natural numbers are acceptable
* [PATCH 2/5] returns speed_capa as maximum available capability for specified speed
* [PATCH 5/5] remove duplex negotiation
* [PATCH 5/5] set default speed to 0xffffffff

v8 changes:
* fix code style

v7 chagnes:
* rebased to latest master
* added support of VIRTIO_NET_F_SPEED_DUPLEX

v6 changes:
* fix code style

v5 changes:
* fixed code style
* fixed commit message and logging text

v4 changes:
* link_speed renamed to speed devarg
* speed devarg is added to virtio-user driver

v3 changes:
* link_speed devarg is added to virtio documentation


^ permalink raw reply	[flat|nested] 359+ messages in thread

* [dpdk-dev] [PATCH v11 1/6] net/virtio: replace default virtio speed
       [not found]       ` <CGME20200416055324eucas1p10b466945b7290cc1e742dd594e95da23@eucas1p1.samsung.com>
@ 2020-04-16  5:53         ` Ivan Dyukov
  2020-04-16 11:44           ` Maxime Coquelin
  2020-04-16 11:55           ` Morten Brørup
  0 siblings, 2 replies; 359+ messages in thread
From: Ivan Dyukov @ 2020-04-16  5:53 UTC (permalink / raw)
  To: dev, maxime.coquelin, i.dyukov, v.kuramshin, amorenoz,
	zhihong.wang, xiaolong.ye, mb

This patch set speed to unknown

Signed-off-by: Ivan Dyukov <i.dyukov@samsung.com>
---
 drivers/net/virtio/virtio_ethdev.c |  4 ++--
 lib/librte_ethdev/rte_ethdev.h     | 27 ++++++++++++++-------------
 2 files changed, 16 insertions(+), 15 deletions(-)

diff --git a/drivers/net/virtio/virtio_ethdev.c b/drivers/net/virtio/virtio_ethdev.c
index f9d0ea70d..e98a76ea2 100644
--- a/drivers/net/virtio/virtio_ethdev.c
+++ b/drivers/net/virtio/virtio_ethdev.c
@@ -2371,7 +2371,7 @@ virtio_dev_link_update(struct rte_eth_dev *dev, __rte_unused int wait_to_complet
 
 	memset(&link, 0, sizeof(link));
 	link.link_duplex = ETH_LINK_FULL_DUPLEX;
-	link.link_speed  = ETH_SPEED_NUM_10G;
+	link.link_speed  = ETH_SPEED_NUM_UNKNOWN;
 	link.link_autoneg = ETH_LINK_FIXED;
 
 	if (!hw->started) {
@@ -2427,7 +2427,7 @@ virtio_dev_info_get(struct rte_eth_dev *dev, struct rte_eth_dev_info *dev_info)
 	uint64_t tso_mask, host_features;
 	struct virtio_hw *hw = dev->data->dev_private;
 
-	dev_info->speed_capa = ETH_LINK_SPEED_10G; /* fake value */
+	dev_info->speed_capa = ETH_LINK_SPEED_AUTONEG; /* fake value */
 
 	dev_info->max_rx_queues =
 		RTE_MIN(hw->max_queue_pairs, VIRTIO_MAX_RX_QUEUES);
diff --git a/lib/librte_ethdev/rte_ethdev.h b/lib/librte_ethdev/rte_ethdev.h
index d1a593ad1..a15ea572e 100644
--- a/lib/librte_ethdev/rte_ethdev.h
+++ b/lib/librte_ethdev/rte_ethdev.h
@@ -287,19 +287,20 @@ struct rte_eth_stats {
 /**
  * Ethernet numeric link speeds in Mbps
  */
-#define ETH_SPEED_NUM_NONE         0 /**< Not defined */
-#define ETH_SPEED_NUM_10M         10 /**<  10 Mbps */
-#define ETH_SPEED_NUM_100M       100 /**< 100 Mbps */
-#define ETH_SPEED_NUM_1G        1000 /**<   1 Gbps */
-#define ETH_SPEED_NUM_2_5G      2500 /**< 2.5 Gbps */
-#define ETH_SPEED_NUM_5G        5000 /**<   5 Gbps */
-#define ETH_SPEED_NUM_10G      10000 /**<  10 Gbps */
-#define ETH_SPEED_NUM_20G      20000 /**<  20 Gbps */
-#define ETH_SPEED_NUM_25G      25000 /**<  25 Gbps */
-#define ETH_SPEED_NUM_40G      40000 /**<  40 Gbps */
-#define ETH_SPEED_NUM_50G      50000 /**<  50 Gbps */
-#define ETH_SPEED_NUM_56G      56000 /**<  56 Gbps */
-#define ETH_SPEED_NUM_100G    100000 /**< 100 Gbps */
+#define ETH_SPEED_NUM_NONE             0 /**< Not defined */
+#define ETH_SPEED_NUM_10M             10 /**<  10 Mbps */
+#define ETH_SPEED_NUM_100M           100 /**< 100 Mbps */
+#define ETH_SPEED_NUM_1G            1000 /**<   1 Gbps */
+#define ETH_SPEED_NUM_2_5G          2500 /**< 2.5 Gbps */
+#define ETH_SPEED_NUM_5G            5000 /**<   5 Gbps */
+#define ETH_SPEED_NUM_10G          10000 /**<  10 Gbps */
+#define ETH_SPEED_NUM_20G          20000 /**<  20 Gbps */
+#define ETH_SPEED_NUM_25G          25000 /**<  25 Gbps */
+#define ETH_SPEED_NUM_40G          40000 /**<  40 Gbps */
+#define ETH_SPEED_NUM_50G          50000 /**<  50 Gbps */
+#define ETH_SPEED_NUM_56G          56000 /**<  56 Gbps */
+#define ETH_SPEED_NUM_100G        100000 /**< 100 Gbps */
+#define ETH_SPEED_NUM_UNKNOWN 0xffffffff /**< Unknown */
 
 /**
  * A structure used to retrieve link-level information of an Ethernet port.
-- 
2.17.1


^ permalink raw reply	[flat|nested] 359+ messages in thread

* [dpdk-dev] [PATCH v11 2/6] net/virtio: refactor devargs parsing
       [not found]       ` <CGME20200416055326eucas1p266592b624ab220d6b259210b5e413e01@eucas1p2.samsung.com>
@ 2020-04-16  5:53         ` Ivan Dyukov
  0 siblings, 0 replies; 359+ messages in thread
From: Ivan Dyukov @ 2020-04-16  5:53 UTC (permalink / raw)
  To: dev, maxime.coquelin, i.dyukov, v.kuramshin, amorenoz,
	zhihong.wang, xiaolong.ye, mb

refactor vdpa specific devargs parsing to more generic way

Signed-off-by: Ivan Dyukov <i.dyukov@samsung.com>
---
 drivers/net/virtio/virtio_ethdev.c | 34 +++++++++++++++++++++---------
 1 file changed, 24 insertions(+), 10 deletions(-)

diff --git a/drivers/net/virtio/virtio_ethdev.c b/drivers/net/virtio/virtio_ethdev.c
index e98a76ea2..60195ab3c 100644
--- a/drivers/net/virtio/virtio_ethdev.c
+++ b/drivers/net/virtio/virtio_ethdev.c
@@ -1957,16 +1957,18 @@ eth_virtio_dev_uninit(struct rte_eth_dev *eth_dev)
 }
 
 static int vdpa_check_handler(__rte_unused const char *key,
-		const char *value, __rte_unused void *opaque)
+		const char *value, void *ret_val)
 {
-	if (strcmp(value, "1"))
-		return -1;
+	if (strcmp(value, "1") == 0)
+		*(int *)ret_val = 1;
+	else
+		*(int *)ret_val = 0;
 
 	return 0;
 }
 
 static int
-vdpa_mode_selected(struct rte_devargs *devargs)
+virtio_dev_devargs_parse(struct rte_devargs *devargs, int *vdpa)
 {
 	struct rte_kvargs *kvlist;
 	const char *key = "vdpa";
@@ -1982,12 +1984,16 @@ vdpa_mode_selected(struct rte_devargs *devargs)
 	if (!rte_kvargs_count(kvlist, key))
 		goto exit;
 
-	/* vdpa mode selected when there's a key-value pair: vdpa=1 */
-	if (rte_kvargs_process(kvlist, key,
-				vdpa_check_handler, NULL) < 0) {
-		goto exit;
+	if (vdpa) {
+		/* vdpa mode selected when there's a key-value pair:
+		 * vdpa=1
+		 */
+		ret = rte_kvargs_process(kvlist, key,
+				vdpa_check_handler, vdpa);
+		if (ret < 0)
+			goto exit;
 	}
-	ret = 1;
+
 
 exit:
 	rte_kvargs_free(kvlist);
@@ -1997,8 +2003,16 @@ vdpa_mode_selected(struct rte_devargs *devargs)
 static int eth_virtio_pci_probe(struct rte_pci_driver *pci_drv __rte_unused,
 	struct rte_pci_device *pci_dev)
 {
+	int vdpa = 0;
+	int ret = 0;
+
+	ret = virtio_dev_devargs_parse(pci_dev->device.devargs, &vdpa);
+	if (ret < 0) {
+		PMD_INIT_LOG(ERR, "devargs parsing is failed");
+		return ret;
+	}
 	/* virtio pmd skips probe if device needs to work in vdpa mode */
-	if (vdpa_mode_selected(pci_dev->device.devargs))
+	if (vdpa == 1)
 		return 1;
 
 	return rte_eth_dev_pci_generic_probe(pci_dev, sizeof(struct virtio_hw),
-- 
2.17.1


^ permalink raw reply	[flat|nested] 359+ messages in thread

* [dpdk-dev] [PATCH v11 3/6] net/virtio: add link speed devarg
       [not found]       ` <CGME20200416055328eucas1p24f25a424be76659170277b7362c8d700@eucas1p2.samsung.com>
@ 2020-04-16  5:53         ` Ivan Dyukov
  0 siblings, 0 replies; 359+ messages in thread
From: Ivan Dyukov @ 2020-04-16  5:53 UTC (permalink / raw)
  To: dev, maxime.coquelin, i.dyukov, v.kuramshin, amorenoz,
	zhihong.wang, xiaolong.ye, mb

Default value of link speed is 0xffffffff (Unknown)

This patch adds speed devarg which allows to configure
link speed of virtio device.

Signed-off-by: Ivan Dyukov <i.dyukov@samsung.com>
---
 doc/guides/nics/virtio.rst         |   7 ++
 drivers/net/virtio/virtio_ethdev.c | 107 ++++++++++++++++++++++++-----
 drivers/net/virtio/virtio_pci.h    |   1 +
 3 files changed, 99 insertions(+), 16 deletions(-)

diff --git a/doc/guides/nics/virtio.rst b/doc/guides/nics/virtio.rst
index d1f5fb898..55bc6a267 100644
--- a/doc/guides/nics/virtio.rst
+++ b/doc/guides/nics/virtio.rst
@@ -356,6 +356,13 @@ Below devargs are supported by the PCI virtio driver:
     a virtio device needs to work in vDPA mode.
     (Default: 0 (disabled))
 
+#.  ``speed``:
+
+    It is used to specify link speed of virtio device, in units of 1Mb.
+    Link speed is a part of link status structure. It could be requested
+    by application using rte_eth_link_get_nowait function.
+    (Default: 0xffffffff (Unknown))
+
 Below devargs are supported by the virtio-user vdev:
 
 #.  ``path``:
diff --git a/drivers/net/virtio/virtio_ethdev.c b/drivers/net/virtio/virtio_ethdev.c
index 60195ab3c..306241d37 100644
--- a/drivers/net/virtio/virtio_ethdev.c
+++ b/drivers/net/virtio/virtio_ethdev.c
@@ -45,6 +45,10 @@ static int virtio_dev_promiscuous_enable(struct rte_eth_dev *dev);
 static int virtio_dev_promiscuous_disable(struct rte_eth_dev *dev);
 static int virtio_dev_allmulticast_enable(struct rte_eth_dev *dev);
 static int virtio_dev_allmulticast_disable(struct rte_eth_dev *dev);
+static uint32_t virtio_dev_speed_capa_get(uint32_t speed);
+static int virtio_dev_devargs_parse(struct rte_devargs *devargs,
+	int *vdpa,
+	uint32_t *speed);
 static int virtio_dev_info_get(struct rte_eth_dev *dev,
 				struct rte_eth_dev_info *dev_info);
 static int virtio_dev_link_update(struct rte_eth_dev *dev,
@@ -1861,6 +1865,7 @@ int
 eth_virtio_dev_init(struct rte_eth_dev *eth_dev)
 {
 	struct virtio_hw *hw = eth_dev->data->dev_private;
+	uint32_t speed = ETH_SPEED_NUM_UNKNOWN;
 	int ret;
 
 	if (sizeof(struct virtio_net_hdr_mrg_rxbuf) > RTE_PKTMBUF_HEADROOM) {
@@ -1886,7 +1891,11 @@ eth_virtio_dev_init(struct rte_eth_dev *eth_dev)
 
 		return 0;
 	}
-
+	ret = virtio_dev_devargs_parse(eth_dev->device->devargs,
+		 NULL, &speed);
+	if (ret < 0)
+		return ret;
+	hw->speed = speed;
 	/*
 	 * Pass the information to the rte_eth_dev_close() that it should also
 	 * release the private port resources.
@@ -1967,33 +1976,100 @@ static int vdpa_check_handler(__rte_unused const char *key,
 	return 0;
 }
 
+
+static uint32_t
+virtio_dev_speed_capa_get(uint32_t speed)
+{
+	struct speed_caps {
+		uint32_t min_speed;
+		uint32_t speed_capa;
+	};
+	struct speed_caps caps[] = {
+		{ETH_SPEED_NUM_10M,    ETH_LINK_SPEED_10M},
+		{ETH_SPEED_NUM_100M,   ETH_LINK_SPEED_100M},
+		{ETH_SPEED_NUM_1G,     ETH_LINK_SPEED_1G},
+		{ETH_SPEED_NUM_2_5G,   ETH_LINK_SPEED_2_5G},
+		{ETH_SPEED_NUM_5G,     ETH_LINK_SPEED_5G},
+		{ETH_SPEED_NUM_10G,    ETH_LINK_SPEED_10G},
+		{ETH_SPEED_NUM_20G,    ETH_LINK_SPEED_20G},
+		{ETH_SPEED_NUM_25G,    ETH_LINK_SPEED_25G},
+		{ETH_SPEED_NUM_40G,    ETH_LINK_SPEED_40G},
+		{ETH_SPEED_NUM_50G,    ETH_LINK_SPEED_50G},
+		{ETH_SPEED_NUM_56G,    ETH_LINK_SPEED_56G},
+		{ETH_SPEED_NUM_100G,   ETH_LINK_SPEED_100G}
+	};
+	const uint32_t caps_size = sizeof(caps) / sizeof(struct speed_caps);
+	uint32_t speed_capa = ETH_LINK_SPEED_AUTONEG;
+	if (speed != ETH_SPEED_NUM_UNKNOWN) {
+		/* find maximum suitable speed capability */
+		for (uint32_t i = 0; i < caps_size; i++) {
+			if (speed >= caps[i].min_speed)
+				speed_capa = caps[i].speed_capa;
+		}
+	}
+	return speed_capa;
+}
+
+
+#define VIRTIO_ARG_SPEED      "speed"
+#define VIRTIO_ARG_VDPA       "vdpa"
+
+
 static int
-virtio_dev_devargs_parse(struct rte_devargs *devargs, int *vdpa)
+link_speed_handler(const char *key __rte_unused,
+		const char *value, void *ret_val)
+{
+	uint32_t val;
+	if (!value || !ret_val)
+		return -EINVAL;
+	errno = 0;
+	val = strtoul(value, NULL, 0);
+	/* validate input */
+	if (errno != 0)
+		return -EINVAL;
+	*(uint32_t *)ret_val = val;
+
+	return 0;
+}
+
+
+static int
+virtio_dev_devargs_parse(struct rte_devargs *devargs, int *vdpa,
+	uint32_t *speed)
 {
 	struct rte_kvargs *kvlist;
-	const char *key = "vdpa";
 	int ret = 0;
 
 	if (devargs == NULL)
 		return 0;
 
 	kvlist = rte_kvargs_parse(devargs->args, NULL);
-	if (kvlist == NULL)
+	if (kvlist == NULL) {
+		PMD_INIT_LOG(ERR, "error when parsing param");
 		return 0;
-
-	if (!rte_kvargs_count(kvlist, key))
-		goto exit;
-
-	if (vdpa) {
+	}
+	if (vdpa && rte_kvargs_count(kvlist, VIRTIO_ARG_VDPA) == 1) {
 		/* vdpa mode selected when there's a key-value pair:
 		 * vdpa=1
 		 */
-		ret = rte_kvargs_process(kvlist, key,
+		ret = rte_kvargs_process(kvlist, VIRTIO_ARG_VDPA,
 				vdpa_check_handler, vdpa);
-		if (ret < 0)
+		if (ret < 0) {
+			PMD_INIT_LOG(ERR, "Failed to parse %s",
+				VIRTIO_ARG_VDPA);
 			goto exit;
+		}
+	}
+	if (speed && rte_kvargs_count(kvlist, VIRTIO_ARG_SPEED) == 1) {
+		ret = rte_kvargs_process(kvlist,
+					VIRTIO_ARG_SPEED,
+					link_speed_handler, speed);
+		if (ret < 0) {
+			PMD_INIT_LOG(ERR, "Failed to parse %s",
+					VIRTIO_ARG_SPEED);
+			goto exit;
+		}
 	}
-
 
 exit:
 	rte_kvargs_free(kvlist);
@@ -2006,7 +2082,7 @@ static int eth_virtio_pci_probe(struct rte_pci_driver *pci_drv __rte_unused,
 	int vdpa = 0;
 	int ret = 0;
 
-	ret = virtio_dev_devargs_parse(pci_dev->device.devargs, &vdpa);
+	ret = virtio_dev_devargs_parse(pci_dev->device.devargs, &vdpa, NULL);
 	if (ret < 0) {
 		PMD_INIT_LOG(ERR, "devargs parsing is failed");
 		return ret;
@@ -2385,7 +2461,7 @@ virtio_dev_link_update(struct rte_eth_dev *dev, __rte_unused int wait_to_complet
 
 	memset(&link, 0, sizeof(link));
 	link.link_duplex = ETH_LINK_FULL_DUPLEX;
-	link.link_speed  = ETH_SPEED_NUM_UNKNOWN;
+	link.link_speed  = hw->speed;
 	link.link_autoneg = ETH_LINK_FIXED;
 
 	if (!hw->started) {
@@ -2440,8 +2516,7 @@ virtio_dev_info_get(struct rte_eth_dev *dev, struct rte_eth_dev_info *dev_info)
 {
 	uint64_t tso_mask, host_features;
 	struct virtio_hw *hw = dev->data->dev_private;
-
-	dev_info->speed_capa = ETH_LINK_SPEED_AUTONEG; /* fake value */
+	dev_info->speed_capa = virtio_dev_speed_capa_get(hw->speed);
 
 	dev_info->max_rx_queues =
 		RTE_MIN(hw->max_queue_pairs, VIRTIO_MAX_RX_QUEUES);
diff --git a/drivers/net/virtio/virtio_pci.h b/drivers/net/virtio/virtio_pci.h
index 7433d2f08..ed98e11c3 100644
--- a/drivers/net/virtio/virtio_pci.h
+++ b/drivers/net/virtio/virtio_pci.h
@@ -259,6 +259,7 @@ struct virtio_hw {
 	uint16_t    port_id;
 	uint8_t     mac_addr[RTE_ETHER_ADDR_LEN];
 	uint32_t    notify_off_multiplier;
+	uint32_t    speed;  /* link speed in MB */
 	uint8_t     *isr;
 	uint16_t    *notify_base;
 	struct virtio_pci_common_cfg *common_cfg;
-- 
2.17.1


^ permalink raw reply	[flat|nested] 359+ messages in thread

* [dpdk-dev] [PATCH v11 4/6] net/virtio-user: fix devargs parsing
       [not found]       ` <CGME20200416055330eucas1p120bee1af98e108e09dd7515faf094c73@eucas1p1.samsung.com>
@ 2020-04-16  5:53         ` Ivan Dyukov
  0 siblings, 0 replies; 359+ messages in thread
From: Ivan Dyukov @ 2020-04-16  5:53 UTC (permalink / raw)
  To: dev, maxime.coquelin, i.dyukov, v.kuramshin, amorenoz,
	zhihong.wang, xiaolong.ye, mb
  Cc: stable

strtoull returns 0 if it fails to parse input string. It's ignored
in get_integer_arg.

This patch handles error cases for strtoull function.

Fixes: ce2eabdd43ec ("net/virtio-user: add virtual device")
Cc: stable@dpdk.org
Signed-off-by: Ivan Dyukov <i.dyukov@samsung.com>
---
 drivers/net/virtio/virtio_user_ethdev.c | 13 +++++++++----
 1 file changed, 9 insertions(+), 4 deletions(-)

diff --git a/drivers/net/virtio/virtio_user_ethdev.c b/drivers/net/virtio/virtio_user_ethdev.c
index e61af4068..a79f68a36 100644
--- a/drivers/net/virtio/virtio_user_ethdev.c
+++ b/drivers/net/virtio/virtio_user_ethdev.c
@@ -477,12 +477,17 @@ static int
 get_integer_arg(const char *key __rte_unused,
 		const char *value, void *extra_args)
 {
+	uint64_t integer = 0;
 	if (!value || !extra_args)
 		return -EINVAL;
-
-	*(uint64_t *)extra_args = strtoull(value, NULL, 0);
-
-	return 0;
+	errno = 0;
+	integer = strtoull(value, NULL, 0);
+	/* extra_args keeps default value, it should be replaced
+	 * only in case of successful parsing of the 'value' arg
+	 */
+	if (errno == 0)
+		*(uint64_t *)extra_args = integer;
+	return -errno;
 }
 
 static struct rte_eth_dev *
-- 
2.17.1


^ permalink raw reply	[flat|nested] 359+ messages in thread

* [dpdk-dev] [PATCH v11 5/6] net/virtio-user: adding link speed devarg
       [not found]       ` <CGME20200416055331eucas1p1870fa45cd2d6876cff472763986dfd4e@eucas1p1.samsung.com>
@ 2020-04-16  5:53         ` Ivan Dyukov
  0 siblings, 0 replies; 359+ messages in thread
From: Ivan Dyukov @ 2020-04-16  5:53 UTC (permalink / raw)
  To: dev, maxime.coquelin, i.dyukov, v.kuramshin, amorenoz,
	zhihong.wang, xiaolong.ye, mb

virtio driver already parses speed devarg. virtio-user should add
it to list of valid devargs and call eth_virtio_dev_init function
which init speed value.

eth_virtio_dev_init already is called from virtio_user_pmd_probe
function. The only change is required to enable speed devargs:
adding speed to list of valid devargs.

Signed-off-by: Ivan Dyukov <i.dyukov@samsung.com>
---
 doc/guides/nics/virtio.rst              | 8 ++++++++
 drivers/net/virtio/virtio_user_ethdev.c | 5 ++++-
 2 files changed, 12 insertions(+), 1 deletion(-)

diff --git a/doc/guides/nics/virtio.rst b/doc/guides/nics/virtio.rst
index 55bc6a267..451789705 100644
--- a/doc/guides/nics/virtio.rst
+++ b/doc/guides/nics/virtio.rst
@@ -410,6 +410,14 @@ Below devargs are supported by the virtio-user vdev:
     It is used to enable virtio device packed virtqueue feature.
     (Default: 0 (disabled))
 
+#.  ``speed``:
+
+    It is used to specify link speed of virtio device, in units of 1Mb.
+    Link speed is a part of link status structure. It could be requested
+    by application using rte_eth_link_get_nowait function.
+    (Default: 0xffffffff (Unknown))
+
+
 Virtio paths Selection and Usage
 --------------------------------
 
diff --git a/drivers/net/virtio/virtio_user_ethdev.c b/drivers/net/virtio/virtio_user_ethdev.c
index a79f68a36..5b32d30fa 100644
--- a/drivers/net/virtio/virtio_user_ethdev.c
+++ b/drivers/net/virtio/virtio_user_ethdev.c
@@ -450,6 +450,8 @@ static const char *valid_args[] = {
 	VIRTIO_USER_ARG_IN_ORDER,
 #define VIRTIO_USER_ARG_PACKED_VQ      "packed_vq"
 	VIRTIO_USER_ARG_PACKED_VQ,
+#define VIRTIO_USER_ARG_SPEED          "speed"
+	VIRTIO_USER_ARG_SPEED,
 	NULL
 };
 
@@ -782,4 +784,5 @@ RTE_PMD_REGISTER_PARAM_STRING(net_virtio_user,
 	"server=<0|1> "
 	"mrg_rxbuf=<0|1> "
 	"in_order=<0|1> "
-	"packed_vq=<0|1>");
+	"packed_vq=<0|1> "
+	"speed=<int>");
-- 
2.17.1


^ permalink raw reply	[flat|nested] 359+ messages in thread

* [dpdk-dev] [PATCH v11 6/6] net/virtio: Support of VIRTIO_NET_F_SPEED_DUPLEX
       [not found]       ` <CGME20200416055333eucas1p15fe1459edef84852c7131443b54fdeed@eucas1p1.samsung.com>
@ 2020-04-16  5:53         ` Ivan Dyukov
  0 siblings, 0 replies; 359+ messages in thread
From: Ivan Dyukov @ 2020-04-16  5:53 UTC (permalink / raw)
  To: dev, maxime.coquelin, i.dyukov, v.kuramshin, amorenoz,
	zhihong.wang, xiaolong.ye, mb

This patch adds a support of VIRTIO_NET_F_SPEED_DUPLEX feature
for virtio driver.

There are two ways to specify speed of the link:
  * 'speed' devarg
  * negotiate speed from qemu via VIRTIO_NET_F_SPEED_DUPLEX
The highest priority is devarg. If devarg is not specified,
driver tries to negotiate it from qemu.

Signed-off-by: Ivan Dyukov <i.dyukov@samsung.com>
---
 drivers/net/virtio/virtio_ethdev.c | 14 ++++++++++++++
 drivers/net/virtio/virtio_ethdev.h |  3 ++-
 drivers/net/virtio/virtio_pci.h    | 15 +++++++++++++++
 3 files changed, 31 insertions(+), 1 deletion(-)

diff --git a/drivers/net/virtio/virtio_ethdev.c b/drivers/net/virtio/virtio_ethdev.c
index 306241d37..b08270714 100644
--- a/drivers/net/virtio/virtio_ethdev.c
+++ b/drivers/net/virtio/virtio_ethdev.c
@@ -1718,6 +1718,20 @@ virtio_init_device(struct rte_eth_dev *eth_dev, uint64_t req_features)
 		     hw->mac_addr[0], hw->mac_addr[1], hw->mac_addr[2],
 		     hw->mac_addr[3], hw->mac_addr[4], hw->mac_addr[5]);
 
+	if (vtpci_with_feature(hw, VIRTIO_NET_F_SPEED_DUPLEX)) {
+		config = &local_config;
+		/* if speed is not specified in devargs */
+		if (hw->speed == ETH_SPEED_NUM_UNKNOWN) {
+			vtpci_read_dev_config(hw,
+				offsetof(struct virtio_net_config, speed),
+				&config->speed, sizeof(config->speed));
+			hw->speed = config->speed;
+		}
+	}
+
+	PMD_INIT_LOG(DEBUG, "link speed = %u%s",
+		hw->speed, hw->speed == ETH_SPEED_NUM_UNKNOWN ?
+		"(UNKNOWN)" : "");
 	if (vtpci_with_feature(hw, VIRTIO_NET_F_CTRL_VQ)) {
 		config = &local_config;
 
diff --git a/drivers/net/virtio/virtio_ethdev.h b/drivers/net/virtio/virtio_ethdev.h
index cd8947656..febaf17a8 100644
--- a/drivers/net/virtio/virtio_ethdev.h
+++ b/drivers/net/virtio/virtio_ethdev.h
@@ -37,7 +37,8 @@
 	 1ULL << VIRTIO_F_RING_PACKED	  |	\
 	 1ULL << VIRTIO_F_IOMMU_PLATFORM  |	\
 	 1ULL << VIRTIO_F_ORDER_PLATFORM  |	\
-	 1ULL << VIRTIO_F_NOTIFICATION_DATA)
+	 1ULL << VIRTIO_F_NOTIFICATION_DATA | \
+	 1ULL << VIRTIO_NET_F_SPEED_DUPLEX)
 
 #define VIRTIO_PMD_SUPPORTED_GUEST_FEATURES	\
 	(VIRTIO_PMD_DEFAULT_GUEST_FEATURES |	\
diff --git a/drivers/net/virtio/virtio_pci.h b/drivers/net/virtio/virtio_pci.h
index ed98e11c3..2948760ab 100644
--- a/drivers/net/virtio/virtio_pci.h
+++ b/drivers/net/virtio/virtio_pci.h
@@ -141,6 +141,9 @@ struct virtnet_ctl;
  */
 #define VIRTIO_F_NOTIFICATION_DATA 38
 
+/* Device set linkspeed and duplex */
+#define VIRTIO_NET_F_SPEED_DUPLEX 63
+
 /* The Guest publishes the used index for which it expects an interrupt
  * at the end of the avail ring. Host should ignore the avail->flags field. */
 /* The Host publishes the avail index for which it expects a kick
@@ -306,6 +309,18 @@ struct virtio_net_config {
 	uint16_t   status;
 	uint16_t   max_virtqueue_pairs;
 	uint16_t   mtu;
+	/*
+	 * speed, in units of 1Mb. All values 0 to INT_MAX are legal.
+	 * Any other value stands for unknown.
+	 */
+	uint32_t speed;
+	/*
+	 * 0x00 - half duplex
+	 * 0x01 - full duplex
+	 * Any other value stands for unknown.
+	 */
+	uint8_t duplex;
+
 } __attribute__((packed));
 
 /*
-- 
2.17.1


^ permalink raw reply	[flat|nested] 359+ messages in thread

* Re: [dpdk-dev] [PATCH v11 1/6] net/virtio: replace default virtio speed
  2020-04-16  5:53         ` [dpdk-dev] [PATCH v11 1/6] net/virtio: replace default virtio speed Ivan Dyukov
@ 2020-04-16 11:44           ` Maxime Coquelin
  2020-04-16 11:55           ` Morten Brørup
  1 sibling, 0 replies; 359+ messages in thread
From: Maxime Coquelin @ 2020-04-16 11:44 UTC (permalink / raw)
  To: Ivan Dyukov, dev, v.kuramshin, amorenoz, zhihong.wang, xiaolong.ye, mb



On 4/16/20 7:53 AM, Ivan Dyukov wrote:
> This patch set speed to unknown
> 
> Signed-off-by: Ivan Dyukov <i.dyukov@samsung.com>
> ---
>  drivers/net/virtio/virtio_ethdev.c |  4 ++--
>  lib/librte_ethdev/rte_ethdev.h     | 27 ++++++++++++++-------------
>  2 files changed, 16 insertions(+), 15 deletions(-)
> 
> diff --git a/drivers/net/virtio/virtio_ethdev.c b/drivers/net/virtio/virtio_ethdev.c
> index f9d0ea70d..e98a76ea2 100644
> --- a/drivers/net/virtio/virtio_ethdev.c
> +++ b/drivers/net/virtio/virtio_ethdev.c
> @@ -2371,7 +2371,7 @@ virtio_dev_link_update(struct rte_eth_dev *dev, __rte_unused int wait_to_complet
>  
>  	memset(&link, 0, sizeof(link));
>  	link.link_duplex = ETH_LINK_FULL_DUPLEX;
> -	link.link_speed  = ETH_SPEED_NUM_10G;
> +	link.link_speed  = ETH_SPEED_NUM_UNKNOWN;
>  	link.link_autoneg = ETH_LINK_FIXED;
>  
>  	if (!hw->started) {
> @@ -2427,7 +2427,7 @@ virtio_dev_info_get(struct rte_eth_dev *dev, struct rte_eth_dev_info *dev_info)
>  	uint64_t tso_mask, host_features;
>  	struct virtio_hw *hw = dev->data->dev_private;
>  
> -	dev_info->speed_capa = ETH_LINK_SPEED_10G; /* fake value */
> +	dev_info->speed_capa = ETH_LINK_SPEED_AUTONEG; /* fake value */
>  
>  	dev_info->max_rx_queues =
>  		RTE_MIN(hw->max_queue_pairs, VIRTIO_MAX_RX_QUEUES);
> diff --git a/lib/librte_ethdev/rte_ethdev.h b/lib/librte_ethdev/rte_ethdev.h
> index d1a593ad1..a15ea572e 100644
> --- a/lib/librte_ethdev/rte_ethdev.h
> +++ b/lib/librte_ethdev/rte_ethdev.h
> @@ -287,19 +287,20 @@ struct rte_eth_stats {
>  /**
>   * Ethernet numeric link speeds in Mbps
>   */
> -#define ETH_SPEED_NUM_NONE         0 /**< Not defined */
> -#define ETH_SPEED_NUM_10M         10 /**<  10 Mbps */
> -#define ETH_SPEED_NUM_100M       100 /**< 100 Mbps */
> -#define ETH_SPEED_NUM_1G        1000 /**<   1 Gbps */
> -#define ETH_SPEED_NUM_2_5G      2500 /**< 2.5 Gbps */
> -#define ETH_SPEED_NUM_5G        5000 /**<   5 Gbps */
> -#define ETH_SPEED_NUM_10G      10000 /**<  10 Gbps */
> -#define ETH_SPEED_NUM_20G      20000 /**<  20 Gbps */
> -#define ETH_SPEED_NUM_25G      25000 /**<  25 Gbps */
> -#define ETH_SPEED_NUM_40G      40000 /**<  40 Gbps */
> -#define ETH_SPEED_NUM_50G      50000 /**<  50 Gbps */
> -#define ETH_SPEED_NUM_56G      56000 /**<  56 Gbps */
> -#define ETH_SPEED_NUM_100G    100000 /**< 100 Gbps */
> +#define ETH_SPEED_NUM_NONE             0 /**< Not defined */
> +#define ETH_SPEED_NUM_10M             10 /**<  10 Mbps */
> +#define ETH_SPEED_NUM_100M           100 /**< 100 Mbps */
> +#define ETH_SPEED_NUM_1G            1000 /**<   1 Gbps */
> +#define ETH_SPEED_NUM_2_5G          2500 /**< 2.5 Gbps */
> +#define ETH_SPEED_NUM_5G            5000 /**<   5 Gbps */
> +#define ETH_SPEED_NUM_10G          10000 /**<  10 Gbps */
> +#define ETH_SPEED_NUM_20G          20000 /**<  20 Gbps */
> +#define ETH_SPEED_NUM_25G          25000 /**<  25 Gbps */
> +#define ETH_SPEED_NUM_40G          40000 /**<  40 Gbps */
> +#define ETH_SPEED_NUM_50G          50000 /**<  50 Gbps */
> +#define ETH_SPEED_NUM_56G          56000 /**<  56 Gbps */
> +#define ETH_SPEED_NUM_100G        100000 /**< 100 Gbps */
> +#define ETH_SPEED_NUM_UNKNOWN 0xffffffff /**< Unknown */
>  
>  /**
>   * A structure used to retrieve link-level information of an Ethernet port.
> 

I actually meant to have the rte_ethdev.h change in a dedicated patch,
as it is in a different subsystem. Someone could want to backport only
the lib change without touching the Virtio driver.

If OK for you, I can do that while applying.

Thanks,
Maxime


^ permalink raw reply	[flat|nested] 359+ messages in thread

* Re: [dpdk-dev] [PATCH v11 1/6] net/virtio: replace default virtio speed
  2020-04-16  5:53         ` [dpdk-dev] [PATCH v11 1/6] net/virtio: replace default virtio speed Ivan Dyukov
  2020-04-16 11:44           ` Maxime Coquelin
@ 2020-04-16 11:55           ` Morten Brørup
  2020-04-16 11:58             ` Maxime Coquelin
  1 sibling, 1 reply; 359+ messages in thread
From: Morten Brørup @ 2020-04-16 11:55 UTC (permalink / raw)
  To: Ivan Dyukov, dev, maxime.coquelin, v.kuramshin, amorenoz,
	zhihong.wang, xiaolong.ye

> From: Ivan Dyukov [mailto:i.dyukov@samsung.com]
> Sent: Thursday, April 16, 2020 7:53 AM
> 
> This patch set speed to unknown
> 
> Signed-off-by: Ivan Dyukov <i.dyukov@samsung.com>
> ---
>  drivers/net/virtio/virtio_ethdev.c |  4 ++--
>  lib/librte_ethdev/rte_ethdev.h     | 27 ++++++++++++++-------------
>  2 files changed, 16 insertions(+), 15 deletions(-)
> 
> diff --git a/drivers/net/virtio/virtio_ethdev.c
> b/drivers/net/virtio/virtio_ethdev.c
> index f9d0ea70d..e98a76ea2 100644
> --- a/drivers/net/virtio/virtio_ethdev.c
> +++ b/drivers/net/virtio/virtio_ethdev.c
> @@ -2371,7 +2371,7 @@ virtio_dev_link_update(struct rte_eth_dev *dev,
> __rte_unused int wait_to_complet
> 
>  	memset(&link, 0, sizeof(link));
>  	link.link_duplex = ETH_LINK_FULL_DUPLEX;
> -	link.link_speed  = ETH_SPEED_NUM_10G;
> +	link.link_speed  = ETH_SPEED_NUM_UNKNOWN;
>  	link.link_autoneg = ETH_LINK_FIXED;
> 
>  	if (!hw->started) {
> @@ -2427,7 +2427,7 @@ virtio_dev_info_get(struct rte_eth_dev *dev,
> struct rte_eth_dev_info *dev_info)
>  	uint64_t tso_mask, host_features;
>  	struct virtio_hw *hw = dev->data->dev_private;
> 
> -	dev_info->speed_capa = ETH_LINK_SPEED_10G; /* fake value */
> +	dev_info->speed_capa = ETH_LINK_SPEED_AUTONEG; /* fake value */

If you indicate that the NIC supports Auto Negotiation here,
then I suggest that you also change the link status as follows:
- link.link_autoneg = ETH_LINK_FIXED;
+ link.link_autoneg = ETH_LINK_AUTONEG;

I considered the opposite change, but if we define that the underlying environment determines the actual speed, then Auto Negotiation seems more correct than Fixed speed.

Med venlig hilsen / kind regards
- Morten Brørup




^ permalink raw reply	[flat|nested] 359+ messages in thread

* Re: [dpdk-dev] [PATCH v11 1/6] net/virtio: replace default virtio speed
  2020-04-16 11:55           ` Morten Brørup
@ 2020-04-16 11:58             ` Maxime Coquelin
  2020-04-16 12:20               ` Ivan Dyukov
  0 siblings, 1 reply; 359+ messages in thread
From: Maxime Coquelin @ 2020-04-16 11:58 UTC (permalink / raw)
  To: Morten Brørup, Ivan Dyukov, dev, v.kuramshin, amorenoz,
	zhihong.wang, xiaolong.ye



On 4/16/20 1:55 PM, Morten Brørup wrote:
>> From: Ivan Dyukov [mailto:i.dyukov@samsung.com]
>> Sent: Thursday, April 16, 2020 7:53 AM
>>
>> This patch set speed to unknown
>>
>> Signed-off-by: Ivan Dyukov <i.dyukov@samsung.com>
>> ---
>>  drivers/net/virtio/virtio_ethdev.c |  4 ++--
>>  lib/librte_ethdev/rte_ethdev.h     | 27 ++++++++++++++-------------
>>  2 files changed, 16 insertions(+), 15 deletions(-)
>>
>> diff --git a/drivers/net/virtio/virtio_ethdev.c
>> b/drivers/net/virtio/virtio_ethdev.c
>> index f9d0ea70d..e98a76ea2 100644
>> --- a/drivers/net/virtio/virtio_ethdev.c
>> +++ b/drivers/net/virtio/virtio_ethdev.c
>> @@ -2371,7 +2371,7 @@ virtio_dev_link_update(struct rte_eth_dev *dev,
>> __rte_unused int wait_to_complet
>>
>>  	memset(&link, 0, sizeof(link));
>>  	link.link_duplex = ETH_LINK_FULL_DUPLEX;
>> -	link.link_speed  = ETH_SPEED_NUM_10G;
>> +	link.link_speed  = ETH_SPEED_NUM_UNKNOWN;
>>  	link.link_autoneg = ETH_LINK_FIXED;
>>
>>  	if (!hw->started) {
>> @@ -2427,7 +2427,7 @@ virtio_dev_info_get(struct rte_eth_dev *dev,
>> struct rte_eth_dev_info *dev_info)
>>  	uint64_t tso_mask, host_features;
>>  	struct virtio_hw *hw = dev->data->dev_private;
>>
>> -	dev_info->speed_capa = ETH_LINK_SPEED_10G; /* fake value */
>> +	dev_info->speed_capa = ETH_LINK_SPEED_AUTONEG; /* fake value */
> 
> If you indicate that the NIC supports Auto Negotiation here,
> then I suggest that you also change the link status as follows:
> - link.link_autoneg = ETH_LINK_FIXED;
> + link.link_autoneg = ETH_LINK_AUTONEG;
> 
> I considered the opposite change, but if we define that the underlying environment determines the actual speed, then Auto Negotiation seems more correct than Fixed speed.

That's a valid point.
Thank you Morten for spotting this!

Ivan, I can do the change while applying if you are fine with it.

Thanks,
Maxime

> Med venlig hilsen / kind regards
> - Morten Brørup
> 
> 
> 


^ permalink raw reply	[flat|nested] 359+ messages in thread

* Re: [dpdk-dev] [PATCH v11 1/6] net/virtio: replace default virtio speed
  2020-04-16 11:58             ` Maxime Coquelin
@ 2020-04-16 12:20               ` Ivan Dyukov
  0 siblings, 0 replies; 359+ messages in thread
From: Ivan Dyukov @ 2020-04-16 12:20 UTC (permalink / raw)
  To: Maxime Coquelin, Morten Brørup, dev, v.kuramshin, amorenoz,
	zhihong.wang, xiaolong.ye

Hi Maxime, Morten,

Thank you for comments. I'll prepare one more revision of the change.

Best regards,
Ivan
16.04.2020 14:58, Maxime Coquelin пишет:
>
> On 4/16/20 1:55 PM, Morten Brørup wrote:
>>> From: Ivan Dyukov [mailto:i.dyukov@samsung.com]
>>> Sent: Thursday, April 16, 2020 7:53 AM
>>>
>>> This patch set speed to unknown
>>>
>>> Signed-off-by: Ivan Dyukov <i.dyukov@samsung.com>
>>> ---
>>>   drivers/net/virtio/virtio_ethdev.c |  4 ++--
>>>   lib/librte_ethdev/rte_ethdev.h     | 27 ++++++++++++++-------------
>>>   2 files changed, 16 insertions(+), 15 deletions(-)
>>>
>>> diff --git a/drivers/net/virtio/virtio_ethdev.c
>>> b/drivers/net/virtio/virtio_ethdev.c
>>> index f9d0ea70d..e98a76ea2 100644
>>> --- a/drivers/net/virtio/virtio_ethdev.c
>>> +++ b/drivers/net/virtio/virtio_ethdev.c
>>> @@ -2371,7 +2371,7 @@ virtio_dev_link_update(struct rte_eth_dev *dev,
>>> __rte_unused int wait_to_complet
>>>
>>>   	memset(&link, 0, sizeof(link));
>>>   	link.link_duplex = ETH_LINK_FULL_DUPLEX;
>>> -	link.link_speed  = ETH_SPEED_NUM_10G;
>>> +	link.link_speed  = ETH_SPEED_NUM_UNKNOWN;
>>>   	link.link_autoneg = ETH_LINK_FIXED;
>>>
>>>   	if (!hw->started) {
>>> @@ -2427,7 +2427,7 @@ virtio_dev_info_get(struct rte_eth_dev *dev,
>>> struct rte_eth_dev_info *dev_info)
>>>   	uint64_t tso_mask, host_features;
>>>   	struct virtio_hw *hw = dev->data->dev_private;
>>>
>>> -	dev_info->speed_capa = ETH_LINK_SPEED_10G; /* fake value */
>>> +	dev_info->speed_capa = ETH_LINK_SPEED_AUTONEG; /* fake value */
>> If you indicate that the NIC supports Auto Negotiation here,
>> then I suggest that you also change the link status as follows:
>> - link.link_autoneg = ETH_LINK_FIXED;
>> + link.link_autoneg = ETH_LINK_AUTONEG;
>>
>> I considered the opposite change, but if we define that the underlying environment determines the actual speed, then Auto Negotiation seems more correct than Fixed speed.
> That's a valid point.
> Thank you Morten for spotting this!
>
> Ivan, I can do the change while applying if you are fine with it.
>
> Thanks,
> Maxime
>
>> Med venlig hilsen / kind regards
>> - Morten Brørup
>>
>>
>>
>


^ permalink raw reply	[flat|nested] 359+ messages in thread

* [dpdk-dev] [PATCH v12 1/7] ethdev: added UNKNOWN speed value
       [not found]     ` <CGME20200416124311eucas1p160468089b68c1d23578d4c3e6b3d0d75@eucas1p1.samsung.com>
@ 2020-04-16 12:42       ` Ivan Dyukov
  2020-04-16 22:14         ` Thomas Monjalon
  0 siblings, 1 reply; 359+ messages in thread
From: Ivan Dyukov @ 2020-04-16 12:42 UTC (permalink / raw)
  To: dev, maxime.coquelin, i.dyukov, v.kuramshin, amorenoz,
	zhihong.wang, xiaolong.ye, mb

UNKNOWN speed equals to 0xffffffff

Signed-off-by: Ivan Dyukov <i.dyukov@samsung.com>
---
 lib/librte_ethdev/rte_ethdev.h | 27 ++++++++++++++-------------
 1 file changed, 14 insertions(+), 13 deletions(-)

diff --git a/lib/librte_ethdev/rte_ethdev.h b/lib/librte_ethdev/rte_ethdev.h
index d1a593ad1..a15ea572e 100644
--- a/lib/librte_ethdev/rte_ethdev.h
+++ b/lib/librte_ethdev/rte_ethdev.h
@@ -287,19 +287,20 @@ struct rte_eth_stats {
 /**
  * Ethernet numeric link speeds in Mbps
  */
-#define ETH_SPEED_NUM_NONE         0 /**< Not defined */
-#define ETH_SPEED_NUM_10M         10 /**<  10 Mbps */
-#define ETH_SPEED_NUM_100M       100 /**< 100 Mbps */
-#define ETH_SPEED_NUM_1G        1000 /**<   1 Gbps */
-#define ETH_SPEED_NUM_2_5G      2500 /**< 2.5 Gbps */
-#define ETH_SPEED_NUM_5G        5000 /**<   5 Gbps */
-#define ETH_SPEED_NUM_10G      10000 /**<  10 Gbps */
-#define ETH_SPEED_NUM_20G      20000 /**<  20 Gbps */
-#define ETH_SPEED_NUM_25G      25000 /**<  25 Gbps */
-#define ETH_SPEED_NUM_40G      40000 /**<  40 Gbps */
-#define ETH_SPEED_NUM_50G      50000 /**<  50 Gbps */
-#define ETH_SPEED_NUM_56G      56000 /**<  56 Gbps */
-#define ETH_SPEED_NUM_100G    100000 /**< 100 Gbps */
+#define ETH_SPEED_NUM_NONE             0 /**< Not defined */
+#define ETH_SPEED_NUM_10M             10 /**<  10 Mbps */
+#define ETH_SPEED_NUM_100M           100 /**< 100 Mbps */
+#define ETH_SPEED_NUM_1G            1000 /**<   1 Gbps */
+#define ETH_SPEED_NUM_2_5G          2500 /**< 2.5 Gbps */
+#define ETH_SPEED_NUM_5G            5000 /**<   5 Gbps */
+#define ETH_SPEED_NUM_10G          10000 /**<  10 Gbps */
+#define ETH_SPEED_NUM_20G          20000 /**<  20 Gbps */
+#define ETH_SPEED_NUM_25G          25000 /**<  25 Gbps */
+#define ETH_SPEED_NUM_40G          40000 /**<  40 Gbps */
+#define ETH_SPEED_NUM_50G          50000 /**<  50 Gbps */
+#define ETH_SPEED_NUM_56G          56000 /**<  56 Gbps */
+#define ETH_SPEED_NUM_100G        100000 /**< 100 Gbps */
+#define ETH_SPEED_NUM_UNKNOWN 0xffffffff /**< Unknown */
 
 /**
  * A structure used to retrieve link-level information of an Ethernet port.
-- 
2.17.1


^ permalink raw reply	[flat|nested] 359+ messages in thread

* [dpdk-dev] [PATCH v12 2/7] net/virtio: replace default virtio speed
       [not found]     ` <CGME20200416124312eucas1p23f4b85e17cf7f8f04c66ee3f16199936@eucas1p2.samsung.com>
@ 2020-04-16 12:42       ` Ivan Dyukov
  0 siblings, 0 replies; 359+ messages in thread
From: Ivan Dyukov @ 2020-04-16 12:42 UTC (permalink / raw)
  To: dev, maxime.coquelin, i.dyukov, v.kuramshin, amorenoz,
	zhihong.wang, xiaolong.ye, mb

This patch set speed to unknown

Signed-off-by: Ivan Dyukov <i.dyukov@samsung.com>
---
 drivers/net/virtio/virtio_ethdev.c | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/drivers/net/virtio/virtio_ethdev.c b/drivers/net/virtio/virtio_ethdev.c
index f9d0ea70d..f914329ed 100644
--- a/drivers/net/virtio/virtio_ethdev.c
+++ b/drivers/net/virtio/virtio_ethdev.c
@@ -2371,8 +2371,8 @@ virtio_dev_link_update(struct rte_eth_dev *dev, __rte_unused int wait_to_complet
 
 	memset(&link, 0, sizeof(link));
 	link.link_duplex = ETH_LINK_FULL_DUPLEX;
-	link.link_speed  = ETH_SPEED_NUM_10G;
-	link.link_autoneg = ETH_LINK_FIXED;
+	link.link_speed  = ETH_SPEED_NUM_UNKNOWN;
+	link.link_autoneg = ETH_LINK_AUTONEG;
 
 	if (!hw->started) {
 		link.link_status = ETH_LINK_DOWN;
@@ -2427,7 +2427,7 @@ virtio_dev_info_get(struct rte_eth_dev *dev, struct rte_eth_dev_info *dev_info)
 	uint64_t tso_mask, host_features;
 	struct virtio_hw *hw = dev->data->dev_private;
 
-	dev_info->speed_capa = ETH_LINK_SPEED_10G; /* fake value */
+	dev_info->speed_capa = ETH_LINK_SPEED_AUTONEG; /* fake value */
 
 	dev_info->max_rx_queues =
 		RTE_MIN(hw->max_queue_pairs, VIRTIO_MAX_RX_QUEUES);
-- 
2.17.1


^ permalink raw reply	[flat|nested] 359+ messages in thread

* [dpdk-dev] [PATCH v12 3/7] net/virtio: refactor devargs parsing
       [not found]     ` <CGME20200416124314eucas1p21c88e52504d01e4fd6ebe9f790b0e5bd@eucas1p2.samsung.com>
@ 2020-04-16 12:42       ` Ivan Dyukov
  0 siblings, 0 replies; 359+ messages in thread
From: Ivan Dyukov @ 2020-04-16 12:42 UTC (permalink / raw)
  To: dev, maxime.coquelin, i.dyukov, v.kuramshin, amorenoz,
	zhihong.wang, xiaolong.ye, mb

refactor vdpa specific devargs parsing to more generic way

Signed-off-by: Ivan Dyukov <i.dyukov@samsung.com>
---
 drivers/net/virtio/virtio_ethdev.c | 34 +++++++++++++++++++++---------
 1 file changed, 24 insertions(+), 10 deletions(-)

diff --git a/drivers/net/virtio/virtio_ethdev.c b/drivers/net/virtio/virtio_ethdev.c
index f914329ed..ca323ee57 100644
--- a/drivers/net/virtio/virtio_ethdev.c
+++ b/drivers/net/virtio/virtio_ethdev.c
@@ -1957,16 +1957,18 @@ eth_virtio_dev_uninit(struct rte_eth_dev *eth_dev)
 }
 
 static int vdpa_check_handler(__rte_unused const char *key,
-		const char *value, __rte_unused void *opaque)
+		const char *value, void *ret_val)
 {
-	if (strcmp(value, "1"))
-		return -1;
+	if (strcmp(value, "1") == 0)
+		*(int *)ret_val = 1;
+	else
+		*(int *)ret_val = 0;
 
 	return 0;
 }
 
 static int
-vdpa_mode_selected(struct rte_devargs *devargs)
+virtio_dev_devargs_parse(struct rte_devargs *devargs, int *vdpa)
 {
 	struct rte_kvargs *kvlist;
 	const char *key = "vdpa";
@@ -1982,12 +1984,16 @@ vdpa_mode_selected(struct rte_devargs *devargs)
 	if (!rte_kvargs_count(kvlist, key))
 		goto exit;
 
-	/* vdpa mode selected when there's a key-value pair: vdpa=1 */
-	if (rte_kvargs_process(kvlist, key,
-				vdpa_check_handler, NULL) < 0) {
-		goto exit;
+	if (vdpa) {
+		/* vdpa mode selected when there's a key-value pair:
+		 * vdpa=1
+		 */
+		ret = rte_kvargs_process(kvlist, key,
+				vdpa_check_handler, vdpa);
+		if (ret < 0)
+			goto exit;
 	}
-	ret = 1;
+
 
 exit:
 	rte_kvargs_free(kvlist);
@@ -1997,8 +2003,16 @@ vdpa_mode_selected(struct rte_devargs *devargs)
 static int eth_virtio_pci_probe(struct rte_pci_driver *pci_drv __rte_unused,
 	struct rte_pci_device *pci_dev)
 {
+	int vdpa = 0;
+	int ret = 0;
+
+	ret = virtio_dev_devargs_parse(pci_dev->device.devargs, &vdpa);
+	if (ret < 0) {
+		PMD_INIT_LOG(ERR, "devargs parsing is failed");
+		return ret;
+	}
 	/* virtio pmd skips probe if device needs to work in vdpa mode */
-	if (vdpa_mode_selected(pci_dev->device.devargs))
+	if (vdpa == 1)
 		return 1;
 
 	return rte_eth_dev_pci_generic_probe(pci_dev, sizeof(struct virtio_hw),
-- 
2.17.1


^ permalink raw reply	[flat|nested] 359+ messages in thread

* [dpdk-dev] [PATCH v12 4/7] net/virtio: add link speed devarg
       [not found]     ` <CGME20200416124316eucas1p2be047d5a4728c47d5db196e46fcf71ab@eucas1p2.samsung.com>
@ 2020-04-16 12:42       ` Ivan Dyukov
  0 siblings, 0 replies; 359+ messages in thread
From: Ivan Dyukov @ 2020-04-16 12:42 UTC (permalink / raw)
  To: dev, maxime.coquelin, i.dyukov, v.kuramshin, amorenoz,
	zhihong.wang, xiaolong.ye, mb

Default value of link speed is 0xffffffff (Unknown)

This patch adds speed devarg which allows to configure
link speed of virtio device.

Signed-off-by: Ivan Dyukov <i.dyukov@samsung.com>
---
 doc/guides/nics/virtio.rst         |   7 ++
 drivers/net/virtio/virtio_ethdev.c | 107 ++++++++++++++++++++++++-----
 drivers/net/virtio/virtio_pci.h    |   1 +
 3 files changed, 99 insertions(+), 16 deletions(-)

diff --git a/doc/guides/nics/virtio.rst b/doc/guides/nics/virtio.rst
index d1f5fb898..55bc6a267 100644
--- a/doc/guides/nics/virtio.rst
+++ b/doc/guides/nics/virtio.rst
@@ -356,6 +356,13 @@ Below devargs are supported by the PCI virtio driver:
     a virtio device needs to work in vDPA mode.
     (Default: 0 (disabled))
 
+#.  ``speed``:
+
+    It is used to specify link speed of virtio device, in units of 1Mb.
+    Link speed is a part of link status structure. It could be requested
+    by application using rte_eth_link_get_nowait function.
+    (Default: 0xffffffff (Unknown))
+
 Below devargs are supported by the virtio-user vdev:
 
 #.  ``path``:
diff --git a/drivers/net/virtio/virtio_ethdev.c b/drivers/net/virtio/virtio_ethdev.c
index ca323ee57..b757edfcc 100644
--- a/drivers/net/virtio/virtio_ethdev.c
+++ b/drivers/net/virtio/virtio_ethdev.c
@@ -45,6 +45,10 @@ static int virtio_dev_promiscuous_enable(struct rte_eth_dev *dev);
 static int virtio_dev_promiscuous_disable(struct rte_eth_dev *dev);
 static int virtio_dev_allmulticast_enable(struct rte_eth_dev *dev);
 static int virtio_dev_allmulticast_disable(struct rte_eth_dev *dev);
+static uint32_t virtio_dev_speed_capa_get(uint32_t speed);
+static int virtio_dev_devargs_parse(struct rte_devargs *devargs,
+	int *vdpa,
+	uint32_t *speed);
 static int virtio_dev_info_get(struct rte_eth_dev *dev,
 				struct rte_eth_dev_info *dev_info);
 static int virtio_dev_link_update(struct rte_eth_dev *dev,
@@ -1861,6 +1865,7 @@ int
 eth_virtio_dev_init(struct rte_eth_dev *eth_dev)
 {
 	struct virtio_hw *hw = eth_dev->data->dev_private;
+	uint32_t speed = ETH_SPEED_NUM_UNKNOWN;
 	int ret;
 
 	if (sizeof(struct virtio_net_hdr_mrg_rxbuf) > RTE_PKTMBUF_HEADROOM) {
@@ -1886,7 +1891,11 @@ eth_virtio_dev_init(struct rte_eth_dev *eth_dev)
 
 		return 0;
 	}
-
+	ret = virtio_dev_devargs_parse(eth_dev->device->devargs,
+		 NULL, &speed);
+	if (ret < 0)
+		return ret;
+	hw->speed = speed;
 	/*
 	 * Pass the information to the rte_eth_dev_close() that it should also
 	 * release the private port resources.
@@ -1967,33 +1976,100 @@ static int vdpa_check_handler(__rte_unused const char *key,
 	return 0;
 }
 
+
+static uint32_t
+virtio_dev_speed_capa_get(uint32_t speed)
+{
+	struct speed_caps {
+		uint32_t min_speed;
+		uint32_t speed_capa;
+	};
+	struct speed_caps caps[] = {
+		{ETH_SPEED_NUM_10M,    ETH_LINK_SPEED_10M},
+		{ETH_SPEED_NUM_100M,   ETH_LINK_SPEED_100M},
+		{ETH_SPEED_NUM_1G,     ETH_LINK_SPEED_1G},
+		{ETH_SPEED_NUM_2_5G,   ETH_LINK_SPEED_2_5G},
+		{ETH_SPEED_NUM_5G,     ETH_LINK_SPEED_5G},
+		{ETH_SPEED_NUM_10G,    ETH_LINK_SPEED_10G},
+		{ETH_SPEED_NUM_20G,    ETH_LINK_SPEED_20G},
+		{ETH_SPEED_NUM_25G,    ETH_LINK_SPEED_25G},
+		{ETH_SPEED_NUM_40G,    ETH_LINK_SPEED_40G},
+		{ETH_SPEED_NUM_50G,    ETH_LINK_SPEED_50G},
+		{ETH_SPEED_NUM_56G,    ETH_LINK_SPEED_56G},
+		{ETH_SPEED_NUM_100G,   ETH_LINK_SPEED_100G}
+	};
+	const uint32_t caps_size = sizeof(caps) / sizeof(struct speed_caps);
+	uint32_t speed_capa = ETH_LINK_SPEED_AUTONEG;
+	if (speed != ETH_SPEED_NUM_UNKNOWN) {
+		/* find maximum suitable speed capability */
+		for (uint32_t i = 0; i < caps_size; i++) {
+			if (speed >= caps[i].min_speed)
+				speed_capa = caps[i].speed_capa;
+		}
+	}
+	return speed_capa;
+}
+
+
+#define VIRTIO_ARG_SPEED      "speed"
+#define VIRTIO_ARG_VDPA       "vdpa"
+
+
 static int
-virtio_dev_devargs_parse(struct rte_devargs *devargs, int *vdpa)
+link_speed_handler(const char *key __rte_unused,
+		const char *value, void *ret_val)
+{
+	uint32_t val;
+	if (!value || !ret_val)
+		return -EINVAL;
+	errno = 0;
+	val = strtoul(value, NULL, 0);
+	/* validate input */
+	if (errno != 0)
+		return -EINVAL;
+	*(uint32_t *)ret_val = val;
+
+	return 0;
+}
+
+
+static int
+virtio_dev_devargs_parse(struct rte_devargs *devargs, int *vdpa,
+	uint32_t *speed)
 {
 	struct rte_kvargs *kvlist;
-	const char *key = "vdpa";
 	int ret = 0;
 
 	if (devargs == NULL)
 		return 0;
 
 	kvlist = rte_kvargs_parse(devargs->args, NULL);
-	if (kvlist == NULL)
+	if (kvlist == NULL) {
+		PMD_INIT_LOG(ERR, "error when parsing param");
 		return 0;
-
-	if (!rte_kvargs_count(kvlist, key))
-		goto exit;
-
-	if (vdpa) {
+	}
+	if (vdpa && rte_kvargs_count(kvlist, VIRTIO_ARG_VDPA) == 1) {
 		/* vdpa mode selected when there's a key-value pair:
 		 * vdpa=1
 		 */
-		ret = rte_kvargs_process(kvlist, key,
+		ret = rte_kvargs_process(kvlist, VIRTIO_ARG_VDPA,
 				vdpa_check_handler, vdpa);
-		if (ret < 0)
+		if (ret < 0) {
+			PMD_INIT_LOG(ERR, "Failed to parse %s",
+				VIRTIO_ARG_VDPA);
 			goto exit;
+		}
+	}
+	if (speed && rte_kvargs_count(kvlist, VIRTIO_ARG_SPEED) == 1) {
+		ret = rte_kvargs_process(kvlist,
+					VIRTIO_ARG_SPEED,
+					link_speed_handler, speed);
+		if (ret < 0) {
+			PMD_INIT_LOG(ERR, "Failed to parse %s",
+					VIRTIO_ARG_SPEED);
+			goto exit;
+		}
 	}
-
 
 exit:
 	rte_kvargs_free(kvlist);
@@ -2006,7 +2082,7 @@ static int eth_virtio_pci_probe(struct rte_pci_driver *pci_drv __rte_unused,
 	int vdpa = 0;
 	int ret = 0;
 
-	ret = virtio_dev_devargs_parse(pci_dev->device.devargs, &vdpa);
+	ret = virtio_dev_devargs_parse(pci_dev->device.devargs, &vdpa, NULL);
 	if (ret < 0) {
 		PMD_INIT_LOG(ERR, "devargs parsing is failed");
 		return ret;
@@ -2385,7 +2461,7 @@ virtio_dev_link_update(struct rte_eth_dev *dev, __rte_unused int wait_to_complet
 
 	memset(&link, 0, sizeof(link));
 	link.link_duplex = ETH_LINK_FULL_DUPLEX;
-	link.link_speed  = ETH_SPEED_NUM_UNKNOWN;
+	link.link_speed  = hw->speed;
 	link.link_autoneg = ETH_LINK_AUTONEG;
 
 	if (!hw->started) {
@@ -2440,8 +2516,7 @@ virtio_dev_info_get(struct rte_eth_dev *dev, struct rte_eth_dev_info *dev_info)
 {
 	uint64_t tso_mask, host_features;
 	struct virtio_hw *hw = dev->data->dev_private;
-
-	dev_info->speed_capa = ETH_LINK_SPEED_AUTONEG; /* fake value */
+	dev_info->speed_capa = virtio_dev_speed_capa_get(hw->speed);
 
 	dev_info->max_rx_queues =
 		RTE_MIN(hw->max_queue_pairs, VIRTIO_MAX_RX_QUEUES);
diff --git a/drivers/net/virtio/virtio_pci.h b/drivers/net/virtio/virtio_pci.h
index 7433d2f08..ed98e11c3 100644
--- a/drivers/net/virtio/virtio_pci.h
+++ b/drivers/net/virtio/virtio_pci.h
@@ -259,6 +259,7 @@ struct virtio_hw {
 	uint16_t    port_id;
 	uint8_t     mac_addr[RTE_ETHER_ADDR_LEN];
 	uint32_t    notify_off_multiplier;
+	uint32_t    speed;  /* link speed in MB */
 	uint8_t     *isr;
 	uint16_t    *notify_base;
 	struct virtio_pci_common_cfg *common_cfg;
-- 
2.17.1


^ permalink raw reply	[flat|nested] 359+ messages in thread

* [dpdk-dev] [PATCH v12 5/7] net/virtio-user: fix devargs parsing
       [not found]     ` <CGME20200416124317eucas1p15276ceb13bfb49ba429e4391d1ecce53@eucas1p1.samsung.com>
@ 2020-04-16 12:42       ` Ivan Dyukov
  0 siblings, 0 replies; 359+ messages in thread
From: Ivan Dyukov @ 2020-04-16 12:42 UTC (permalink / raw)
  To: dev, maxime.coquelin, i.dyukov, v.kuramshin, amorenoz,
	zhihong.wang, xiaolong.ye, mb
  Cc: stable

strtoull returns 0 if it fails to parse input string. It's ignored
in get_integer_arg.

This patch handles error cases for strtoull function.

Fixes: ce2eabdd43ec ("net/virtio-user: add virtual device")
Cc: stable@dpdk.org
Signed-off-by: Ivan Dyukov <i.dyukov@samsung.com>
---
 drivers/net/virtio/virtio_user_ethdev.c | 13 +++++++++----
 1 file changed, 9 insertions(+), 4 deletions(-)

diff --git a/drivers/net/virtio/virtio_user_ethdev.c b/drivers/net/virtio/virtio_user_ethdev.c
index e61af4068..a79f68a36 100644
--- a/drivers/net/virtio/virtio_user_ethdev.c
+++ b/drivers/net/virtio/virtio_user_ethdev.c
@@ -477,12 +477,17 @@ static int
 get_integer_arg(const char *key __rte_unused,
 		const char *value, void *extra_args)
 {
+	uint64_t integer = 0;
 	if (!value || !extra_args)
 		return -EINVAL;
-
-	*(uint64_t *)extra_args = strtoull(value, NULL, 0);
-
-	return 0;
+	errno = 0;
+	integer = strtoull(value, NULL, 0);
+	/* extra_args keeps default value, it should be replaced
+	 * only in case of successful parsing of the 'value' arg
+	 */
+	if (errno == 0)
+		*(uint64_t *)extra_args = integer;
+	return -errno;
 }
 
 static struct rte_eth_dev *
-- 
2.17.1


^ permalink raw reply	[flat|nested] 359+ messages in thread

* [dpdk-dev] [PATCH v12 6/7] net/virtio-user: adding link speed devarg
       [not found]     ` <CGME20200416124319eucas1p1465ff1637498a4d90f9da4b5e0524d41@eucas1p1.samsung.com>
@ 2020-04-16 12:42       ` Ivan Dyukov
  0 siblings, 0 replies; 359+ messages in thread
From: Ivan Dyukov @ 2020-04-16 12:42 UTC (permalink / raw)
  To: dev, maxime.coquelin, i.dyukov, v.kuramshin, amorenoz,
	zhihong.wang, xiaolong.ye, mb

virtio driver already parses speed devarg. virtio-user should add
it to list of valid devargs and call eth_virtio_dev_init function
which init speed value.

eth_virtio_dev_init already is called from virtio_user_pmd_probe
function. The only change is required to enable speed devargs:
adding speed to list of valid devargs.

Signed-off-by: Ivan Dyukov <i.dyukov@samsung.com>
---
 doc/guides/nics/virtio.rst              | 8 ++++++++
 drivers/net/virtio/virtio_user_ethdev.c | 5 ++++-
 2 files changed, 12 insertions(+), 1 deletion(-)

diff --git a/doc/guides/nics/virtio.rst b/doc/guides/nics/virtio.rst
index 55bc6a267..451789705 100644
--- a/doc/guides/nics/virtio.rst
+++ b/doc/guides/nics/virtio.rst
@@ -410,6 +410,14 @@ Below devargs are supported by the virtio-user vdev:
     It is used to enable virtio device packed virtqueue feature.
     (Default: 0 (disabled))
 
+#.  ``speed``:
+
+    It is used to specify link speed of virtio device, in units of 1Mb.
+    Link speed is a part of link status structure. It could be requested
+    by application using rte_eth_link_get_nowait function.
+    (Default: 0xffffffff (Unknown))
+
+
 Virtio paths Selection and Usage
 --------------------------------
 
diff --git a/drivers/net/virtio/virtio_user_ethdev.c b/drivers/net/virtio/virtio_user_ethdev.c
index a79f68a36..5b32d30fa 100644
--- a/drivers/net/virtio/virtio_user_ethdev.c
+++ b/drivers/net/virtio/virtio_user_ethdev.c
@@ -450,6 +450,8 @@ static const char *valid_args[] = {
 	VIRTIO_USER_ARG_IN_ORDER,
 #define VIRTIO_USER_ARG_PACKED_VQ      "packed_vq"
 	VIRTIO_USER_ARG_PACKED_VQ,
+#define VIRTIO_USER_ARG_SPEED          "speed"
+	VIRTIO_USER_ARG_SPEED,
 	NULL
 };
 
@@ -782,4 +784,5 @@ RTE_PMD_REGISTER_PARAM_STRING(net_virtio_user,
 	"server=<0|1> "
 	"mrg_rxbuf=<0|1> "
 	"in_order=<0|1> "
-	"packed_vq=<0|1>");
+	"packed_vq=<0|1> "
+	"speed=<int>");
-- 
2.17.1


^ permalink raw reply	[flat|nested] 359+ messages in thread

* [dpdk-dev] [PATCH v12 7/7] net/virtio: Support of VIRTIO_NET_F_SPEED_DUPLEX
       [not found]     ` <CGME20200416124321eucas1p2768f2846666ffad04efcadd871859cf9@eucas1p2.samsung.com>
@ 2020-04-16 12:42       ` Ivan Dyukov
  0 siblings, 0 replies; 359+ messages in thread
From: Ivan Dyukov @ 2020-04-16 12:42 UTC (permalink / raw)
  To: dev, maxime.coquelin, i.dyukov, v.kuramshin, amorenoz,
	zhihong.wang, xiaolong.ye, mb

This patch adds a support of VIRTIO_NET_F_SPEED_DUPLEX feature
for virtio driver.

There are two ways to specify speed of the link:
  * 'speed' devarg
  * negotiate speed from qemu via VIRTIO_NET_F_SPEED_DUPLEX
The highest priority is devarg. If devarg is not specified,
driver tries to negotiate it from qemu.

Signed-off-by: Ivan Dyukov <i.dyukov@samsung.com>
---
 drivers/net/virtio/virtio_ethdev.c | 14 ++++++++++++++
 drivers/net/virtio/virtio_ethdev.h |  3 ++-
 drivers/net/virtio/virtio_pci.h    | 15 +++++++++++++++
 3 files changed, 31 insertions(+), 1 deletion(-)

diff --git a/drivers/net/virtio/virtio_ethdev.c b/drivers/net/virtio/virtio_ethdev.c
index b757edfcc..46d699773 100644
--- a/drivers/net/virtio/virtio_ethdev.c
+++ b/drivers/net/virtio/virtio_ethdev.c
@@ -1718,6 +1718,20 @@ virtio_init_device(struct rte_eth_dev *eth_dev, uint64_t req_features)
 		     hw->mac_addr[0], hw->mac_addr[1], hw->mac_addr[2],
 		     hw->mac_addr[3], hw->mac_addr[4], hw->mac_addr[5]);
 
+	if (vtpci_with_feature(hw, VIRTIO_NET_F_SPEED_DUPLEX)) {
+		config = &local_config;
+		/* if speed is not specified in devargs */
+		if (hw->speed == ETH_SPEED_NUM_UNKNOWN) {
+			vtpci_read_dev_config(hw,
+				offsetof(struct virtio_net_config, speed),
+				&config->speed, sizeof(config->speed));
+			hw->speed = config->speed;
+		}
+	}
+
+	PMD_INIT_LOG(DEBUG, "link speed = %u%s",
+		hw->speed, hw->speed == ETH_SPEED_NUM_UNKNOWN ?
+		"(UNKNOWN)" : "");
 	if (vtpci_with_feature(hw, VIRTIO_NET_F_CTRL_VQ)) {
 		config = &local_config;
 
diff --git a/drivers/net/virtio/virtio_ethdev.h b/drivers/net/virtio/virtio_ethdev.h
index cd8947656..febaf17a8 100644
--- a/drivers/net/virtio/virtio_ethdev.h
+++ b/drivers/net/virtio/virtio_ethdev.h
@@ -37,7 +37,8 @@
 	 1ULL << VIRTIO_F_RING_PACKED	  |	\
 	 1ULL << VIRTIO_F_IOMMU_PLATFORM  |	\
 	 1ULL << VIRTIO_F_ORDER_PLATFORM  |	\
-	 1ULL << VIRTIO_F_NOTIFICATION_DATA)
+	 1ULL << VIRTIO_F_NOTIFICATION_DATA | \
+	 1ULL << VIRTIO_NET_F_SPEED_DUPLEX)
 
 #define VIRTIO_PMD_SUPPORTED_GUEST_FEATURES	\
 	(VIRTIO_PMD_DEFAULT_GUEST_FEATURES |	\
diff --git a/drivers/net/virtio/virtio_pci.h b/drivers/net/virtio/virtio_pci.h
index ed98e11c3..2948760ab 100644
--- a/drivers/net/virtio/virtio_pci.h
+++ b/drivers/net/virtio/virtio_pci.h
@@ -141,6 +141,9 @@ struct virtnet_ctl;
  */
 #define VIRTIO_F_NOTIFICATION_DATA 38
 
+/* Device set linkspeed and duplex */
+#define VIRTIO_NET_F_SPEED_DUPLEX 63
+
 /* The Guest publishes the used index for which it expects an interrupt
  * at the end of the avail ring. Host should ignore the avail->flags field. */
 /* The Host publishes the avail index for which it expects a kick
@@ -306,6 +309,18 @@ struct virtio_net_config {
 	uint16_t   status;
 	uint16_t   max_virtqueue_pairs;
 	uint16_t   mtu;
+	/*
+	 * speed, in units of 1Mb. All values 0 to INT_MAX are legal.
+	 * Any other value stands for unknown.
+	 */
+	uint32_t speed;
+	/*
+	 * 0x00 - half duplex
+	 * 0x01 - full duplex
+	 * Any other value stands for unknown.
+	 */
+	uint8_t duplex;
+
 } __attribute__((packed));
 
 /*
-- 
2.17.1


^ permalink raw reply	[flat|nested] 359+ messages in thread

* Re: [dpdk-dev] [PATCH v12 1/7] ethdev: added UNKNOWN speed value
  2020-04-16 12:42       ` [dpdk-dev] [PATCH v12 1/7] ethdev: added UNKNOWN speed value Ivan Dyukov
@ 2020-04-16 22:14         ` Thomas Monjalon
  2020-04-17  6:40           ` Ivan Dyukov
  0 siblings, 1 reply; 359+ messages in thread
From: Thomas Monjalon @ 2020-04-16 22:14 UTC (permalink / raw)
  To: Ivan Dyukov
  Cc: dev, maxime.coquelin, v.kuramshin, amorenoz, zhihong.wang,
	xiaolong.ye, mb, ferruh.yigit, arybchenko

Hi,

Please look at an update below from ethdev co-maintainers.

16/04/2020 14:42, Ivan Dyukov:
> UNKNOWN speed equals to 0xffffffff
[...]
> +#define ETH_SPEED_NUM_UNKNOWN 0xffffffff /**< Unknown */

This approach is being rejected in another thread:
http://inbox.dpdk.org/dev/42de4bd1-0a6c-6591-cd27-67ce692fabc9@intel.com/




^ permalink raw reply	[flat|nested] 359+ messages in thread

* Re: [dpdk-dev] [PATCH v12 1/7] ethdev: added UNKNOWN speed value
  2020-04-16 22:14         ` Thomas Monjalon
@ 2020-04-17  6:40           ` Ivan Dyukov
  2020-04-17 15:14             ` Maxime Coquelin
  0 siblings, 1 reply; 359+ messages in thread
From: Ivan Dyukov @ 2020-04-17  6:40 UTC (permalink / raw)
  To: Thomas Monjalon, maxime.coquelin, mb, ferruh.yigit, arybchenko
  Cc: dev, v.kuramshin, amorenoz, zhihong.wang, xiaolong.ye

Hello Everyone,

Ook. I can take care about examples updates. link_speed could be printed 
in following way:
("link speed %u%s", link_speed, link_speed 
==ETH_SPEED_NUM_UNKNOWN?"(UNKNOWN)":"")

Please let me know if you have any objections.

There are about 47 cases.

$ grep -rn link_speed examples/ app/ doc/ | wc -l
47

Thanks,
Ivan
17.04.2020 01:14, Thomas Monjalon пишет:
> Hi,
>
> Please look at an update below from ethdev co-maintainers.
>
> 16/04/2020 14:42, Ivan Dyukov:
>> UNKNOWN speed equals to 0xffffffff
> [...]
>> +#define ETH_SPEED_NUM_UNKNOWN 0xffffffff /**< Unknown */
> This approach is being rejected in another thread:
> https://protect2.fireeye.com/url?k=ed2d2a70-b0fe73ce-ed2ca13f-0cc47a31ba82-80584d32127c24cd&q=1&u=http%3A%2F%2Finbox.dpdk.org%2Fdev%2F42de4bd1-0a6c-6591-cd27-67ce692fabc9%40intel.com%2F
>
>
>
>


^ permalink raw reply	[flat|nested] 359+ messages in thread

* Re: [dpdk-dev] [PATCH v12 1/7] ethdev: added UNKNOWN speed value
  2020-04-17  6:40           ` Ivan Dyukov
@ 2020-04-17 15:14             ` Maxime Coquelin
  2020-04-17 15:44               ` Ferruh Yigit
  0 siblings, 1 reply; 359+ messages in thread
From: Maxime Coquelin @ 2020-04-17 15:14 UTC (permalink / raw)
  To: Ivan Dyukov, Thomas Monjalon, mb, ferruh.yigit, arybchenko
  Cc: dev, v.kuramshin, amorenoz, zhihong.wang, xiaolong.ye

Hi Ferruh & Andrew,

On 4/17/20 8:40 AM, Ivan Dyukov wrote:
> Hello Everyone,
> 
> Ook. I can take care about examples updates. link_speed could be printed 
> in following way:
> ("link speed %u%s", link_speed, link_speed 
> ==ETH_SPEED_NUM_UNKNOWN?"(UNKNOWN)":"")
> 
> Please let me know if you have any objections.
> 
> There are about 47 cases.
> 
> $ grep -rn link_speed examples/ app/ doc/ | wc -l
> 47
> 
> Thanks,
> Ivan
> 17.04.2020 01:14, Thomas Monjalon пишет:
>> Hi,
>>
>> Please look at an update below from ethdev co-maintainers.
>>
>> 16/04/2020 14:42, Ivan Dyukov:
>>> UNKNOWN speed equals to 0xffffffff
>> [...]
>>> +#define ETH_SPEED_NUM_UNKNOWN 0xffffffff /**< Unknown */
>> This approach is being rejected in another thread:
>> https://protect2.fireeye.com/url?k=ed2d2a70-b0fe73ce-ed2ca13f-0cc47a31ba82-80584d32127c24cd&q=1&u=http%3A%2F%2Finbox.dpdk.org%2Fdev%2F42de4bd1-0a6c-6591-cd27-67ce692fabc9%40intel.com%2F

Would that work for you?
I would need your ACK before applying the series (which I planned to do
for -rc1).

Thanks in advance,
Maxime


^ permalink raw reply	[flat|nested] 359+ messages in thread

* Re: [dpdk-dev] [PATCH v12 1/7] ethdev: added UNKNOWN speed value
  2020-04-17 15:14             ` Maxime Coquelin
@ 2020-04-17 15:44               ` Ferruh Yigit
  2020-04-17 15:54                 ` Maxime Coquelin
  0 siblings, 1 reply; 359+ messages in thread
From: Ferruh Yigit @ 2020-04-17 15:44 UTC (permalink / raw)
  To: Maxime Coquelin, Ivan Dyukov, Thomas Monjalon, mb, arybchenko
  Cc: dev, v.kuramshin, amorenoz, zhihong.wang, xiaolong.ye

On 4/17/2020 4:14 PM, Maxime Coquelin wrote:
> Hi Ferruh & Andrew,
> 
> On 4/17/20 8:40 AM, Ivan Dyukov wrote:
>> Hello Everyone,
>>
>> Ook. I can take care about examples updates. link_speed could be printed 
>> in following way:
>> ("link speed %u%s", link_speed, link_speed 
>> ==ETH_SPEED_NUM_UNKNOWN?"(UNKNOWN)":"")
>>
>> Please let me know if you have any objections.
>>
>> There are about 47 cases.
>>
>> $ grep -rn link_speed examples/ app/ doc/ | wc -l
>> 47
>>
>> Thanks,
>> Ivan
>> 17.04.2020 01:14, Thomas Monjalon пишет:
>>> Hi,
>>>
>>> Please look at an update below from ethdev co-maintainers.
>>>
>>> 16/04/2020 14:42, Ivan Dyukov:
>>>> UNKNOWN speed equals to 0xffffffff
>>> [...]
>>>> +#define ETH_SPEED_NUM_UNKNOWN 0xffffffff /**< Unknown */
>>> This approach is being rejected in another thread:
>>> https://protect2.fireeye.com/url?k=ed2d2a70-b0fe73ce-ed2ca13f-0cc47a31ba82-80584d32127c24cd&q=1&u=http%3A%2F%2Finbox.dpdk.org%2Fdev%2F42de4bd1-0a6c-6591-cd27-67ce692fabc9%40intel.com%2F
> 
> Would that work for you?
> I would need your ACK before applying the series (which I planned to do
> for -rc1).

Hi Maxime,

There is another patch from Thomas that targets this change only [1], and it is
waiting for change request, because the scope of the change is larger than just
defining a new macro, documentation & sample/test applications should be aware
of this new speed definition.

Instead of this patch, this patchset can wait [1] as dependency.

Or if this patchset is urgent, perhaps this patch can go in as it as and Thomas'
patch can replace it later with full implementation, if Thomas agrees.

And not sure if it is good idea, but perhaps this "unknown speed' can be used
local to virtio until [1] becomes ready, though I am for having this as last option.

[1]
https://patches.dpdk.org/patch/67915/

^ permalink raw reply	[flat|nested] 359+ messages in thread

* Re: [dpdk-dev] [PATCH v12 1/7] ethdev: added UNKNOWN speed value
  2020-04-17 15:44               ` Ferruh Yigit
@ 2020-04-17 15:54                 ` Maxime Coquelin
  2020-04-17 17:23                   ` Thomas Monjalon
  0 siblings, 1 reply; 359+ messages in thread
From: Maxime Coquelin @ 2020-04-17 15:54 UTC (permalink / raw)
  To: Ferruh Yigit, Ivan Dyukov, Thomas Monjalon, mb, arybchenko
  Cc: dev, v.kuramshin, amorenoz, zhihong.wang, xiaolong.ye

Hi Ferruh,

On 4/17/20 5:44 PM, Ferruh Yigit wrote:
> On 4/17/2020 4:14 PM, Maxime Coquelin wrote:
>> Hi Ferruh & Andrew,
>>
>> On 4/17/20 8:40 AM, Ivan Dyukov wrote:
>>> Hello Everyone,
>>>
>>> Ook. I can take care about examples updates. link_speed could be printed 
>>> in following way:
>>> ("link speed %u%s", link_speed, link_speed 
>>> ==ETH_SPEED_NUM_UNKNOWN?"(UNKNOWN)":"")
>>>
>>> Please let me know if you have any objections.
>>>
>>> There are about 47 cases.
>>>
>>> $ grep -rn link_speed examples/ app/ doc/ | wc -l
>>> 47
>>>
>>> Thanks,
>>> Ivan
>>> 17.04.2020 01:14, Thomas Monjalon пишет:
>>>> Hi,
>>>>
>>>> Please look at an update below from ethdev co-maintainers.
>>>>
>>>> 16/04/2020 14:42, Ivan Dyukov:
>>>>> UNKNOWN speed equals to 0xffffffff
>>>> [...]
>>>>> +#define ETH_SPEED_NUM_UNKNOWN 0xffffffff /**< Unknown */
>>>> This approach is being rejected in another thread:
>>>> https://protect2.fireeye.com/url?k=ed2d2a70-b0fe73ce-ed2ca13f-0cc47a31ba82-80584d32127c24cd&q=1&u=http%3A%2F%2Finbox.dpdk.org%2Fdev%2F42de4bd1-0a6c-6591-cd27-67ce692fabc9%40intel.com%2F
>>
>> Would that work for you?
>> I would need your ACK before applying the series (which I planned to do
>> for -rc1).
> 
> Hi Maxime,
> 
> There is another patch from Thomas that targets this change only [1], and it is
> waiting for change request, because the scope of the change is larger than just
> defining a new macro, documentation & sample/test applications should be aware
> of this new speed definition.
> 
> Instead of this patch, this patchset can wait [1] as dependency.
> 
> Or if this patchset is urgent, perhaps this patch can go in as it as and Thomas'
> patch can replace it later with full implementation, if Thomas agrees.
> 
> And not sure if it is good idea, but perhaps this "unknown speed' can be used
> local to virtio until [1] becomes ready, though I am for having this as last option.

I was replying to my mail after discussing with Thomas.

I agree Thomas's series is better, and now understand this is an API
change that was not announced.

What I propose it basically to apply Ivan's v8 with a few fixes on top
that he did. It means that if no value is set in the NIC or not value
defined as devargs, then 10G will be picked as default.

Note that the 10G value is the one currently displayyed, without Ivan's
series, so it seems a reasonable temporary solution.

Thanks,
Maxime

> [1]
> https://patches.dpdk.org/patch/67915/
> 


^ permalink raw reply	[flat|nested] 359+ messages in thread

* Re: [dpdk-dev] [PATCH v8 0/5] net/virtio: add link speed devarg
  2020-03-30  7:57     ` [dpdk-dev] [PATCH v8 0/5] net/virtio: add link speed devarg Ivan Dyukov
                         ` (4 preceding siblings ...)
       [not found]       ` <CGME20200330075834eucas1p2892713fbbd1b13d9f65e5efc9d25d9a8@eucas1p2.samsung.com>
@ 2020-04-17 17:12       ` Maxime Coquelin
  5 siblings, 0 replies; 359+ messages in thread
From: Maxime Coquelin @ 2020-04-17 17:12 UTC (permalink / raw)
  To: Ivan Dyukov, dev, tiwei.bie, amorenoz, zhihong.wang, xiaolong.ye

Hi Ivan,

On 3/30/20 9:57 AM, Ivan Dyukov wrote:
> 
> v8 changes:
> * fix code style
> 
> v7 chagnes:
> * rebased to latest master
> * added support of VIRTIO_NET_F_SPEED_DUPLEX
> 
> v6 changes:
> * fix code style
> 
> v5 changes:
> * fixed code style
> * fixed commit message and logging text
> 
> v4 changes:
> * link_speed renamed to speed devarg
> * speed devarg is added to virtio-user driver
> 
> v3 changes:
> * link_speed devarg is added to virtio documentation
> 
> 

I finally applied this version, with adding the changes not related to
ETH_SPEED_NUM_UNKNOWN from next revisions.
Once the ETH_SPEED_NUM_UNKNOWN series from Thomas is accepted (might
only happen in v20.08), we'll adopt it in Virtio driver.

It is applied to dpdk-next-virtio/master, let me know if you spot any
issue there.

Thanks again for adding VIRTIO_NET_F_SPEED_DUPLEX,
Maxime


^ permalink raw reply	[flat|nested] 359+ messages in thread

* Re: [dpdk-dev] [PATCH v12 1/7] ethdev: added UNKNOWN speed value
  2020-04-17 15:54                 ` Maxime Coquelin
@ 2020-04-17 17:23                   ` Thomas Monjalon
       [not found]                     ` <CGME20200427095750eucas1p29d1b58cf0e55bf6bc50be3e42ccff159@eucas1p2.samsung.com>
  0 siblings, 1 reply; 359+ messages in thread
From: Thomas Monjalon @ 2020-04-17 17:23 UTC (permalink / raw)
  To: Ferruh Yigit, Ivan Dyukov, mb, arybchenko, Maxime Coquelin
  Cc: dev, v.kuramshin, amorenoz, zhihong.wang, xiaolong.ye

17/04/2020 17:54, Maxime Coquelin:
> Hi Ferruh,
> 
> On 4/17/20 5:44 PM, Ferruh Yigit wrote:
> > On 4/17/2020 4:14 PM, Maxime Coquelin wrote:
> >> Hi Ferruh & Andrew,
> >>
> >> On 4/17/20 8:40 AM, Ivan Dyukov wrote:
> >>> Hello Everyone,
> >>>
> >>> Ook. I can take care about examples updates. link_speed could be printed 
> >>> in following way:
> >>> ("link speed %u%s", link_speed, link_speed 
> >>> ==ETH_SPEED_NUM_UNKNOWN?"(UNKNOWN)":"")
> >>>
> >>> Please let me know if you have any objections.
> >>>
> >>> There are about 47 cases.
> >>>
> >>> $ grep -rn link_speed examples/ app/ doc/ | wc -l
> >>> 47
> >>>
> >>> Thanks,
> >>> Ivan
> >>> 17.04.2020 01:14, Thomas Monjalon пишет:
> >>>> Hi,
> >>>>
> >>>> Please look at an update below from ethdev co-maintainers.
> >>>>
> >>>> 16/04/2020 14:42, Ivan Dyukov:
> >>>>> UNKNOWN speed equals to 0xffffffff
> >>>> [...]
> >>>>> +#define ETH_SPEED_NUM_UNKNOWN 0xffffffff /**< Unknown */
> >>>> This approach is being rejected in another thread:
> >>>> https://protect2.fireeye.com/url?k=ed2d2a70-b0fe73ce-ed2ca13f-0cc47a31ba82-80584d32127c24cd&q=1&u=http%3A%2F%2Finbox.dpdk.org%2Fdev%2F42de4bd1-0a6c-6591-cd27-67ce692fabc9%40intel.com%2F
> >>
> >> Would that work for you?
> >> I would need your ACK before applying the series (which I planned to do
> >> for -rc1).
> > 
> > Hi Maxime,
> > 
> > There is another patch from Thomas that targets this change only [1], and it is
> > waiting for change request, because the scope of the change is larger than just
> > defining a new macro, documentation & sample/test applications should be aware
> > of this new speed definition.
> > 
> > Instead of this patch, this patchset can wait [1] as dependency.
> > 
> > Or if this patchset is urgent, perhaps this patch can go in as it as and Thomas'
> > patch can replace it later with full implementation, if Thomas agrees.
> > 
> > And not sure if it is good idea, but perhaps this "unknown speed' can be used
> > local to virtio until [1] becomes ready, though I am for having this as last option.
> 
> I was replying to my mail after discussing with Thomas.
> 
> I agree Thomas's series is better, and now understand this is an API
> change that was not announced.
> 
> What I propose it basically to apply Ivan's v8 with a few fixes on top
> that he did. It means that if no value is set in the NIC or not value
> defined as devargs, then 10G will be picked as default.
> 
> Note that the 10G value is the one currently displayyed, without Ivan's
> series, so it seems a reasonable temporary solution.

I am OK with the suggested solution for virtio in 20.05.

Any help to implement and document unknown speed is welcome.
I won't work on it during the next 2 weeks, so feel free to take over
my patch and make it complete for 20.08.



^ permalink raw reply	[flat|nested] 359+ messages in thread

* [dpdk-dev] [PATCH v1 0/6] ethdev: allow unknown link speed
       [not found]                     ` <CGME20200427095750eucas1p29d1b58cf0e55bf6bc50be3e42ccff159@eucas1p2.samsung.com>
@ 2020-04-27  9:57                       ` Ivan Dyukov
       [not found]                         ` <CGME20200427095753eucas1p24327f9862457d9f3bc892a60c8645814@eucas1p2.samsung.com>
                                           ` (16 more replies)
  0 siblings, 17 replies; 359+ messages in thread
From: Ivan Dyukov @ 2020-04-27  9:57 UTC (permalink / raw)
  To: dev, i.dyukov, v.kuramshin, thomas, david.marchand, ferruh.yigit,
	arybchenko

This is initial patchset which introduces UNKNOWN speed to dpdk
applications. Also it contains changes related to printf formating.
Patchset contains changes for app/ and doc/ folders.
examples/ folder will be provided later.




^ permalink raw reply	[flat|nested] 359+ messages in thread

* [dpdk-dev] [PATCH v1 1/6] ethdev: allow unknown link speed
       [not found]                         ` <CGME20200427095753eucas1p24327f9862457d9f3bc892a60c8645814@eucas1p2.samsung.com>
@ 2020-04-27  9:57                           ` " Ivan Dyukov
  2020-05-01 13:10                             ` Andrew Rybchenko
  0 siblings, 1 reply; 359+ messages in thread
From: Ivan Dyukov @ 2020-04-27  9:57 UTC (permalink / raw)
  To: dev, i.dyukov, v.kuramshin, thomas, david.marchand, ferruh.yigit,
	arybchenko

From: Thomas Monjalon <thomas@monjalon.net>

When querying the link informations, the link status is
a mandatory major information.
Other boolean values are supposed to be accurate:
	- duplex mode (half/full)
	- negotiation (auto/fixed)

This API update is making explicit that the link speed information
is optional.
The value ETH_SPEED_NUM_NONE (0) was already part of the API.
The value ETH_SPEED_NUM_UNKNOWN (infinite) is added to cover
two different cases:
	- speed is not known by the driver
	- device is virtual

Suggested-by: Morten Brørup <mb@smartsharesystems.com>
Suggested-by: Benoit Ganne <bganne@cisco.com>
Signed-off-by: Thomas Monjalon <thomas@monjalon.net>
---
 lib/librte_ethdev/rte_ethdev.h | 20 ++++++++++----------
 1 file changed, 10 insertions(+), 10 deletions(-)

diff --git a/lib/librte_ethdev/rte_ethdev.h b/lib/librte_ethdev/rte_ethdev.h
index 0f6d0530d..2f94a09d4 100644
--- a/lib/librte_ethdev/rte_ethdev.h
+++ b/lib/librte_ethdev/rte_ethdev.h
@@ -301,6 +301,7 @@ struct rte_eth_stats {
 #define ETH_SPEED_NUM_50G      50000 /**<  50 Gbps */
 #define ETH_SPEED_NUM_56G      56000 /**<  56 Gbps */
 #define ETH_SPEED_NUM_100G    100000 /**< 100 Gbps */
+#define ETH_SPEED_NUM_UNKNOWN UINT32_MAX /**< Unknown */
 
 /**
  * A structure used to retrieve link-level information of an Ethernet port.
@@ -2260,15 +2261,16 @@ int rte_eth_allmulticast_disable(uint16_t port_id);
 int rte_eth_allmulticast_get(uint16_t port_id);
 
 /**
- * Retrieve the status (ON/OFF), the speed (in Mbps) and the mode (HALF-DUPLEX
- * or FULL-DUPLEX) of the physical link of an Ethernet device. It might need
- * to wait up to 9 seconds in it.
+ * Retrieve the link status (up/down), the duplex mode (half/full),
+ * the negotiation (auto/fixed), and if available, the speed (Mbps).
+ *
+ * It might need to wait up to 9 seconds.
+ * @see rte_eth_link_get_nowait.
  *
  * @param port_id
  *   The port identifier of the Ethernet device.
  * @param link
- *   A pointer to an *rte_eth_link* structure to be filled with
- *   the status, the speed and the mode of the Ethernet device link.
+ *   Link informations written back.
  * @return
  *   - (0) if successful.
  *   - (-ENOTSUP) if the function is not supported in PMD driver.
@@ -2277,15 +2279,13 @@ int rte_eth_allmulticast_get(uint16_t port_id);
 int rte_eth_link_get(uint16_t port_id, struct rte_eth_link *link);
 
 /**
- * Retrieve the status (ON/OFF), the speed (in Mbps) and the mode (HALF-DUPLEX
- * or FULL-DUPLEX) of the physical link of an Ethernet device. It is a no-wait
- * version of rte_eth_link_get().
+ * Retrieve the link status (up/down), the duplex mode (half/full),
+ * the negotiation (auto/fixed), and if available, the speed (Mbps).
  *
  * @param port_id
  *   The port identifier of the Ethernet device.
  * @param link
- *   A pointer to an *rte_eth_link* structure to be filled with
- *   the status, the speed and the mode of the Ethernet device link.
+ *   Link informations written back.
  * @return
  *   - (0) if successful.
  *   - (-ENOTSUP) if the function is not supported in PMD driver.
-- 
2.17.1


^ permalink raw reply	[flat|nested] 359+ messages in thread

* [dpdk-dev] [PATCH v1 2/6] app/procinfo: fix printf format specifier for uint
       [not found]                         ` <CGME20200427095754eucas1p2fb7a4e57cfa9006aebdd0e7a5d4d5e58@eucas1p2.samsung.com>
@ 2020-04-27  9:57                           ` Ivan Dyukov
  0 siblings, 0 replies; 359+ messages in thread
From: Ivan Dyukov @ 2020-04-27  9:57 UTC (permalink / raw)
  To: dev, i.dyukov, v.kuramshin, thomas, david.marchand, ferruh.yigit,
	arybchenko

Signed-off-by: Ivan Dyukov <i.dyukov@samsung.com>
---
 app/proc-info/main.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/app/proc-info/main.c b/app/proc-info/main.c
index abeca4aab..b1a025a36 100644
--- a/app/proc-info/main.c
+++ b/app/proc-info/main.c
@@ -685,7 +685,7 @@ show_port(void)
 			printf("Link get failed (port %u): %s\n",
 			       i, rte_strerror(-ret));
 		} else {
-			printf("\t  -- link speed %d duplex %d,"
+			printf("\t  -- link speed %u duplex %d,"
 					" auto neg %d status %d\n",
 					link.link_speed,
 					link.link_duplex,
-- 
2.17.1


^ permalink raw reply	[flat|nested] 359+ messages in thread

* [dpdk-dev] [PATCH v1 3/6] ethdev: remove extra 'new line' in output
       [not found]                         ` <CGME20200427095756eucas1p208ef420a6cb9b3f3fc6b7ce09210c973@eucas1p2.samsung.com>
@ 2020-04-27  9:57                           ` Ivan Dyukov
  2020-05-01 13:15                             ` Andrew Rybchenko
  0 siblings, 1 reply; 359+ messages in thread
From: Ivan Dyukov @ 2020-04-27  9:57 UTC (permalink / raw)
  To: dev, i.dyukov, v.kuramshin, thomas, david.marchand, ferruh.yigit,
	arybchenko

Signed-off-by: Ivan Dyukov <i.dyukov@samsung.com>
---
 app/test-pmd/testpmd.c   | 2 +-
 app/test/test_pmd_perf.c | 2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/app/test-pmd/testpmd.c b/app/test-pmd/testpmd.c
index 99bacddbf..d4df23a93 100644
--- a/app/test-pmd/testpmd.c
+++ b/app/test-pmd/testpmd.c
@@ -3005,7 +3005,7 @@ check_all_ports_link_status(uint32_t port_mask)
 					"Port%d Link Up. speed %u Mbps- %s\n",
 					portid, link.link_speed,
 				(link.link_duplex == ETH_LINK_FULL_DUPLEX) ?
-					("full-duplex") : ("half-duplex\n"));
+					("full-duplex") : ("half-duplex"));
 				else
 					printf("Port %d Link Down\n", portid);
 				continue;
diff --git a/app/test/test_pmd_perf.c b/app/test/test_pmd_perf.c
index d61be58bb..352cd4715 100644
--- a/app/test/test_pmd_perf.c
+++ b/app/test/test_pmd_perf.c
@@ -151,7 +151,7 @@ check_all_ports_link_status(uint16_t port_num, uint32_t port_mask)
 					"Port%d Link Up. Speed %u Mbps - %s\n",
 						portid, link.link_speed,
 				(link.link_duplex == ETH_LINK_FULL_DUPLEX) ?
-					("full-duplex") : ("half-duplex\n"));
+					("full-duplex") : ("half-duplex"));
 					if (link_mbps == 0)
 						link_mbps = link.link_speed;
 				} else
-- 
2.17.1


^ permalink raw reply	[flat|nested] 359+ messages in thread

* [dpdk-dev] [PATCH v1 4/6] app/testpmd: remove extra type conversions
       [not found]                         ` <CGME20200427095757eucas1p272442bb5f00d143ef6498bf3c264fcf4@eucas1p2.samsung.com>
@ 2020-04-27  9:57                           ` Ivan Dyukov
  0 siblings, 0 replies; 359+ messages in thread
From: Ivan Dyukov @ 2020-04-27  9:57 UTC (permalink / raw)
  To: dev, i.dyukov, v.kuramshin, thomas, david.marchand, ferruh.yigit,
	arybchenko

link_speed is uint32_t. There are no needs to convert it.

Signed-off-by: Ivan Dyukov <i.dyukov@samsung.com>
---
 app/test-pmd/config.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/app/test-pmd/config.c b/app/test-pmd/config.c
index 72f25d152..661297ddd 100644
--- a/app/test-pmd/config.c
+++ b/app/test-pmd/config.c
@@ -577,7 +577,7 @@ port_infos_display(portid_t port_id)
 		printf("\nmemory allocation on the socket: %u",port->socket_id);
 
 	printf("\nLink status: %s\n", (link.link_status) ? ("up") : ("down"));
-	printf("Link speed: %u Mbps\n", (unsigned) link.link_speed);
+	printf("Link speed: %u Mbps\n", link.link_speed);
 	printf("Link duplex: %s\n", (link.link_duplex == ETH_LINK_FULL_DUPLEX) ?
 	       ("full-duplex") : ("half-duplex"));
 
@@ -727,7 +727,7 @@ port_summary_display(portid_t port_id)
 		mac_addr.addr_bytes[2], mac_addr.addr_bytes[3],
 		mac_addr.addr_bytes[4], mac_addr.addr_bytes[5], name,
 		dev_info.driver_name, (link.link_status) ? ("up") : ("down"),
-		(unsigned int) link.link_speed);
+		link.link_speed);
 }
 
 void
-- 
2.17.1


^ permalink raw reply	[flat|nested] 359+ messages in thread

* [dpdk-dev] [PATCH v1 5/6] doc: update sample app with unknown speed
       [not found]                         ` <CGME20200427095759eucas1p146d501188af3d1215707e664672076bf@eucas1p1.samsung.com>
@ 2020-04-27  9:57                           ` Ivan Dyukov
  2020-05-01 13:28                             ` Andrew Rybchenko
  0 siblings, 1 reply; 359+ messages in thread
From: Ivan Dyukov @ 2020-04-27  9:57 UTC (permalink / raw)
  To: dev, i.dyukov, v.kuramshin, thomas, david.marchand, ferruh.yigit,
	arybchenko

Signed-off-by: Ivan Dyukov <i.dyukov@samsung.com>
---
 doc/guides/sample_app_ug/link_status_intr.rst | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/doc/guides/sample_app_ug/link_status_intr.rst b/doc/guides/sample_app_ug/link_status_intr.rst
index 5283be8b7..6ebc707b7 100644
--- a/doc/guides/sample_app_ug/link_status_intr.rst
+++ b/doc/guides/sample_app_ug/link_status_intr.rst
@@ -177,7 +177,8 @@ An example callback function that has been written as indicated below.
             printf("Failed to get port %d link status: %s\n\n",
                    port_id, rte_strerror(-ret));
         } else if (link.link_status) {
-            printf("Port %d Link Up - speed %u Mbps - %s\n\n", port_id, (unsigned)link.link_speed,
+            printf("Port %d Link Up - speed %u%s - %s\n\n", port_id, (unsigned)link.link_speed,
+                  (link.link_speed == UINT32_MAX) ? ("(UNKNOWN)") : (" Mbps"),
                   (link.link_duplex == ETH_LINK_FULL_DUPLEX) ? ("full-duplex") : ("half-duplex"));
         } else
             printf("Port %d Link Down\n\n", port_id);
-- 
2.17.1


^ permalink raw reply	[flat|nested] 359+ messages in thread

* [dpdk-dev] [PATCH v1 6/6] ethdev: UNKNOWN link speed print format
       [not found]                         ` <CGME20200427095800eucas1p16c30ec18649efe66b831728fe661703f@eucas1p1.samsung.com>
@ 2020-04-27  9:57                           ` Ivan Dyukov
  0 siblings, 0 replies; 359+ messages in thread
From: Ivan Dyukov @ 2020-04-27  9:57 UTC (permalink / raw)
  To: dev, i.dyukov, v.kuramshin, thomas, david.marchand, ferruh.yigit,
	arybchenko

Signed-off-by: Ivan Dyukov <i.dyukov@samsung.com>
---
 app/proc-info/main.c     |  7 ++++++-
 app/test-pipeline/init.c | 14 ++++++++------
 app/test-pmd/config.c    | 10 ++++++----
 app/test-pmd/testpmd.c   |  4 +++-
 app/test/test_pmd_perf.c |  4 +++-
 5 files changed, 26 insertions(+), 13 deletions(-)

diff --git a/app/proc-info/main.c b/app/proc-info/main.c
index b1a025a36..27065a231 100644
--- a/app/proc-info/main.c
+++ b/app/proc-info/main.c
@@ -685,10 +685,15 @@ show_port(void)
 			printf("Link get failed (port %u): %s\n",
 			       i, rte_strerror(-ret));
 		} else {
-			printf("\t  -- link speed %u duplex %d,"
+			printf("\t  -- link speed %u%s duplex %d%s,"
 					" auto neg %d status %d\n",
 					link.link_speed,
+					(link.link_speed == UINT32_MAX) ?
+					("(UNKNOWN)") : (" Mbps"),
 					link.link_duplex,
+					(link.link_duplex == 
+					 ETH_LINK_FULL_DUPLEX) ?
+					("(full)") : ("(half)"),
 					link.link_autoneg,
 					link.link_status);
 		}
diff --git a/app/test-pipeline/init.c b/app/test-pipeline/init.c
index 67d54ae05..09b762a4e 100644
--- a/app/test-pipeline/init.c
+++ b/app/test-pipeline/init.c
@@ -173,12 +173,14 @@ app_ports_check_link(void)
 			all_ports_up = 0;
 			continue;
 		}
-
-		RTE_LOG(INFO, USER1, "Port %u (%u Gbps) %s\n",
-			port,
-			link.link_speed / 1000,
-			link.link_status ? "UP" : "DOWN");
-
+		if (link.link_speed == UINT32_MAX)
+			RTE_LOG(INFO, USER1, "Port %u (UNKNOWN Gbps) %s\n",
+				port, link.link_status ? "UP" : "DOWN");
+		else
+			RTE_LOG(INFO, USER1, "Port %u (%u Gbps) %s\n",
+				port,
+				link.link_speed / 1000,
+				link.link_status ? "UP" : "DOWN");
 		if (link.link_status == ETH_LINK_DOWN)
 			all_ports_up = 0;
 	}
diff --git a/app/test-pmd/config.c b/app/test-pmd/config.c
index 661297ddd..96e668ae5 100644
--- a/app/test-pmd/config.c
+++ b/app/test-pmd/config.c
@@ -577,7 +577,8 @@ port_infos_display(portid_t port_id)
 		printf("\nmemory allocation on the socket: %u",port->socket_id);
 
 	printf("\nLink status: %s\n", (link.link_status) ? ("up") : ("down"));
-	printf("Link speed: %u Mbps\n", link.link_speed);
+	printf("Link speed: %u%s\n", link.link_speed,
+	       (link.link_speed == UINT32_MAX) ? ("(UNKNOWN)") : (" Mbps"));
 	printf("Link duplex: %s\n", (link.link_duplex == ETH_LINK_FULL_DUPLEX) ?
 	       ("full-duplex") : ("half-duplex"));
 
@@ -722,12 +723,13 @@ port_summary_display(portid_t port_id)
 	if (ret != 0)
 		return;
 
-	printf("%-4d %02X:%02X:%02X:%02X:%02X:%02X %-12s %-14s %-8s %uMbps\n",
+	printf("%-4d %02X:%02X:%02X:%02X:%02X:%02X %-12s %-14s %-8s %u%s\n",
 		port_id, mac_addr.addr_bytes[0], mac_addr.addr_bytes[1],
 		mac_addr.addr_bytes[2], mac_addr.addr_bytes[3],
 		mac_addr.addr_bytes[4], mac_addr.addr_bytes[5], name,
 		dev_info.driver_name, (link.link_status) ? ("up") : ("down"),
-		link.link_speed);
+		link.link_speed,
+		(link.link_speed == UINT32_MAX) ? ("(UNKNOWN)") : (" Mbps"));
 }
 
 void
@@ -3787,7 +3789,7 @@ set_queue_rate_limit(portid_t port_id, uint16_t queue_idx, uint16_t rate)
 	ret = eth_link_get_nowait_print_err(port_id, &link);
 	if (ret < 0)
 		return 1;
-	if (rate > link.link_speed) {
+	if (link.link_speed != UINT32_MAX && rate > link.link_speed) {
 		printf("Invalid rate value:%u bigger than link speed: %u\n",
 			rate, link.link_speed);
 		return 1;
diff --git a/app/test-pmd/testpmd.c b/app/test-pmd/testpmd.c
index d4df23a93..9b47886f7 100644
--- a/app/test-pmd/testpmd.c
+++ b/app/test-pmd/testpmd.c
@@ -3002,8 +3002,10 @@ check_all_ports_link_status(uint32_t port_mask)
 			if (print_flag == 1) {
 				if (link.link_status)
 					printf(
-					"Port%d Link Up. speed %u Mbps- %s\n",
+					"Port%d Link Up. speed %u%s- %s\n",
 					portid, link.link_speed,
+				(link.link_speed == UINT32_MAX) ?
+					("(UNKNOWN)") : (" Mbps"),
 				(link.link_duplex == ETH_LINK_FULL_DUPLEX) ?
 					("full-duplex") : ("half-duplex"));
 				else
diff --git a/app/test/test_pmd_perf.c b/app/test/test_pmd_perf.c
index 352cd4715..c8124676d 100644
--- a/app/test/test_pmd_perf.c
+++ b/app/test/test_pmd_perf.c
@@ -148,8 +148,10 @@ check_all_ports_link_status(uint16_t port_num, uint32_t port_mask)
 			if (print_flag == 1) {
 				if (link.link_status) {
 					printf(
-					"Port%d Link Up. Speed %u Mbps - %s\n",
+					"Port%d Link Up. Speed %u%s - %s\n",
 						portid, link.link_speed,
+				(link.link_speed == UINT32_MAX) ?
+					("(UNKNOWN)") : (" Mbps"),
 				(link.link_duplex == ETH_LINK_FULL_DUPLEX) ?
 					("full-duplex") : ("half-duplex"));
 					if (link_mbps == 0)
-- 
2.17.1


^ permalink raw reply	[flat|nested] 359+ messages in thread

* Re: [dpdk-dev] [PATCH v1 1/6] ethdev: allow unknown link speed
  2020-04-27  9:57                           ` [dpdk-dev] [PATCH v1 1/6] " Ivan Dyukov
@ 2020-05-01 13:10                             ` Andrew Rybchenko
  0 siblings, 0 replies; 359+ messages in thread
From: Andrew Rybchenko @ 2020-05-01 13:10 UTC (permalink / raw)
  To: Thomas Monjalon, dev, i.dyukov, v.kuramshin, thomas,
	david.marchand, ferruh.yigit, arybchenko

On 4/27/20 12:57 PM, Ivan Dyukov wrote:
> From: Thomas Monjalon <thomas@monjalon.net>
> 
> When querying the link informations, the link status is
> a mandatory major information.
> Other boolean values are supposed to be accurate:
> 	- duplex mode (half/full)
> 	- negotiation (auto/fixed)
> 
> This API update is making explicit that the link speed information
> is optional.
> The value ETH_SPEED_NUM_NONE (0) was already part of the API.
> The value ETH_SPEED_NUM_UNKNOWN (infinite) is added to cover
> two different cases:
> 	- speed is not known by the driver
> 	- device is virtual
> 
> Suggested-by: Morten Brørup <mb@smartsharesystems.com>
> Suggested-by: Benoit Ganne <bganne@cisco.com>
> Signed-off-by: Thomas Monjalon <thomas@monjalon.net>

Acked-by: Andrew Rybchenko <arybchenko@solarflare.com>


^ permalink raw reply	[flat|nested] 359+ messages in thread

* Re: [dpdk-dev] [PATCH v1 3/6] ethdev: remove extra 'new line' in output
  2020-04-27  9:57                           ` [dpdk-dev] [PATCH v1 3/6] ethdev: remove extra 'new line' in output Ivan Dyukov
@ 2020-05-01 13:15                             ` Andrew Rybchenko
  2020-05-07 10:28                               ` Thomas Monjalon
  0 siblings, 1 reply; 359+ messages in thread
From: Andrew Rybchenko @ 2020-05-01 13:15 UTC (permalink / raw)
  To: Thomas Monjalon, dev, i.dyukov, v.kuramshin, thomas,
	david.marchand, ferruh.yigit, arybchenko

On 4/27/20 12:57 PM, Ivan Dyukov wrote:
> Signed-off-by: Ivan Dyukov <i.dyukov@samsung.com>
> ---
>   app/test-pmd/testpmd.c   | 2 +-
>   app/test/test_pmd_perf.c | 2 +-
>   2 files changed, 2 insertions(+), 2 deletions(-)
> 
> diff --git a/app/test-pmd/testpmd.c b/app/test-pmd/testpmd.c
> index 99bacddbf..d4df23a93 100644
> --- a/app/test-pmd/testpmd.c
> +++ b/app/test-pmd/testpmd.c
> @@ -3005,7 +3005,7 @@ check_all_ports_link_status(uint32_t port_mask)
>   					"Port%d Link Up. speed %u Mbps- %s\n",
>   					portid, link.link_speed,
>   				(link.link_duplex == ETH_LINK_FULL_DUPLEX) ?
> -					("full-duplex") : ("half-duplex\n"));
> +					("full-duplex") : ("half-duplex"));
>   				else
>   					printf("Port %d Link Down\n", portid);
>   				continue;
> diff --git a/app/test/test_pmd_perf.c b/app/test/test_pmd_perf.c
> index d61be58bb..352cd4715 100644
> --- a/app/test/test_pmd_perf.c
> +++ b/app/test/test_pmd_perf.c
> @@ -151,7 +151,7 @@ check_all_ports_link_status(uint16_t port_num, uint32_t port_mask)
>   					"Port%d Link Up. Speed %u Mbps - %s\n",
>   						portid, link.link_speed,
>   				(link.link_duplex == ETH_LINK_FULL_DUPLEX) ?
> -					("full-duplex") : ("half-duplex\n"));
> +					("full-duplex") : ("half-duplex"));
>   					if (link_mbps == 0)
>   						link_mbps = link.link_speed;
>   				} else
> 


I think Fixes: tag is required here.

Acked-by: Andrew Rybchenko <arybchenko@solarflare.com>

^ permalink raw reply	[flat|nested] 359+ messages in thread

* Re: [dpdk-dev] [PATCH v1 5/6] doc: update sample app with unknown speed
  2020-04-27  9:57                           ` [dpdk-dev] [PATCH v1 5/6] doc: update sample app with unknown speed Ivan Dyukov
@ 2020-05-01 13:28                             ` Andrew Rybchenko
  2020-05-02 19:35                               ` Ivan Dyukov
  0 siblings, 1 reply; 359+ messages in thread
From: Andrew Rybchenko @ 2020-05-01 13:28 UTC (permalink / raw)
  To: Thomas Monjalon, dev, i.dyukov, v.kuramshin, thomas,
	david.marchand, ferruh.yigit, arybchenko

On 4/27/20 12:57 PM, Ivan Dyukov wrote:
> Signed-off-by: Ivan Dyukov <i.dyukov@samsung.com>
> ---
>   doc/guides/sample_app_ug/link_status_intr.rst | 3 ++-
>   1 file changed, 2 insertions(+), 1 deletion(-)
> 
> diff --git a/doc/guides/sample_app_ug/link_status_intr.rst b/doc/guides/sample_app_ug/link_status_intr.rst
> index 5283be8b7..6ebc707b7 100644
> --- a/doc/guides/sample_app_ug/link_status_intr.rst
> +++ b/doc/guides/sample_app_ug/link_status_intr.rst
> @@ -177,7 +177,8 @@ An example callback function that has been written as indicated below.
>               printf("Failed to get port %d link status: %s\n\n",
>                      port_id, rte_strerror(-ret));
>           } else if (link.link_status) {
> -            printf("Port %d Link Up - speed %u Mbps - %s\n\n", port_id, (unsigned)link.link_speed,
> +            printf("Port %d Link Up - speed %u%s - %s\n\n", port_id, (unsigned)link.link_speed,
> +                  (link.link_speed == UINT32_MAX) ? ("(UNKNOWN)") : (" Mbps"),
>                     (link.link_duplex == ETH_LINK_FULL_DUPLEX) ? ("full-duplex") : ("half-duplex"));
>           } else
>               printf("Port %d Link Down\n\n", port_id);
> 

I think that 0 looks nicer than UINT32_MAX when printed as integer
keeping in mind that it is unknown.

^ permalink raw reply	[flat|nested] 359+ messages in thread

* Re: [dpdk-dev] [PATCH v1 5/6] doc: update sample app with unknown speed
  2020-05-01 13:28                             ` Andrew Rybchenko
@ 2020-05-02 19:35                               ` Ivan Dyukov
  2020-05-03 13:57                                 ` Andrew Rybchenko
  0 siblings, 1 reply; 359+ messages in thread
From: Ivan Dyukov @ 2020-05-02 19:35 UTC (permalink / raw)
  To: Andrew Rybchenko, Thomas Monjalon, dev, v.kuramshin,
	david.marchand, ferruh.yigit

01.05.2020 16:28, Andrew Rybchenko пишет:
> On 4/27/20 12:57 PM, Ivan Dyukov wrote:
>> Signed-off-by: Ivan Dyukov <i.dyukov@samsung.com>
>> ---
>>   doc/guides/sample_app_ug/link_status_intr.rst | 3 ++-
>>   1 file changed, 2 insertions(+), 1 deletion(-)
>>
>> diff --git a/doc/guides/sample_app_ug/link_status_intr.rst 
>> b/doc/guides/sample_app_ug/link_status_intr.rst
>> index 5283be8b7..6ebc707b7 100644
>> --- a/doc/guides/sample_app_ug/link_status_intr.rst
>> +++ b/doc/guides/sample_app_ug/link_status_intr.rst
>> @@ -177,7 +177,8 @@ An example callback function that has been 
>> written as indicated below.
>>               printf("Failed to get port %d link status: %s\n\n",
>>                      port_id, rte_strerror(-ret));
>>           } else if (link.link_status) {
>> -            printf("Port %d Link Up - speed %u Mbps - %s\n\n", 
>> port_id, (unsigned)link.link_speed,
>> +            printf("Port %d Link Up - speed %u%s - %s\n\n", port_id, 
>> (unsigned)link.link_speed,
>> +                  (link.link_speed == UINT32_MAX) ? ("(UNKNOWN)") : 
>> (" Mbps"),
>>                     (link.link_duplex == ETH_LINK_FULL_DUPLEX) ? 
>> ("full-duplex") : ("half-duplex"));
>>           } else
>>               printf("Port %d Link Down\n\n", port_id);
>>
>
> I think that 0 looks nicer than UINT32_MAX when printed as integer
> keeping in mind that it is unknown.
>
zero will mislead developers about real value of the link_speed. 
therefore we should print real value of the speed or print nothing. e.g.

    if (link.link_speed == UINT32_MAX)

         printf("Port %d Link Up - speed UNKNOWN - %s\n\n", port_id,
                    (link.link_duplex == ETH_LINK_FULL_DUPLEX) ? 
("full-duplex") : ("half-duplex"));
    else

         printf("Port %d Link Up - speed %u Mbps - %s\n\n", port_id, 
link.link_speed,

                     (link.link_duplex == ETH_LINK_FULL_DUPLEX) ? 
("full-duplex") : ("half-duplex"));


^ permalink raw reply	[flat|nested] 359+ messages in thread

* Re: [dpdk-dev] [PATCH v1 5/6] doc: update sample app with unknown speed
  2020-05-02 19:35                               ` Ivan Dyukov
@ 2020-05-03 13:57                                 ` Andrew Rybchenko
  2020-05-04  1:16                                   ` Varghese, Vipin
                                                     ` (2 more replies)
  0 siblings, 3 replies; 359+ messages in thread
From: Andrew Rybchenko @ 2020-05-03 13:57 UTC (permalink / raw)
  To: Ivan Dyukov, Thomas Monjalon, dev, v.kuramshin, david.marchand,
	ferruh.yigit

On 5/2/20 10:35 PM, Ivan Dyukov wrote:
> 01.05.2020 16:28, Andrew Rybchenko пишет:
>> On 4/27/20 12:57 PM, Ivan Dyukov wrote:
>>> Signed-off-by: Ivan Dyukov <i.dyukov@samsung.com>
>>> ---
>>>   doc/guides/sample_app_ug/link_status_intr.rst | 3 ++-
>>>   1 file changed, 2 insertions(+), 1 deletion(-)
>>>
>>> diff --git a/doc/guides/sample_app_ug/link_status_intr.rst 
>>> b/doc/guides/sample_app_ug/link_status_intr.rst
>>> index 5283be8b7..6ebc707b7 100644
>>> --- a/doc/guides/sample_app_ug/link_status_intr.rst
>>> +++ b/doc/guides/sample_app_ug/link_status_intr.rst
>>> @@ -177,7 +177,8 @@ An example callback function that has been 
>>> written as indicated below.
>>>               printf("Failed to get port %d link status: %s\n\n",
>>>                      port_id, rte_strerror(-ret));
>>>           } else if (link.link_status) {
>>> -            printf("Port %d Link Up - speed %u Mbps - %s\n\n", 
>>> port_id, (unsigned)link.link_speed,
>>> +            printf("Port %d Link Up - speed %u%s - %s\n\n", port_id, 
>>> (unsigned)link.link_speed,
>>> +                  (link.link_speed == UINT32_MAX) ? ("(UNKNOWN)") : 
>>> (" Mbps"),
>>>                     (link.link_duplex == ETH_LINK_FULL_DUPLEX) ? 
>>> ("full-duplex") : ("half-duplex"));
>>>           } else
>>>               printf("Port %d Link Down\n\n", port_id);
>>>
>> I think that 0 looks nicer than UINT32_MAX when printed as integer
>> keeping in mind that it is unknown.
>>
> zero will mislead developers about real value of the link_speed. 
> therefore we should print real value of the speed or print nothing. e.g.
>
>     if (link.link_speed == UINT32_MAX)
>
>          printf("Port %d Link Up - speed UNKNOWN - %s\n\n", port_id,
>                     (link.link_duplex == ETH_LINK_FULL_DUPLEX) ? 
> ("full-duplex") : ("half-duplex"));
>     else
>
>          printf("Port %d Link Up - speed %u Mbps - %s\n\n", port_id, 
> link.link_speed,
>
>                      (link.link_duplex == ETH_LINK_FULL_DUPLEX) ? 
> ("full-duplex") : ("half-duplex"));

I'm not sure about 0 to be misleading, but it could be.
Above definitely will look better in stdout.
The only problem is code duplication in many-many places.
May be add simple function in ethdev to do it and use it in
all examples?

Please, wait more feedback before doing it.


^ permalink raw reply	[flat|nested] 359+ messages in thread

* Re: [dpdk-dev] [PATCH v1 5/6] doc: update sample app with unknown speed
  2020-05-03 13:57                                 ` Andrew Rybchenko
@ 2020-05-04  1:16                                   ` Varghese, Vipin
  2020-05-04 15:46                                   ` Ivan Dyukov
  2020-05-06 17:40                                   ` Ferruh Yigit
  2 siblings, 0 replies; 359+ messages in thread
From: Varghese, Vipin @ 2020-05-04  1:16 UTC (permalink / raw)
  To: Andrew Rybchenko, Ivan Dyukov, Thomas Monjalon, dev, v.kuramshin,
	david.marchand, Yigit, Ferruh

Hi,

Sharing an observation especially with Fortville (X710), if the port is not started the advertised speed is not max speed (`10000` or `40000`). Hence would cross check on `link_state` be useful before display?



> -----Original Message-----
> From: dev <dev-bounces@dpdk.org> On Behalf Of Andrew Rybchenko
> Sent: Sunday, May 3, 2020 7:27 PM
> To: Ivan Dyukov <i.dyukov@samsung.com>; Thomas Monjalon
> <thomas@monjalon.net>; dev@dpdk.org; v.kuramshin@samsung.com;
> david.marchand@redhat.com; Yigit, Ferruh <ferruh.yigit@intel.com>
> Subject: Re: [dpdk-dev] [PATCH v1 5/6] doc: update sample app with unknown
> speed
> 
> On 5/2/20 10:35 PM, Ivan Dyukov wrote:
> > 01.05.2020 16:28, Andrew Rybchenko пишет:
> >> On 4/27/20 12:57 PM, Ivan Dyukov wrote:
> >>> Signed-off-by: Ivan Dyukov <i.dyukov@samsung.com>
> >>> ---
> >>>   doc/guides/sample_app_ug/link_status_intr.rst | 3 ++-
> >>>   1 file changed, 2 insertions(+), 1 deletion(-)
> >>>
> >>> diff --git a/doc/guides/sample_app_ug/link_status_intr.rst
> >>> b/doc/guides/sample_app_ug/link_status_intr.rst
> >>> index 5283be8b7..6ebc707b7 100644
> >>> --- a/doc/guides/sample_app_ug/link_status_intr.rst
> >>> +++ b/doc/guides/sample_app_ug/link_status_intr.rst
> >>> @@ -177,7 +177,8 @@ An example callback function that has been
> >>> written as indicated below.
> >>>               printf("Failed to get port %d link status: %s\n\n",
> >>>                      port_id, rte_strerror(-ret));
> >>>           } else if (link.link_status) {
> >>> -            printf("Port %d Link Up - speed %u Mbps - %s\n\n",
> >>> port_id, (unsigned)link.link_speed,
> >>> +            printf("Port %d Link Up - speed %u%s - %s\n\n",
> >>> +port_id,
> >>> (unsigned)link.link_speed,
> >>> +                  (link.link_speed == UINT32_MAX) ? ("(UNKNOWN)") :
> >>> (" Mbps"),
> >>>                     (link.link_duplex == ETH_LINK_FULL_DUPLEX) ?
> >>> ("full-duplex") : ("half-duplex"));
> >>>           } else
> >>>               printf("Port %d Link Down\n\n", port_id);
> >>>
> >> I think that 0 looks nicer than UINT32_MAX when printed as integer
> >> keeping in mind that it is unknown.
> >>
> > zero will mislead developers about real value of the link_speed.
> > therefore we should print real value of the speed or print nothing. e.g.
> >
> >     if (link.link_speed == UINT32_MAX)
> >
> >          printf("Port %d Link Up - speed UNKNOWN - %s\n\n", port_id,
> >                     (link.link_duplex == ETH_LINK_FULL_DUPLEX) ?
> > ("full-duplex") : ("half-duplex"));
> >     else
> >
> >          printf("Port %d Link Up - speed %u Mbps - %s\n\n", port_id,
> > link.link_speed,
> >
> >                      (link.link_duplex == ETH_LINK_FULL_DUPLEX) ?
> > ("full-duplex") : ("half-duplex"));
> 
> I'm not sure about 0 to be misleading, but it could be.
> Above definitely will look better in stdout.
> The only problem is code duplication in many-many places.
> May be add simple function in ethdev to do it and use it in all examples?
> 
> Please, wait more feedback before doing it.


^ permalink raw reply	[flat|nested] 359+ messages in thread

* Re: [dpdk-dev] [PATCH v1 5/6] doc: update sample app with unknown speed
  2020-05-03 13:57                                 ` Andrew Rybchenko
  2020-05-04  1:16                                   ` Varghese, Vipin
@ 2020-05-04 15:46                                   ` Ivan Dyukov
  2020-05-04 15:54                                     ` Andrew Rybchenko
  2020-05-06 17:40                                   ` Ferruh Yigit
  2 siblings, 1 reply; 359+ messages in thread
From: Ivan Dyukov @ 2020-05-04 15:46 UTC (permalink / raw)
  To: Andrew Rybchenko, Thomas Monjalon, dev, v.kuramshin,
	david.marchand, ferruh.yigit

03.05.2020 16:57, Andrew Rybchenko пишет:
> On 5/2/20 10:35 PM, Ivan Dyukov wrote:
>> 01.05.2020 16:28, Andrew Rybchenko пишет:
>>> On 4/27/20 12:57 PM, Ivan Dyukov wrote:
>>>> Signed-off-by: Ivan Dyukov <i.dyukov@samsung.com>
>>>> ---
>>>>    doc/guides/sample_app_ug/link_status_intr.rst | 3 ++-
>>>>    1 file changed, 2 insertions(+), 1 deletion(-)
>>>>
>>>> diff --git a/doc/guides/sample_app_ug/link_status_intr.rst
>>>> b/doc/guides/sample_app_ug/link_status_intr.rst
>>>> index 5283be8b7..6ebc707b7 100644
>>>> --- a/doc/guides/sample_app_ug/link_status_intr.rst
>>>> +++ b/doc/guides/sample_app_ug/link_status_intr.rst
>>>> @@ -177,7 +177,8 @@ An example callback function that has been
>>>> written as indicated below.
>>>>                printf("Failed to get port %d link status: %s\n\n",
>>>>                       port_id, rte_strerror(-ret));
>>>>            } else if (link.link_status) {
>>>> -            printf("Port %d Link Up - speed %u Mbps - %s\n\n",
>>>> port_id, (unsigned)link.link_speed,
>>>> +            printf("Port %d Link Up - speed %u%s - %s\n\n", port_id,
>>>> (unsigned)link.link_speed,
>>>> +                  (link.link_speed == UINT32_MAX) ? ("(UNKNOWN)") :
>>>> (" Mbps"),
>>>>                      (link.link_duplex == ETH_LINK_FULL_DUPLEX) ?
>>>> ("full-duplex") : ("half-duplex"));
>>>>            } else
>>>>                printf("Port %d Link Down\n\n", port_id);
>>>>
>>> I think that 0 looks nicer than UINT32_MAX when printed as integer
>>> keeping in mind that it is unknown.
>>>
>> zero will mislead developers about real value of the link_speed.
>> therefore we should print real value of the speed or print nothing. e.g.
>>
>>      if (link.link_speed == UINT32_MAX)
>>
>>           printf("Port %d Link Up - speed UNKNOWN - %s\n\n", port_id,
>>                      (link.link_duplex == ETH_LINK_FULL_DUPLEX) ?
>> ("full-duplex") : ("half-duplex"));
>>      else
>>
>>           printf("Port %d Link Up - speed %u Mbps - %s\n\n", port_id,
>> link.link_speed,
>>
>>                       (link.link_duplex == ETH_LINK_FULL_DUPLEX) ?
>> ("full-duplex") : ("half-duplex"));
> I'm not sure about 0 to be misleading, but it could be.
> Above definitely will look better in stdout.
> The only problem is code duplication in many-many places.
> May be add simple function in ethdev to do it and use it in
> all examples?
Also we can introduce new printf specifier using 
register_printf_specifier function or even rewrite %u which will print 
UNKNOWN in case of
UINT32_MAX.
>
> Please, wait more feedback before doing it.
>
>


^ permalink raw reply	[flat|nested] 359+ messages in thread

* Re: [dpdk-dev] [PATCH v1 5/6] doc: update sample app with unknown speed
  2020-05-04 15:46                                   ` Ivan Dyukov
@ 2020-05-04 15:54                                     ` Andrew Rybchenko
  2020-05-04 18:31                                       ` Ivan Dyukov
  0 siblings, 1 reply; 359+ messages in thread
From: Andrew Rybchenko @ 2020-05-04 15:54 UTC (permalink / raw)
  To: Ivan Dyukov, Thomas Monjalon, dev, v.kuramshin, david.marchand,
	ferruh.yigit

On 5/4/20 6:46 PM, Ivan Dyukov wrote:
> 03.05.2020 16:57, Andrew Rybchenko пишет:
>> On 5/2/20 10:35 PM, Ivan Dyukov wrote:
>>> 01.05.2020 16:28, Andrew Rybchenko пишет:
>>>> On 4/27/20 12:57 PM, Ivan Dyukov wrote:
>>>>> Signed-off-by: Ivan Dyukov <i.dyukov@samsung.com>
>>>>> ---
>>>>>    doc/guides/sample_app_ug/link_status_intr.rst | 3 ++-
>>>>>    1 file changed, 2 insertions(+), 1 deletion(-)
>>>>>
>>>>> diff --git a/doc/guides/sample_app_ug/link_status_intr.rst
>>>>> b/doc/guides/sample_app_ug/link_status_intr.rst
>>>>> index 5283be8b7..6ebc707b7 100644
>>>>> --- a/doc/guides/sample_app_ug/link_status_intr.rst
>>>>> +++ b/doc/guides/sample_app_ug/link_status_intr.rst
>>>>> @@ -177,7 +177,8 @@ An example callback function that has been
>>>>> written as indicated below.
>>>>>                printf("Failed to get port %d link status: %s\n\n",
>>>>>                       port_id, rte_strerror(-ret));
>>>>>            } else if (link.link_status) {
>>>>> -            printf("Port %d Link Up - speed %u Mbps - %s\n\n",
>>>>> port_id, (unsigned)link.link_speed,
>>>>> +            printf("Port %d Link Up - speed %u%s - %s\n\n", port_id,
>>>>> (unsigned)link.link_speed,
>>>>> +                  (link.link_speed == UINT32_MAX) ? ("(UNKNOWN)") :
>>>>> (" Mbps"),
>>>>>                      (link.link_duplex == ETH_LINK_FULL_DUPLEX) ?
>>>>> ("full-duplex") : ("half-duplex"));
>>>>>            } else
>>>>>                printf("Port %d Link Down\n\n", port_id);
>>>>>
>>>> I think that 0 looks nicer than UINT32_MAX when printed as integer
>>>> keeping in mind that it is unknown.
>>>>
>>> zero will mislead developers about real value of the link_speed.
>>> therefore we should print real value of the speed or print nothing. e.g.
>>>
>>>      if (link.link_speed == UINT32_MAX)
>>>
>>>           printf("Port %d Link Up - speed UNKNOWN - %s\n\n", port_id,
>>>                      (link.link_duplex == ETH_LINK_FULL_DUPLEX) ?
>>> ("full-duplex") : ("half-duplex"));
>>>      else
>>>
>>>           printf("Port %d Link Up - speed %u Mbps - %s\n\n", port_id,
>>> link.link_speed,
>>>
>>>                       (link.link_duplex == ETH_LINK_FULL_DUPLEX) ?
>>> ("full-duplex") : ("half-duplex"));
>> I'm not sure about 0 to be misleading, but it could be.
>> Above definitely will look better in stdout.
>> The only problem is code duplication in many-many places.
>> May be add simple function in ethdev to do it and use it in
>> all examples?
> Also we can introduce new printf specifier using 
> register_printf_specifier function or even rewrite %u which will print 
> UNKNOWN in case of
> UINT32_MAX.

True, but it is too libc-specific as far as I know.

>> Please, wait more feedback before doing it.
>>
>>


^ permalink raw reply	[flat|nested] 359+ messages in thread

* Re: [dpdk-dev] [PATCH v1 5/6] doc: update sample app with unknown speed
  2020-05-04 15:54                                     ` Andrew Rybchenko
@ 2020-05-04 18:31                                       ` Ivan Dyukov
  0 siblings, 0 replies; 359+ messages in thread
From: Ivan Dyukov @ 2020-05-04 18:31 UTC (permalink / raw)
  To: Andrew Rybchenko, Thomas Monjalon, dev, v.kuramshin,
	david.marchand, ferruh.yigit

04.05.2020 18:54, Andrew Rybchenko пишет:
> On 5/4/20 6:46 PM, Ivan Dyukov wrote:
>> 03.05.2020 16:57, Andrew Rybchenko пишет:
>>> On 5/2/20 10:35 PM, Ivan Dyukov wrote:
>>>> 01.05.2020 16:28, Andrew Rybchenko пишет:
>>>>> On 4/27/20 12:57 PM, Ivan Dyukov wrote:
>>>>>> Signed-off-by: Ivan Dyukov <i.dyukov@samsung.com>
>>>>>> ---
>>>>>>     doc/guides/sample_app_ug/link_status_intr.rst | 3 ++-
>>>>>>     1 file changed, 2 insertions(+), 1 deletion(-)
>>>>>>
>>>>>> diff --git a/doc/guides/sample_app_ug/link_status_intr.rst
>>>>>> b/doc/guides/sample_app_ug/link_status_intr.rst
>>>>>> index 5283be8b7..6ebc707b7 100644
>>>>>> --- a/doc/guides/sample_app_ug/link_status_intr.rst
>>>>>> +++ b/doc/guides/sample_app_ug/link_status_intr.rst
>>>>>> @@ -177,7 +177,8 @@ An example callback function that has been
>>>>>> written as indicated below.
>>>>>>                 printf("Failed to get port %d link status: %s\n\n",
>>>>>>                        port_id, rte_strerror(-ret));
>>>>>>             } else if (link.link_status) {
>>>>>> -            printf("Port %d Link Up - speed %u Mbps - %s\n\n",
>>>>>> port_id, (unsigned)link.link_speed,
>>>>>> +            printf("Port %d Link Up - speed %u%s - %s\n\n", port_id,
>>>>>> (unsigned)link.link_speed,
>>>>>> +                  (link.link_speed == UINT32_MAX) ? ("(UNKNOWN)") :
>>>>>> (" Mbps"),
>>>>>>                       (link.link_duplex == ETH_LINK_FULL_DUPLEX) ?
>>>>>> ("full-duplex") : ("half-duplex"));
>>>>>>             } else
>>>>>>                 printf("Port %d Link Down\n\n", port_id);
>>>>>>
>>>>> I think that 0 looks nicer than UINT32_MAX when printed as integer
>>>>> keeping in mind that it is unknown.
>>>>>
>>>> zero will mislead developers about real value of the link_speed.
>>>> therefore we should print real value of the speed or print nothing. e.g.
>>>>
>>>>       if (link.link_speed == UINT32_MAX)
>>>>
>>>>            printf("Port %d Link Up - speed UNKNOWN - %s\n\n", port_id,
>>>>                       (link.link_duplex == ETH_LINK_FULL_DUPLEX) ?
>>>> ("full-duplex") : ("half-duplex"));
>>>>       else
>>>>
>>>>            printf("Port %d Link Up - speed %u Mbps - %s\n\n", port_id,
>>>> link.link_speed,
>>>>
>>>>                        (link.link_duplex == ETH_LINK_FULL_DUPLEX) ?
>>>> ("full-duplex") : ("half-duplex"));
>>> I'm not sure about 0 to be misleading, but it could be.
>>> Above definitely will look better in stdout.
>>> The only problem is code duplication in many-many places.
>>> May be add simple function in ethdev to do it and use it in
>>> all examples?
>> Also we can introduce new printf specifier using
>> register_printf_specifier function or even rewrite %u which will print
>> UNKNOWN in case of
>> UINT32_MAX.
> True, but it is too libc-specific as far as I know.

Yep, it has portability issues. It's GNU C extension. https://www.gnu.org/software/libc/manual/html_node/Customizing-Printf.html

>
>>> Please, wait more feedback before doing it.
>>>
>>>
>


^ permalink raw reply	[flat|nested] 359+ messages in thread

* Re: [dpdk-dev] [PATCH v1 5/6] doc: update sample app with unknown speed
  2020-05-03 13:57                                 ` Andrew Rybchenko
  2020-05-04  1:16                                   ` Varghese, Vipin
  2020-05-04 15:46                                   ` Ivan Dyukov
@ 2020-05-06 17:40                                   ` Ferruh Yigit
  2 siblings, 0 replies; 359+ messages in thread
From: Ferruh Yigit @ 2020-05-06 17:40 UTC (permalink / raw)
  To: Andrew Rybchenko, Ivan Dyukov, Thomas Monjalon, dev, v.kuramshin,
	david.marchand

On 5/3/2020 2:57 PM, Andrew Rybchenko wrote:
> On 5/2/20 10:35 PM, Ivan Dyukov wrote:
>> 01.05.2020 16:28, Andrew Rybchenko пишет:
>>> On 4/27/20 12:57 PM, Ivan Dyukov wrote:
>>>> Signed-off-by: Ivan Dyukov <i.dyukov@samsung.com>
>>>> ---
>>>>   doc/guides/sample_app_ug/link_status_intr.rst | 3 ++-
>>>>   1 file changed, 2 insertions(+), 1 deletion(-)
>>>>
>>>> diff --git a/doc/guides/sample_app_ug/link_status_intr.rst 
>>>> b/doc/guides/sample_app_ug/link_status_intr.rst
>>>> index 5283be8b7..6ebc707b7 100644
>>>> --- a/doc/guides/sample_app_ug/link_status_intr.rst
>>>> +++ b/doc/guides/sample_app_ug/link_status_intr.rst
>>>> @@ -177,7 +177,8 @@ An example callback function that has been 
>>>> written as indicated below.
>>>>               printf("Failed to get port %d link status: %s\n\n",
>>>>                      port_id, rte_strerror(-ret));
>>>>           } else if (link.link_status) {
>>>> -            printf("Port %d Link Up - speed %u Mbps - %s\n\n", 
>>>> port_id, (unsigned)link.link_speed,
>>>> +            printf("Port %d Link Up - speed %u%s - %s\n\n", port_id, 
>>>> (unsigned)link.link_speed,
>>>> +                  (link.link_speed == UINT32_MAX) ? ("(UNKNOWN)") : 
>>>> (" Mbps"),
>>>>                     (link.link_duplex == ETH_LINK_FULL_DUPLEX) ? 
>>>> ("full-duplex") : ("half-duplex"));
>>>>           } else
>>>>               printf("Port %d Link Down\n\n", port_id);
>>>>
>>> I think that 0 looks nicer than UINT32_MAX when printed as integer
>>> keeping in mind that it is unknown.
>>>
>> zero will mislead developers about real value of the link_speed. 
>> therefore we should print real value of the speed or print nothing. e.g.
>>
>>     if (link.link_speed == UINT32_MAX)
>>
>>          printf("Port %d Link Up - speed UNKNOWN - %s\n\n", port_id,
>>                     (link.link_duplex == ETH_LINK_FULL_DUPLEX) ? 
>> ("full-duplex") : ("half-duplex"));
>>     else
>>
>>          printf("Port %d Link Up - speed %u Mbps - %s\n\n", port_id, 
>> link.link_speed,
>>
>>                      (link.link_duplex == ETH_LINK_FULL_DUPLEX) ? 
>> ("full-duplex") : ("half-duplex"));
> 
> I'm not sure about 0 to be misleading, but it could be.
> Above definitely will look better in stdout.

+1

> The only problem is code duplication in many-many places.

+1

What about print signed value, so it will be "-1 UNKNOWN", not too bad as log
but concern is if it is confusing again?

> May be add simple function in ethdev to do it and use it in
> all examples?
> 
> Please, wait more feedback before doing it.
>

^ permalink raw reply	[flat|nested] 359+ messages in thread

* Re: [dpdk-dev] [PATCH v1 0/6] ethdev: allow unknown link speed
  2020-04-27  9:57                       ` [dpdk-dev] [PATCH v1 0/6] ethdev: allow unknown link speed Ivan Dyukov
                                           ` (5 preceding siblings ...)
       [not found]                         ` <CGME20200427095800eucas1p16c30ec18649efe66b831728fe661703f@eucas1p1.samsung.com>
@ 2020-05-06 17:42                         ` Ferruh Yigit
  2020-05-07  8:53                           ` Ivan Dyukov
       [not found]                         ` <CGME20200526191045eucas1p2291305a5c7a7d59070af6330db52765c@eucas1p2.samsung.com>
                                           ` (9 subsequent siblings)
  16 siblings, 1 reply; 359+ messages in thread
From: Ferruh Yigit @ 2020-05-06 17:42 UTC (permalink / raw)
  To: 4816966.qqrk5fENW1, dev, i.dyukov, v.kuramshin, thomas,
	david.marchand, arybchenko

On 4/27/2020 10:57 AM, Ivan Dyukov wrote:
> This is initial patchset which introduces UNKNOWN speed to dpdk
> applications. Also it contains changes related to printf formating.
> Patchset contains changes for app/ and doc/ folders.
> examples/ folder will be provided later.
> 
> 

Also I can see there are some physical PMDs that are using 'ETH_SPEED_NUM_NONE'
as unknown, can we fix them as part of this set?


^ permalink raw reply	[flat|nested] 359+ messages in thread

* Re: [dpdk-dev] [PATCH v1 0/6] ethdev: allow unknown link speed
  2020-05-06 17:42                         ` [dpdk-dev] [PATCH v1 0/6] ethdev: allow unknown link speed Ferruh Yigit
@ 2020-05-07  8:53                           ` Ivan Dyukov
  2020-05-07 10:31                             ` Thomas Monjalon
  0 siblings, 1 reply; 359+ messages in thread
From: Ivan Dyukov @ 2020-05-07  8:53 UTC (permalink / raw)
  To: Ferruh Yigit, thomas; +Cc: dev, v.kuramshin, david.marchand, arybchenko

06.05.2020 20:42, Ferruh Yigit пишет:
> On 4/27/2020 10:57 AM, Ivan Dyukov wrote:
>> This is initial patchset which introduces UNKNOWN speed to dpdk
>> applications. Also it contains changes related to printf formating.
>> Patchset contains changes for app/ and doc/ folders.
>> examples/ folder will be provided later.
>>
>>
> Also I can see there are some physical PMDs that are using 'ETH_SPEED_NUM_NONE'
> as unknown, can we fix them as part of this set?
>
Initially, we had a plan to use UNKNOWN only for virtual devices.

Thomas, could you please comment this?



^ permalink raw reply	[flat|nested] 359+ messages in thread

* Re: [dpdk-dev] [PATCH v1 3/6] ethdev: remove extra 'new line' in output
  2020-05-01 13:15                             ` Andrew Rybchenko
@ 2020-05-07 10:28                               ` Thomas Monjalon
  2020-05-07 15:15                                 ` Ivan Dyukov
       [not found]                                 ` <CGME20200507182612eucas1p10d955ce6857f01fd85a5268d10edc489@eucas1p1.samsung.com>
  0 siblings, 2 replies; 359+ messages in thread
From: Thomas Monjalon @ 2020-05-07 10:28 UTC (permalink / raw)
  To: i.dyukov, Andrew Rybchenko; +Cc: dev, v.kuramshin, david.marchand, ferruh.yigit

01/05/2020 15:15, Andrew Rybchenko:
> On 4/27/20 12:57 PM, Ivan Dyukov wrote:
> > Signed-off-by: Ivan Dyukov <i.dyukov@samsung.com>
> > ---
> >   app/test-pmd/testpmd.c   | 2 +-
> >   app/test/test_pmd_perf.c | 2 +-
> >   2 files changed, 2 insertions(+), 2 deletions(-)
> > 
> > diff --git a/app/test-pmd/testpmd.c b/app/test-pmd/testpmd.c
> > index 99bacddbf..d4df23a93 100644
> > --- a/app/test-pmd/testpmd.c
> > +++ b/app/test-pmd/testpmd.c
> > @@ -3005,7 +3005,7 @@ check_all_ports_link_status(uint32_t port_mask)
> >   					"Port%d Link Up. speed %u Mbps- %s\n",
> >   					portid, link.link_speed,
> >   				(link.link_duplex == ETH_LINK_FULL_DUPLEX) ?
> > -					("full-duplex") : ("half-duplex\n"));
> > +					("full-duplex") : ("half-duplex"));
> >   				else
> >   					printf("Port %d Link Down\n", portid);
> >   				continue;
> > diff --git a/app/test/test_pmd_perf.c b/app/test/test_pmd_perf.c
> > index d61be58bb..352cd4715 100644
> > --- a/app/test/test_pmd_perf.c
> > +++ b/app/test/test_pmd_perf.c
> > @@ -151,7 +151,7 @@ check_all_ports_link_status(uint16_t port_num, uint32_t port_mask)
> >   					"Port%d Link Up. Speed %u Mbps - %s\n",
> >   						portid, link.link_speed,
> >   				(link.link_duplex == ETH_LINK_FULL_DUPLEX) ?
> > -					("full-duplex") : ("half-duplex\n"));
> > +					("full-duplex") : ("half-duplex"));
> >   					if (link_mbps == 0)
> >   						link_mbps = link.link_speed;
> >   				} else
> > 
> 
> 
> I think Fixes: tag is required here.
> 
> Acked-by: Andrew Rybchenko <arybchenko@solarflare.com>

Yes please, we would like to backport it.



^ permalink raw reply	[flat|nested] 359+ messages in thread

* Re: [dpdk-dev] [PATCH v1 0/6] ethdev: allow unknown link speed
  2020-05-07  8:53                           ` Ivan Dyukov
@ 2020-05-07 10:31                             ` Thomas Monjalon
  2020-05-07 13:55                               ` Ivan Dyukov
  0 siblings, 1 reply; 359+ messages in thread
From: Thomas Monjalon @ 2020-05-07 10:31 UTC (permalink / raw)
  To: Ferruh Yigit, Ivan Dyukov
  Cc: dev, v.kuramshin, david.marchand, arybchenko, matan

07/05/2020 10:53, Ivan Dyukov:
> 06.05.2020 20:42, Ferruh Yigit пишет:
> > On 4/27/2020 10:57 AM, Ivan Dyukov wrote:
> >> This is initial patchset which introduces UNKNOWN speed to dpdk
> >> applications. Also it contains changes related to printf formating.
> >> Patchset contains changes for app/ and doc/ folders.
> >> examples/ folder will be provided later.
> >>
> >>
> > Also I can see there are some physical PMDs that are using 'ETH_SPEED_NUM_NONE'
> > as unknown, can we fix them as part of this set?
> >
> Initially, we had a plan to use UNKNOWN only for virtual devices.
> 
> Thomas, could you please comment this?

No I think UNKNOWN must be used also for HW devices which are not able
to provide a speed value.

In mlx5 case, it can be used to return the link status (up/down)
even if speed query is failing (it happens with buggy kernel version).



^ permalink raw reply	[flat|nested] 359+ messages in thread

* Re: [dpdk-dev] [PATCH v1 0/6] ethdev: allow unknown link speed
  2020-05-07 10:31                             ` Thomas Monjalon
@ 2020-05-07 13:55                               ` Ivan Dyukov
  2020-05-07 14:08                                 ` Ferruh Yigit
  0 siblings, 1 reply; 359+ messages in thread
From: Ivan Dyukov @ 2020-05-07 13:55 UTC (permalink / raw)
  To: Thomas Monjalon, Ferruh Yigit
  Cc: dev, v.kuramshin, david.marchand, arybchenko, matan

07.05.2020 13:31, Thomas Monjalon пишет:
> 07/05/2020 10:53, Ivan Dyukov:
>> 06.05.2020 20:42, Ferruh Yigit пишет:
>>> On 4/27/2020 10:57 AM, Ivan Dyukov wrote:
>>>> This is initial patchset which introduces UNKNOWN speed to dpdk
>>>> applications. Also it contains changes related to printf formating.
>>>> Patchset contains changes for app/ and doc/ folders.
>>>> examples/ folder will be provided later.
>>>>
>>>>
>>> Also I can see there are some physical PMDs that are using 'ETH_SPEED_NUM_NONE'
>>> as unknown, can we fix them as part of this set?
>>>
>> Initially, we had a plan to use UNKNOWN only for virtual devices.
>>
>> Thomas, could you please comment this?
> No I think UNKNOWN must be used also for HW devices which are not able
> to provide a speed value.
>
> In mlx5 case, it can be used to return the link status (up/down)
> even if speed query is failing (it happens with buggy kernel version).
>
Ok.  Is ETH_SPEED_NUM_NONE still needed then?  could it be replaced by 
UNKNOWN everywhere?
>


^ permalink raw reply	[flat|nested] 359+ messages in thread

* Re: [dpdk-dev] [PATCH v1 0/6] ethdev: allow unknown link speed
  2020-05-07 13:55                               ` Ivan Dyukov
@ 2020-05-07 14:08                                 ` Ferruh Yigit
  0 siblings, 0 replies; 359+ messages in thread
From: Ferruh Yigit @ 2020-05-07 14:08 UTC (permalink / raw)
  To: Ivan Dyukov, Thomas Monjalon
  Cc: dev, v.kuramshin, david.marchand, arybchenko, matan

On 5/7/2020 2:55 PM, Ivan Dyukov wrote:
> 07.05.2020 13:31, Thomas Monjalon пишет:
>> 07/05/2020 10:53, Ivan Dyukov:
>>> 06.05.2020 20:42, Ferruh Yigit пишет:
>>>> On 4/27/2020 10:57 AM, Ivan Dyukov wrote:
>>>>> This is initial patchset which introduces UNKNOWN speed to dpdk
>>>>> applications. Also it contains changes related to printf formating.
>>>>> Patchset contains changes for app/ and doc/ folders.
>>>>> examples/ folder will be provided later.
>>>>>
>>>>>
>>>> Also I can see there are some physical PMDs that are using 'ETH_SPEED_NUM_NONE'
>>>> as unknown, can we fix them as part of this set?
>>>>
>>> Initially, we had a plan to use UNKNOWN only for virtual devices.
>>>
>>> Thomas, could you please comment this?
>> No I think UNKNOWN must be used also for HW devices which are not able
>> to provide a speed value.
>>
>> In mlx5 case, it can be used to return the link status (up/down)
>> even if speed query is failing (it happens with buggy kernel version).
>>
> Ok.  Is ETH_SPEED_NUM_NONE still needed then?  could it be replaced by 
> UNKNOWN everywhere?

It is needed, please don't replace it.

For example when the link is down, device speed is 'ETH_SPEED_NUM_NONE', but
when the link is up but driver doesn't know the speed, for some reason, device
speed is 'ETH_SPEED_NUM_UNKNOWN'.

First patch says 'ETH_SPEED_NUM_UNKNOWN' is for two cases:
	- speed is not known by the driver
	- device is virtual

We are talking about first case above.


^ permalink raw reply	[flat|nested] 359+ messages in thread

* Re: [dpdk-dev] [PATCH v1 3/6] ethdev: remove extra 'new line' in output
  2020-05-07 10:28                               ` Thomas Monjalon
@ 2020-05-07 15:15                                 ` Ivan Dyukov
       [not found]                                 ` <CGME20200507182612eucas1p10d955ce6857f01fd85a5268d10edc489@eucas1p1.samsung.com>
  1 sibling, 0 replies; 359+ messages in thread
From: Ivan Dyukov @ 2020-05-07 15:15 UTC (permalink / raw)
  To: Thomas Monjalon, Andrew Rybchenko
  Cc: dev, v.kuramshin, david.marchand, ferruh.yigit

07.05.2020 13:28, Thomas Monjalon пишет:
> 01/05/2020 15:15, Andrew Rybchenko:
>> On 4/27/20 12:57 PM, Ivan Dyukov wrote:
>>> Signed-off-by: Ivan Dyukov <i.dyukov@samsung.com>
>>> ---
>>>    app/test-pmd/testpmd.c   | 2 +-
>>>    app/test/test_pmd_perf.c | 2 +-
>>>    2 files changed, 2 insertions(+), 2 deletions(-)
>>>
>>> diff --git a/app/test-pmd/testpmd.c b/app/test-pmd/testpmd.c
>>> index 99bacddbf..d4df23a93 100644
>>> --- a/app/test-pmd/testpmd.c
>>> +++ b/app/test-pmd/testpmd.c
>>> @@ -3005,7 +3005,7 @@ check_all_ports_link_status(uint32_t port_mask)
>>>    					"Port%d Link Up. speed %u Mbps- %s\n",
>>>    					portid, link.link_speed,
>>>    				(link.link_duplex == ETH_LINK_FULL_DUPLEX) ?
>>> -					("full-duplex") : ("half-duplex\n"));
>>> +					("full-duplex") : ("half-duplex"));
>>>    				else
>>>    					printf("Port %d Link Down\n", portid);
>>>    				continue;
>>> diff --git a/app/test/test_pmd_perf.c b/app/test/test_pmd_perf.c
>>> index d61be58bb..352cd4715 100644
>>> --- a/app/test/test_pmd_perf.c
>>> +++ b/app/test/test_pmd_perf.c
>>> @@ -151,7 +151,7 @@ check_all_ports_link_status(uint16_t port_num, uint32_t port_mask)
>>>    					"Port%d Link Up. Speed %u Mbps - %s\n",
>>>    						portid, link.link_speed,
>>>    				(link.link_duplex == ETH_LINK_FULL_DUPLEX) ?
>>> -					("full-duplex") : ("half-duplex\n"));
>>> +					("full-duplex") : ("half-duplex"));
>>>    					if (link_mbps == 0)
>>>    						link_mbps = link.link_speed;
>>>    				} else
>>>
>>
>> I think Fixes: tag is required here.
>>
>> Acked-by: Andrew Rybchenko <arybchenko@solarflare.com>
> Yes please, we would like to backport it.
>
>
>
Ok. I'll make separate patch for that.  There are about 24 same 
'copy/paste' in example folder.



^ permalink raw reply	[flat|nested] 359+ messages in thread

* [dpdk-dev] [PATCH v1 1/3] ethdev: remove extra 'new line' in output
       [not found]                                 ` <CGME20200507182612eucas1p10d955ce6857f01fd85a5268d10edc489@eucas1p1.samsung.com>
@ 2020-05-07 18:26                                   ` " Ivan Dyukov
       [not found]                                     ` <CGME20200507182615eucas1p10a1ad94553507df541e2c43cf952722b@eucas1p1.samsung.com>
                                                       ` (2 more replies)
  0 siblings, 3 replies; 359+ messages in thread
From: Ivan Dyukov @ 2020-05-07 18:26 UTC (permalink / raw)
  To: dev, i.dyukov, v.kuramshin, thomas, david.marchand, ferruh.yigit,
	arybchenko
  Cc: stable

This is testpmd part of new line cleanup

Fixes: 002ade70e9 (app/test: measure cycles per packet in Rx/Tx)
Fixes: ce8d561418 (app/testpmd: add port configuration settings)
Cc: stable@dpdk.org

Acked-by: Andrew Rybchenko <arybchenko@solarflare.com>
Signed-off-by: Ivan Dyukov <i.dyukov@samsung.com>
---
 app/test-pmd/testpmd.c   | 2 +-
 app/test/test_pmd_perf.c | 2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/app/test-pmd/testpmd.c b/app/test-pmd/testpmd.c
index 99bacddbf..d4df23a93 100644
--- a/app/test-pmd/testpmd.c
+++ b/app/test-pmd/testpmd.c
@@ -3005,7 +3005,7 @@ check_all_ports_link_status(uint32_t port_mask)
 					"Port%d Link Up. speed %u Mbps- %s\n",
 					portid, link.link_speed,
 				(link.link_duplex == ETH_LINK_FULL_DUPLEX) ?
-					("full-duplex") : ("half-duplex\n"));
+					("full-duplex") : ("half-duplex"));
 				else
 					printf("Port %d Link Down\n", portid);
 				continue;
diff --git a/app/test/test_pmd_perf.c b/app/test/test_pmd_perf.c
index d61be58bb..352cd4715 100644
--- a/app/test/test_pmd_perf.c
+++ b/app/test/test_pmd_perf.c
@@ -151,7 +151,7 @@ check_all_ports_link_status(uint16_t port_num, uint32_t port_mask)
 					"Port%d Link Up. Speed %u Mbps - %s\n",
 						portid, link.link_speed,
 				(link.link_duplex == ETH_LINK_FULL_DUPLEX) ?
-					("full-duplex") : ("half-duplex\n"));
+					("full-duplex") : ("half-duplex"));
 					if (link_mbps == 0)
 						link_mbps = link.link_speed;
 				} else
-- 
2.17.1


^ permalink raw reply	[flat|nested] 359+ messages in thread

* [dpdk-dev] [PATCH v1 2/3] examples: remove extra 'new line' in output
       [not found]                                     ` <CGME20200507182615eucas1p10a1ad94553507df541e2c43cf952722b@eucas1p1.samsung.com>
@ 2020-05-07 18:26                                       ` " Ivan Dyukov
  0 siblings, 0 replies; 359+ messages in thread
From: Ivan Dyukov @ 2020-05-07 18:26 UTC (permalink / raw)
  To: dev, i.dyukov, v.kuramshin, thomas, david.marchand, ferruh.yigit,
	arybchenko
  Cc: stable

This patch removes extra 'new line' in few app examples

Fixes: d3641ae863 (examples: update link status checks)
Cc: stable@dpdk.org

Signed-off-by: Ivan Dyukov <i.dyukov@samsung.com>
---
 examples/ip_fragmentation/main.c                         | 2 +-
 examples/ipv4_multicast/main.c                           | 2 +-
 examples/l2fwd/main.c                                    | 2 +-
 examples/l3fwd/main.c                                    | 2 +-
 examples/link_status_interrupt/main.c                    | 2 +-
 examples/multi_process/client_server_mp/mp_server/init.c | 2 +-
 examples/multi_process/symmetric_mp/main.c               | 2 +-
 7 files changed, 7 insertions(+), 7 deletions(-)

diff --git a/examples/ip_fragmentation/main.c b/examples/ip_fragmentation/main.c
index 5eca7ba99..4afb97109 100644
--- a/examples/ip_fragmentation/main.c
+++ b/examples/ip_fragmentation/main.c
@@ -617,7 +617,7 @@ check_all_ports_link_status(uint32_t port_mask)
 					"Port%d Link Up .Speed %u Mbps - %s\n",
 						portid, link.link_speed,
 				(link.link_duplex == ETH_LINK_FULL_DUPLEX) ?
-					("full-duplex") : ("half-duplex\n"));
+					("full-duplex") : ("half-duplex"));
 				else
 					printf("Port %d Link Down\n", portid);
 				continue;
diff --git a/examples/ipv4_multicast/main.c b/examples/ipv4_multicast/main.c
index 1fb28513b..7e255c35a 100644
--- a/examples/ipv4_multicast/main.c
+++ b/examples/ipv4_multicast/main.c
@@ -596,7 +596,7 @@ check_all_ports_link_status(uint32_t port_mask)
 					"Port%d Link Up. Speed %u Mbps - %s\n",
 					portid, link.link_speed,
 				(link.link_duplex == ETH_LINK_FULL_DUPLEX) ?
-					("full-duplex") : ("half-duplex\n"));
+					("full-duplex") : ("half-duplex"));
 				else
 					printf("Port %d Link Down\n", portid);
 				continue;
diff --git a/examples/l2fwd/main.c b/examples/l2fwd/main.c
index 88ddfe589..f8d14b843 100644
--- a/examples/l2fwd/main.c
+++ b/examples/l2fwd/main.c
@@ -478,7 +478,7 @@ check_all_ports_link_status(uint32_t port_mask)
 					"Port%d Link Up. Speed %u Mbps - %s\n",
 						portid, link.link_speed,
 				(link.link_duplex == ETH_LINK_FULL_DUPLEX) ?
-					("full-duplex") : ("half-duplex\n"));
+					("full-duplex") : ("half-duplex"));
 				else
 					printf("Port %d Link Down\n", portid);
 				continue;
diff --git a/examples/l3fwd/main.c b/examples/l3fwd/main.c
index dda430d68..84f171f18 100644
--- a/examples/l3fwd/main.c
+++ b/examples/l3fwd/main.c
@@ -838,7 +838,7 @@ check_all_ports_link_status(uint32_t port_mask)
 					"Port%d Link Up. Speed %u Mbps -%s\n",
 						portid, link.link_speed,
 				(link.link_duplex == ETH_LINK_FULL_DUPLEX) ?
-					("full-duplex") : ("half-duplex\n"));
+					("full-duplex") : ("half-duplex"));
 				else
 					printf("Port %d Link Down\n", portid);
 				continue;
diff --git a/examples/link_status_interrupt/main.c b/examples/link_status_interrupt/main.c
index 38422f6ac..25efe2b09 100644
--- a/examples/link_status_interrupt/main.c
+++ b/examples/link_status_interrupt/main.c
@@ -500,7 +500,7 @@ check_all_ports_link_status(uint16_t port_num, uint32_t port_mask)
 					"Port%d Link Up. Speed %u Mbps - %s\n",
 						portid, link.link_speed,
 				(link.link_duplex == ETH_LINK_FULL_DUPLEX) ?
-					("full-duplex") : ("half-duplex\n"));
+					("full-duplex") : ("half-duplex"));
 				else
 					printf("Port %d Link Down\n", portid);
 				continue;
diff --git a/examples/multi_process/client_server_mp/mp_server/init.c b/examples/multi_process/client_server_mp/mp_server/init.c
index ad9f46f0a..c2ec07ac6 100644
--- a/examples/multi_process/client_server_mp/mp_server/init.c
+++ b/examples/multi_process/client_server_mp/mp_server/init.c
@@ -209,7 +209,7 @@ check_all_ports_link_status(uint16_t port_num, uint32_t port_mask)
 						"Mbps - %s\n", ports->id[portid],
 						(unsigned)link.link_speed,
 				(link.link_duplex == ETH_LINK_FULL_DUPLEX) ?
-					("full-duplex") : ("half-duplex\n"));
+					("full-duplex") : ("half-duplex"));
 				else
 					printf("Port %d Link Down\n",
 						(uint8_t)ports->id[portid]);
diff --git a/examples/multi_process/symmetric_mp/main.c b/examples/multi_process/symmetric_mp/main.c
index 522f211c0..9a16e198c 100644
--- a/examples/multi_process/symmetric_mp/main.c
+++ b/examples/multi_process/symmetric_mp/main.c
@@ -389,7 +389,7 @@ check_all_ports_link_status(uint16_t port_num, uint32_t port_mask)
 					"Port%d Link Up. Speed %u Mbps - %s\n",
 						portid, link.link_speed,
 				(link.link_duplex == ETH_LINK_FULL_DUPLEX) ?
-					("full-duplex") : ("half-duplex\n"));
+					("full-duplex") : ("half-duplex"));
 				else
 					printf("Port %d Link Down\n", portid);
 				continue;
-- 
2.17.1


^ permalink raw reply	[flat|nested] 359+ messages in thread

* [dpdk-dev] [PATCH v1 3/3] examples: remove extra 'new line' in output
       [not found]                                     ` <CGME20200507182616eucas1p2b6d7e7ac68b1b0fe8b1d71dd112fcc9d@eucas1p2.samsung.com>
@ 2020-05-07 18:26                                       ` " Ivan Dyukov
  0 siblings, 0 replies; 359+ messages in thread
From: Ivan Dyukov @ 2020-05-07 18:26 UTC (permalink / raw)
  To: dev, i.dyukov, v.kuramshin, thomas, david.marchand, ferruh.yigit,
	arybchenko
  Cc: stable

This patch removes extra 'new line' in few app examples

Fixes: d299106e8e (examples/ipsec-secgw: add IPsec sample application)
Fixes: d48415e1fe (examples/performance-thread: add l3fwd-thread app)
Fixes: 3fc5ca2f63 (kni: initial import)
Fixes: 387259bd6c (examples/l2fwd-crypto: add sample application)
Fixes: 20c78ac9ee (examples/vm_power_mgr: add port initialisation)
Fixes: e64833f227 (examples/l2fwd-keepalive: add sample application)
Fixes: de3cfa2c98 (sched: initial import)
Fixes: d7937e2e3d (power: initial import)
Fixes: 204896f8d6 (examples/l2fwd-jobstats: add new example)
Fixes: 4ff457986f (examples/l2fwd-event: add default poll mode routines)
Fixes: 39aad0e88c (examples/flow_distributor: new example to demonstrate EFD)
Fixes: c8e6ceeceb (examples/ioat: add new sample app for ioat driver)
Fixes: 361b2e9559 (acl: new sample l3fwd-acl)
Fixes: cc8f4d020c (examples/ip_reassembly: initial import)
Cc: stable@dpdk.org

Signed-off-by: Ivan Dyukov <i.dyukov@samsung.com>
---
 examples/ioat/ioatfwd.c                         | 2 +-
 examples/ip_reassembly/main.c                   | 2 +-
 examples/ipsec-secgw/ipsec-secgw.c              | 2 +-
 examples/kni/main.c                             | 2 +-
 examples/l2fwd-crypto/main.c                    | 2 +-
 examples/l2fwd-event/main.c                     | 2 +-
 examples/l2fwd-jobstats/main.c                  | 2 +-
 examples/l2fwd-keepalive/main.c                 | 2 +-
 examples/l3fwd-acl/main.c                       | 2 +-
 examples/l3fwd-power/main.c                     | 2 +-
 examples/performance-thread/l3fwd-thread/main.c | 2 +-
 examples/qos_sched/init.c                       | 2 +-
 examples/server_node_efd/server/init.c          | 2 +-
 examples/vm_power_manager/main.c                | 2 +-
 14 files changed, 14 insertions(+), 14 deletions(-)

diff --git a/examples/ioat/ioatfwd.c b/examples/ioat/ioatfwd.c
index 7255ff3c9..53de23179 100644
--- a/examples/ioat/ioatfwd.c
+++ b/examples/ioat/ioatfwd.c
@@ -718,7 +718,7 @@ check_link_status(uint32_t port_mask)
 				"Port %d Link Up. Speed %u Mbps - %s\n",
 				portid, link.link_speed,
 				(link.link_duplex == ETH_LINK_FULL_DUPLEX) ?
-				("full-duplex") : ("half-duplex\n"));
+				("full-duplex") : ("half-duplex"));
 			link_status = 1;
 		} else
 			printf("Port %d Link Down\n", portid);
diff --git a/examples/ip_reassembly/main.c b/examples/ip_reassembly/main.c
index e34d8f0e1..494d7ee77 100644
--- a/examples/ip_reassembly/main.c
+++ b/examples/ip_reassembly/main.c
@@ -736,7 +736,7 @@ check_all_ports_link_status(uint32_t port_mask)
 					"Port%d Link Up. Speed %u Mbps - %s\n",
 						portid, link.link_speed,
 				(link.link_duplex == ETH_LINK_FULL_DUPLEX) ?
-					("full-duplex") : ("half-duplex\n"));
+					("full-duplex") : ("half-duplex"));
 				else
 					printf("Port %d Link Down\n", portid);
 				continue;
diff --git a/examples/ipsec-secgw/ipsec-secgw.c b/examples/ipsec-secgw/ipsec-secgw.c
index 6d02341de..5b3690ce9 100644
--- a/examples/ipsec-secgw/ipsec-secgw.c
+++ b/examples/ipsec-secgw/ipsec-secgw.c
@@ -1800,7 +1800,7 @@ check_all_ports_link_status(uint32_t port_mask)
 					"Port%d Link Up - speed %u Mbps -%s\n",
 						portid, link.link_speed,
 				(link.link_duplex == ETH_LINK_FULL_DUPLEX) ?
-					("full-duplex") : ("half-duplex\n"));
+					("full-duplex") : ("half-duplex"));
 				else
 					printf("Port %d Link Down\n", portid);
 				continue;
diff --git a/examples/kni/main.c b/examples/kni/main.c
index 29fc37e1f..6b4ab3b5b 100644
--- a/examples/kni/main.c
+++ b/examples/kni/main.c
@@ -683,7 +683,7 @@ check_all_ports_link_status(uint32_t port_mask)
 					"Port%d Link Up - speed %uMbps - %s\n",
 						portid, link.link_speed,
 				(link.link_duplex == ETH_LINK_FULL_DUPLEX) ?
-					("full-duplex") : ("half-duplex\n"));
+					("full-duplex") : ("half-duplex"));
 				else
 					printf("Port %d Link Down\n", portid);
 				continue;
diff --git a/examples/l2fwd-crypto/main.c b/examples/l2fwd-crypto/main.c
index 61d78295d..fcb55c370 100644
--- a/examples/l2fwd-crypto/main.c
+++ b/examples/l2fwd-crypto/main.c
@@ -1756,7 +1756,7 @@ check_all_ports_link_status(uint32_t port_mask)
 					"Port%d Link Up. Speed %u Mbps - %s\n",
 						portid, link.link_speed,
 				(link.link_duplex == ETH_LINK_FULL_DUPLEX) ?
-					("full-duplex") : ("half-duplex\n"));
+					("full-duplex") : ("half-duplex"));
 				else
 					printf("Port %d Link Down\n", portid);
 				continue;
diff --git a/examples/l2fwd-event/main.c b/examples/l2fwd-event/main.c
index 9cc29d732..9593ef11e 100644
--- a/examples/l2fwd-event/main.c
+++ b/examples/l2fwd-event/main.c
@@ -394,7 +394,7 @@ check_all_ports_link_status(struct l2fwd_resources *rsrc,
 					"Port%d Link Up. Speed %u Mbps - %s\n",
 						port_id, link.link_speed,
 				(link.link_duplex == ETH_LINK_FULL_DUPLEX) ?
-					("full-duplex") : ("half-duplex\n"));
+					("full-duplex") : ("half-duplex"));
 				else
 					printf("Port %d Link Down\n", port_id);
 				continue;
diff --git a/examples/l2fwd-jobstats/main.c b/examples/l2fwd-jobstats/main.c
index c1ca100ed..396fd89db 100644
--- a/examples/l2fwd-jobstats/main.c
+++ b/examples/l2fwd-jobstats/main.c
@@ -710,7 +710,7 @@ check_all_ports_link_status(uint32_t port_mask)
 					"Port%d Link Up. Speed %u Mbps - %s\n",
 						portid, link.link_speed,
 				(link.link_duplex == ETH_LINK_FULL_DUPLEX) ?
-					("full-duplex") : ("half-duplex\n"));
+					("full-duplex") : ("half-duplex"));
 				else
 					printf("Port %d Link Down\n", portid);
 				continue;
diff --git a/examples/l2fwd-keepalive/main.c b/examples/l2fwd-keepalive/main.c
index 2ae5a3c6a..3a6bf2e47 100644
--- a/examples/l2fwd-keepalive/main.c
+++ b/examples/l2fwd-keepalive/main.c
@@ -475,7 +475,7 @@ check_all_ports_link_status(uint32_t port_mask)
 					"Port%d Link Up. Speed %u Mbps - %s\n",
 						portid, link.link_speed,
 				(link.link_duplex == ETH_LINK_FULL_DUPLEX) ?
-					("full-duplex") : ("half-duplex\n"));
+					("full-duplex") : ("half-duplex"));
 				else
 					printf("Port %d Link Down\n", portid);
 				continue;
diff --git a/examples/l3fwd-acl/main.c b/examples/l3fwd-acl/main.c
index cccf81929..f22fca732 100644
--- a/examples/l3fwd-acl/main.c
+++ b/examples/l3fwd-acl/main.c
@@ -1839,7 +1839,7 @@ check_all_ports_link_status(uint32_t port_mask)
 					"Port%d Link Up. Speed %u Mbps %s\n",
 						portid, link.link_speed,
 				(link.link_duplex == ETH_LINK_FULL_DUPLEX) ?
-					("full-duplex") : ("half-duplex\n"));
+					("full-duplex") : ("half-duplex"));
 				else
 					printf("Port %d Link Down\n", portid);
 				continue;
diff --git a/examples/l3fwd-power/main.c b/examples/l3fwd-power/main.c
index 293b3da4a..c8339ee5a 100644
--- a/examples/l3fwd-power/main.c
+++ b/examples/l3fwd-power/main.c
@@ -1959,7 +1959,7 @@ check_all_ports_link_status(uint32_t port_mask)
 						"Mbps - %s\n", (uint8_t)portid,
 						(unsigned)link.link_speed,
 				(link.link_duplex == ETH_LINK_FULL_DUPLEX) ?
-					("full-duplex") : ("half-duplex\n"));
+					("full-duplex") : ("half-duplex"));
 				else
 					printf("Port %d Link Down\n",
 						(uint8_t)portid);
diff --git a/examples/performance-thread/l3fwd-thread/main.c b/examples/performance-thread/l3fwd-thread/main.c
index 43a5b9248..84c1d7b3a 100644
--- a/examples/performance-thread/l3fwd-thread/main.c
+++ b/examples/performance-thread/l3fwd-thread/main.c
@@ -3457,7 +3457,7 @@ check_all_ports_link_status(uint32_t port_mask)
 					"Port%d Link Up. Speed %u Mbps - %s\n",
 						portid, link.link_speed,
 				(link.link_duplex == ETH_LINK_FULL_DUPLEX) ?
-					("full-duplex") : ("half-duplex\n"));
+					("full-duplex") : ("half-duplex"));
 				else
 					printf("Port %d Link Down\n", portid);
 				continue;
diff --git a/examples/qos_sched/init.c b/examples/qos_sched/init.c
index 0a17e0d4d..9626c15b8 100644
--- a/examples/qos_sched/init.c
+++ b/examples/qos_sched/init.c
@@ -164,7 +164,7 @@ app_init_port(uint16_t portid, struct rte_mempool *mp)
 		printf(" Link Up - speed %u Mbps - %s\n",
 			(uint32_t) link.link_speed,
 			(link.link_duplex == ETH_LINK_FULL_DUPLEX) ?
-			("full-duplex") : ("half-duplex\n"));
+			("full-duplex") : ("half-duplex"));
 	} else {
 		printf(" Link Down\n");
 	}
diff --git a/examples/server_node_efd/server/init.c b/examples/server_node_efd/server/init.c
index 00e2e4059..378a74fa5 100644
--- a/examples/server_node_efd/server/init.c
+++ b/examples/server_node_efd/server/init.c
@@ -272,7 +272,7 @@ check_all_ports_link_status(uint16_t port_num, uint32_t port_mask)
 						info->id[portid],
 						link.link_speed,
 				(link.link_duplex == ETH_LINK_FULL_DUPLEX) ?
-					("full-duplex") : ("half-duplex\n"));
+					("full-duplex") : ("half-duplex"));
 				else
 					printf("Port %d Link Down\n",
 						info->id[portid]);
diff --git a/examples/vm_power_manager/main.c b/examples/vm_power_manager/main.c
index dc6afb132..273bfec29 100644
--- a/examples/vm_power_manager/main.c
+++ b/examples/vm_power_manager/main.c
@@ -272,7 +272,7 @@ check_all_ports_link_status(uint32_t port_mask)
 						"Mbps - %s\n", (uint16_t)portid,
 						(unsigned int)link.link_speed,
 				(link.link_duplex == ETH_LINK_FULL_DUPLEX) ?
-					("full-duplex") : ("half-duplex\n"));
+					("full-duplex") : ("half-duplex"));
 				else
 					printf("Port %d Link Down\n",
 						(uint16_t)portid);
-- 
2.17.1


^ permalink raw reply	[flat|nested] 359+ messages in thread

* Re: [dpdk-dev] [PATCH v1 1/3] ethdev: remove extra 'new line' in output
  2020-05-07 18:26                                   ` [dpdk-dev] [PATCH v1 1/3] " Ivan Dyukov
       [not found]                                     ` <CGME20200507182615eucas1p10a1ad94553507df541e2c43cf952722b@eucas1p1.samsung.com>
       [not found]                                     ` <CGME20200507182616eucas1p2b6d7e7ac68b1b0fe8b1d71dd112fcc9d@eucas1p2.samsung.com>
@ 2020-05-12  2:08                                     ` " Thomas Monjalon
  2 siblings, 0 replies; 359+ messages in thread
From: Thomas Monjalon @ 2020-05-12  2:08 UTC (permalink / raw)
  To: Ivan Dyukov
  Cc: dev, v.kuramshin, david.marchand, ferruh.yigit, arybchenko, stable

07/05/2020 20:26, Ivan Dyukov:
> This is testpmd part of new line cleanup
> 
> Fixes: 002ade70e9 (app/test: measure cycles per packet in Rx/Tx)
> Fixes: ce8d561418 (app/testpmd: add port configuration settings)
> Cc: stable@dpdk.org
> 
> Acked-by: Andrew Rybchenko <arybchenko@solarflare.com>
> Signed-off-by: Ivan Dyukov <i.dyukov@samsung.com>

Series applied, thanks




^ permalink raw reply	[flat|nested] 359+ messages in thread

* [dpdk-dev] [PATCH v2 0/7] ethdev: allow unknown link speed
       [not found]                         ` <CGME20200526191045eucas1p2291305a5c7a7d59070af6330db52765c@eucas1p2.samsung.com>
@ 2020-05-26 19:10                           ` " Ivan Dyukov
       [not found]                             ` <CGME20200526191048eucas1p2970aa70da22d080be6cc2554d5a7083b@eucas1p2.samsung.com>
                                               ` (6 more replies)
  0 siblings, 7 replies; 359+ messages in thread
From: Ivan Dyukov @ 2020-05-26 19:10 UTC (permalink / raw)
  To: dev, i.dyukov, v.kuramshin, thomas, david.marchand, ferruh.yigit,
	arybchenko, wei.zhao1, jia.guo, beilei.xing, qiming.yang,
	wenzhuo.lu

 app/proc-info/main.c                          | 15 +++++++++------
 app/test-pipeline/init.c                      | 11 ++++++-----
 app/test-pmd/config.c                         | 20 ++++++++++++--------
 app/test-pmd/testpmd.c                        | 10 ++++++----
 app/test/test_pmd_perf.c                      | 10 ++++++----
 doc/guides/sample_app_ug/link_status_intr.rst |  6 ++++--
 drivers/net/i40e/i40e_ethdev.c                |  5 ++++-
 drivers/net/i40e/i40e_ethdev_vf.c             | 10 +++++-----
 drivers/net/ice/ice_ethdev.c                  |  5 ++++-
 drivers/net/ixgbe/ixgbe_ethdev.c              |  6 +-----
 lib/librte_ethdev/rte_ethdev.c                | 39 +++++++++++++++++++++++++++++++++++++++
 lib/librte_ethdev/rte_ethdev.h                | 51 +++++++++++++++++++++++++++++++++++++++++----------
 12 files changed, 137 insertions(+), 51 deletions(-)


v2 changes:
* add function which format link status to textual representation
* update drivers for Intel nics with 'unknown' speed
TBD:
update examples in 'example' folder with new status printing mechanism
update remaining nic drivers with 'unknown' speed

v1 changes:
This is initial patchset which introduces UNKNOWN speed to dpdk
applications. Also it contains changes related to printf formating.
Patchset contains changes for app/ and doc/ folders.
examples/ folder will be provided later.



^ permalink raw reply	[flat|nested] 359+ messages in thread

* [dpdk-dev] [PATCH v2 1/7] ethdev: allow unknown link speed
       [not found]                             ` <CGME20200526191048eucas1p2970aa70da22d080be6cc2554d5a7083b@eucas1p2.samsung.com>
@ 2020-05-26 19:10                               ` " Ivan Dyukov
  0 siblings, 0 replies; 359+ messages in thread
From: Ivan Dyukov @ 2020-05-26 19:10 UTC (permalink / raw)
  To: dev, i.dyukov, v.kuramshin, thomas, david.marchand, ferruh.yigit,
	arybchenko, wei.zhao1, jia.guo, beilei.xing, qiming.yang,
	wenzhuo.lu

From: Thomas Monjalon <thomas@monjalon.net>

When querying the link information, the link status is
a mandatory major information.
Other boolean values are supposed to be accurate:
	- duplex mode (half/full)
	- negotiation (auto/fixed)

This API update is making explicit that the link speed information
is optional.
The value ETH_SPEED_NUM_NONE (0) was already part of the API.
The value ETH_SPEED_NUM_UNKNOWN (infinite) is added to cover
two different cases:
	- speed is not known by the driver
	- device is virtual

Suggested-by: Morten Brørup <mb@smartsharesystems.com>
Suggested-by: Benoit Ganne <bganne@cisco.com>
Signed-off-by: Thomas Monjalon <thomas@monjalon.net>
---
 lib/librte_ethdev/rte_ethdev.h | 20 ++++++++++----------
 1 file changed, 10 insertions(+), 10 deletions(-)

diff --git a/lib/librte_ethdev/rte_ethdev.h b/lib/librte_ethdev/rte_ethdev.h
index a49242bcd..2090af501 100644
--- a/lib/librte_ethdev/rte_ethdev.h
+++ b/lib/librte_ethdev/rte_ethdev.h
@@ -303,6 +303,7 @@ struct rte_eth_stats {
 #define ETH_SPEED_NUM_56G      56000 /**<  56 Gbps */
 #define ETH_SPEED_NUM_100G    100000 /**< 100 Gbps */
 #define ETH_SPEED_NUM_200G    200000 /**< 200 Gbps */
+#define ETH_SPEED_NUM_UNKNOWN UINT32_MAX /**< Unknown */
 
 /**
  * A structure used to retrieve link-level information of an Ethernet port.
@@ -2262,15 +2263,16 @@ int rte_eth_allmulticast_disable(uint16_t port_id);
 int rte_eth_allmulticast_get(uint16_t port_id);
 
 /**
- * Retrieve the status (ON/OFF), the speed (in Mbps) and the mode (HALF-DUPLEX
- * or FULL-DUPLEX) of the physical link of an Ethernet device. It might need
- * to wait up to 9 seconds in it.
+ * Retrieve the link status (up/down), the duplex mode (half/full),
+ * the negotiation (auto/fixed), and if available, the speed (Mbps).
+ *
+ * It might need to wait up to 9 seconds.
+ * @see rte_eth_link_get_nowait.
  *
  * @param port_id
  *   The port identifier of the Ethernet device.
  * @param link
- *   A pointer to an *rte_eth_link* structure to be filled with
- *   the status, the speed and the mode of the Ethernet device link.
+ *   Link information written back.
  * @return
  *   - (0) if successful.
  *   - (-ENOTSUP) if the function is not supported in PMD driver.
@@ -2279,15 +2281,13 @@ int rte_eth_allmulticast_get(uint16_t port_id);
 int rte_eth_link_get(uint16_t port_id, struct rte_eth_link *link);
 
 /**
- * Retrieve the status (ON/OFF), the speed (in Mbps) and the mode (HALF-DUPLEX
- * or FULL-DUPLEX) of the physical link of an Ethernet device. It is a no-wait
- * version of rte_eth_link_get().
+ * Retrieve the link status (up/down), the duplex mode (half/full),
+ * the negotiation (auto/fixed), and if available, the speed (Mbps).
  *
  * @param port_id
  *   The port identifier of the Ethernet device.
  * @param link
- *   A pointer to an *rte_eth_link* structure to be filled with
- *   the status, the speed and the mode of the Ethernet device link.
+ *   Link information written back.
  * @return
  *   - (0) if successful.
  *   - (-ENOTSUP) if the function is not supported in PMD driver.
-- 
2.17.1


^ permalink raw reply	[flat|nested] 359+ messages in thread

* [dpdk-dev] [PATCH v2 2/7] ethdev: add a link status text representation
       [not found]                             ` <CGME20200526191050eucas1p16311d491af2d7640553aced2e55ac83a@eucas1p1.samsung.com>
@ 2020-05-26 19:10                               ` Ivan Dyukov
  2020-05-27  7:45                                 ` [dpdk-dev] [PATCH v2 2/7] ethdev: add a link status textrepresentation Morten Brørup
  0 siblings, 1 reply; 359+ messages in thread
From: Ivan Dyukov @ 2020-05-26 19:10 UTC (permalink / raw)
  To: dev, i.dyukov, v.kuramshin, thomas, david.marchand, ferruh.yigit,
	arybchenko, wei.zhao1, jia.guo, beilei.xing, qiming.yang,
	wenzhuo.lu

This commit add function which treat link status structure
and format it to text representation.

Signed-off-by: Ivan Dyukov <i.dyukov@samsung.com>
---
 lib/librte_ethdev/rte_ethdev.c | 39 ++++++++++++++++++++++++++++++++++
 lib/librte_ethdev/rte_ethdev.h | 31 +++++++++++++++++++++++++++
 2 files changed, 70 insertions(+)

diff --git a/lib/librte_ethdev/rte_ethdev.c b/lib/librte_ethdev/rte_ethdev.c
index 8e10a6fc3..8d75c2440 100644
--- a/lib/librte_ethdev/rte_ethdev.c
+++ b/lib/librte_ethdev/rte_ethdev.c
@@ -2385,6 +2385,45 @@ rte_eth_link_get_nowait(uint16_t port_id, struct rte_eth_link *eth_link)
 	return 0;
 }
 
+void
+rte_eth_link_prepare_text(struct rte_eth_link *eth_link, uint32_t speed_unit,
+			  struct rte_eth_link_text *link_text)
+{
+	uint32_t link_speed = 0;
+	/* prepare link speed */
+	if (eth_link->link_speed == ETH_SPEED_NUM_UNKNOWN)
+		memcpy(link_text->link_speed, "unknown", sizeof("unknown"));
+	else {
+		if (speed_unit == ETH_SPEED_UNIT_GBPS)
+			link_speed = eth_link->link_speed / 1000;
+		else
+			link_speed = eth_link->link_speed;
+		snprintf(link_text->link_speed, sizeof(link_text->link_speed),
+			 "%u", link_speed);
+	}
+	/* prepare link duplex */
+	if (eth_link->link_duplex == ETH_LINK_FULL_DUPLEX)
+		memcpy(link_text->link_duplex, "full-duplex",
+			sizeof("full-duplex"));
+	else
+		memcpy(link_text->link_duplex, "half-duplex",
+			sizeof("half-duplex"));
+	/* prepare autoneg */
+	if (eth_link->link_autoneg == ETH_LINK_AUTONEG)
+		memcpy(link_text->link_autoneg, "autoneg",
+			sizeof("autoneg"));
+	else
+		memcpy(link_text->link_autoneg, "fixed",
+			sizeof("fixed"));
+	/* prepare status */
+	if (eth_link->link_status == ETH_LINK_DOWN)
+		memcpy(link_text->link_status, "down",
+			sizeof("down"));
+	else
+		memcpy(link_text->link_status, "up",
+			sizeof("up"));
+}
+
 int
 rte_eth_stats_get(uint16_t port_id, struct rte_eth_stats *stats)
 {
diff --git a/lib/librte_ethdev/rte_ethdev.h b/lib/librte_ethdev/rte_ethdev.h
index 2090af501..53d2f0c78 100644
--- a/lib/librte_ethdev/rte_ethdev.h
+++ b/lib/librte_ethdev/rte_ethdev.h
@@ -316,6 +316,19 @@ struct rte_eth_link {
 	uint16_t link_status  : 1;  /**< ETH_LINK_[DOWN/UP] */
 } __rte_aligned(8);      /**< aligned for atomic64 read/write */
 
+/**
+ * Link speed units
+ */
+#define ETH_SPEED_UNIT_GBPS 0
+#define ETH_SPEED_UNIT_MBPS 1
+
+
+struct rte_eth_link_text {
+	char link_speed[14];  /** link speed */
+	char link_duplex[12];  /** full-duplex or half-duplex */
+	char link_autoneg[8];  /** autoneg or fixed */
+	char link_status[5];  /** down or up */
+};
 /* Utility constants */
 #define ETH_LINK_HALF_DUPLEX 0 /**< Half-duplex connection (see link_duplex). */
 #define ETH_LINK_FULL_DUPLEX 1 /**< Full-duplex connection (see link_duplex). */
@@ -2295,6 +2308,24 @@ int rte_eth_link_get(uint16_t port_id, struct rte_eth_link *link);
  */
 int rte_eth_link_get_nowait(uint16_t port_id, struct rte_eth_link *link);
 
+/**
+ * Format link status to textual representation. speed_unit is used to convert
+ * link_speed to specified unit. Also this function threats a special
+ * ETH_SPEED_NUM_UNKNOWN value of link_speed and return 'UNKNOWN' speed
+ * in this case.
+ *
+ * @param link
+ *   Link status provided by rte_eth_link_get function
+ * @param speed_unit
+ *   Target units for the speed. Following values are available:
+ *    - ETH_SPEED_UNIT_GBPS
+ *    - ETH_SPEED_UNIT_MBPS
+ * @param link_text
+ *   A pointer to an *rte_eth_link_text* structure to be filled with
+ *   textual representation of device status
+ */
+void rte_eth_link_prepare_text(struct rte_eth_link *link, uint32_t speed_unit,
+				struct rte_eth_link_text *link_text);
 /**
  * Retrieve the general I/O statistics of an Ethernet device.
  *
-- 
2.17.1


^ permalink raw reply	[flat|nested] 359+ messages in thread

* [dpdk-dev] [PATCH v2 3/7] app: UNKNOWN link speed print format
       [not found]                             ` <CGME20200526191052eucas1p2c53ca292499647dce2360fbe328c4521@eucas1p2.samsung.com>
@ 2020-05-26 19:10                               ` Ivan Dyukov
  0 siblings, 0 replies; 359+ messages in thread
From: Ivan Dyukov @ 2020-05-26 19:10 UTC (permalink / raw)
  To: dev, i.dyukov, v.kuramshin, thomas, david.marchand, ferruh.yigit,
	arybchenko, wei.zhao1, jia.guo, beilei.xing, qiming.yang,
	wenzhuo.lu

Add usage of rte_eth_link_prepare_text function to example
applications

Signed-off-by: Ivan Dyukov <i.dyukov@samsung.com>
---
 app/proc-info/main.c     | 15 +++++++++------
 app/test-pipeline/init.c | 11 ++++++-----
 app/test-pmd/config.c    | 20 ++++++++++++--------
 app/test-pmd/testpmd.c   | 10 ++++++----
 app/test/test_pmd_perf.c | 10 ++++++----
 5 files changed, 39 insertions(+), 27 deletions(-)

diff --git a/app/proc-info/main.c b/app/proc-info/main.c
index abeca4aab..d8506cbb2 100644
--- a/app/proc-info/main.c
+++ b/app/proc-info/main.c
@@ -669,6 +669,7 @@ show_port(void)
 	RTE_ETH_FOREACH_DEV(i) {
 		uint16_t mtu = 0;
 		struct rte_eth_link link;
+		struct rte_eth_link_text link_text;
 		struct rte_eth_dev_info dev_info;
 		struct rte_eth_rxq_info queue_info;
 		struct rte_eth_rss_conf rss_conf;
@@ -685,12 +686,14 @@ show_port(void)
 			printf("Link get failed (port %u): %s\n",
 			       i, rte_strerror(-ret));
 		} else {
-			printf("\t  -- link speed %d duplex %d,"
-					" auto neg %d status %d\n",
-					link.link_speed,
-					link.link_duplex,
-					link.link_autoneg,
-					link.link_status);
+			rte_eth_link_prepare_text(&link,
+				ETH_SPEED_UNIT_MBPS, &link_text);
+			printf("\t  -- link speed: %s, duplex: %s,"
+					" auto neg: %s, status: %s\n",
+					link_text.link_speed,
+					link_text.link_duplex,
+					link_text.link_autoneg,
+					link_text.link_status);
 		}
 		printf("\t  -- promiscuous (%d)\n",
 				rte_eth_promiscuous_get(i));
diff --git a/app/test-pipeline/init.c b/app/test-pipeline/init.c
index 67d54ae05..920023825 100644
--- a/app/test-pipeline/init.c
+++ b/app/test-pipeline/init.c
@@ -160,6 +160,7 @@ app_ports_check_link(void)
 
 	for (i = 0; i < app.n_ports; i++) {
 		struct rte_eth_link link;
+		struct rte_eth_link_text link_text;
 		uint16_t port;
 		int ret;
 
@@ -173,12 +174,12 @@ app_ports_check_link(void)
 			all_ports_up = 0;
 			continue;
 		}
-
-		RTE_LOG(INFO, USER1, "Port %u (%u Gbps) %s\n",
+		rte_eth_link_prepare_text(&link,
+			ETH_SPEED_UNIT_GBPS, &link_text);
+		RTE_LOG(INFO, USER1, "Port %u (%s Gbps) %s\n",
 			port,
-			link.link_speed / 1000,
-			link.link_status ? "UP" : "DOWN");
-
+			link_text.link_speed,
+			link_text.link_status);
 		if (link.link_status == ETH_LINK_DOWN)
 			all_ports_up = 0;
 	}
diff --git a/app/test-pmd/config.c b/app/test-pmd/config.c
index 5381207cc..722f57c12 100644
--- a/app/test-pmd/config.c
+++ b/app/test-pmd/config.c
@@ -552,6 +552,7 @@ port_infos_display(portid_t port_id)
 	struct rte_port *port;
 	struct rte_ether_addr mac_addr;
 	struct rte_eth_link link;
+	struct rte_eth_link_text link_text;
 	struct rte_eth_dev_info dev_info;
 	int vlan_offload;
 	struct rte_mempool * mp;
@@ -600,10 +601,10 @@ port_infos_display(portid_t port_id)
 	} else
 		printf("\nmemory allocation on the socket: %u",port->socket_id);
 
-	printf("\nLink status: %s\n", (link.link_status) ? ("up") : ("down"));
-	printf("Link speed: %u Mbps\n", (unsigned) link.link_speed);
-	printf("Link duplex: %s\n", (link.link_duplex == ETH_LINK_FULL_DUPLEX) ?
-	       ("full-duplex") : ("half-duplex"));
+	rte_eth_link_prepare_text(&link, ETH_SPEED_UNIT_MBPS, &link_text);
+	printf("\nLink status: %s\n", link_text.link_status);
+	printf("Link speed: %s Mbps\n", link_text.link_speed);
+	printf("Link duplex: %s\n", link_text.link_duplex);
 
 	if (!rte_eth_dev_get_mtu(port_id, &mtu))
 		printf("MTU: %u\n", mtu);
@@ -724,6 +725,7 @@ port_summary_display(portid_t port_id)
 {
 	struct rte_ether_addr mac_addr;
 	struct rte_eth_link link;
+	struct rte_eth_link_text link_text;
 	struct rte_eth_dev_info dev_info;
 	char name[RTE_ETH_NAME_MAX_LEN];
 	int ret;
@@ -746,12 +748,14 @@ port_summary_display(portid_t port_id)
 	if (ret != 0)
 		return;
 
-	printf("%-4d %02X:%02X:%02X:%02X:%02X:%02X %-12s %-14s %-8s %uMbps\n",
+	rte_eth_link_prepare_text(&link, ETH_SPEED_UNIT_GBPS,
+					&link_text);
+	printf("%-4d %02X:%02X:%02X:%02X:%02X:%02X %-12s %-14s %-8s %sMbps\n",
 		port_id, mac_addr.addr_bytes[0], mac_addr.addr_bytes[1],
 		mac_addr.addr_bytes[2], mac_addr.addr_bytes[3],
 		mac_addr.addr_bytes[4], mac_addr.addr_bytes[5], name,
-		dev_info.driver_name, (link.link_status) ? ("up") : ("down"),
-		(unsigned int) link.link_speed);
+		dev_info.driver_name, link_text.link_status,
+		link_text.link_speed);
 }
 
 void
@@ -3897,7 +3901,7 @@ set_queue_rate_limit(portid_t port_id, uint16_t queue_idx, uint16_t rate)
 	ret = eth_link_get_nowait_print_err(port_id, &link);
 	if (ret < 0)
 		return 1;
-	if (rate > link.link_speed) {
+	if (link.link_speed != UINT32_MAX && rate > link.link_speed) {
 		printf("Invalid rate value:%u bigger than link speed: %u\n",
 			rate, link.link_speed);
 		return 1;
diff --git a/app/test-pmd/testpmd.c b/app/test-pmd/testpmd.c
index 9cbe6e9f6..fd78e1cea 100644
--- a/app/test-pmd/testpmd.c
+++ b/app/test-pmd/testpmd.c
@@ -2987,6 +2987,7 @@ check_all_ports_link_status(uint32_t port_mask)
 	portid_t portid;
 	uint8_t count, all_ports_up, print_flag = 0;
 	struct rte_eth_link link;
+	struct rte_eth_link_text link_text;
 	int ret;
 
 	printf("Checking link statuses...\n");
@@ -3007,12 +3008,13 @@ check_all_ports_link_status(uint32_t port_mask)
 			}
 			/* print link status if flag set */
 			if (print_flag == 1) {
+				rte_eth_link_prepare_text(&link,
+					ETH_SPEED_UNIT_MBPS, &link_text);
 				if (link.link_status)
 					printf(
-					"Port%d Link Up. speed %u Mbps- %s\n",
-					portid, link.link_speed,
-				(link.link_duplex == ETH_LINK_FULL_DUPLEX) ?
-					("full-duplex") : ("half-duplex"));
+					"Port%d Link Up. speed %s Mbps- %s\n",
+					portid, link_text.link_speed,
+					link_text.link_duplex);
 				else
 					printf("Port %d Link Down\n", portid);
 				continue;
diff --git a/app/test/test_pmd_perf.c b/app/test/test_pmd_perf.c
index 352cd4715..9a275287b 100644
--- a/app/test/test_pmd_perf.c
+++ b/app/test/test_pmd_perf.c
@@ -125,6 +125,7 @@ check_all_ports_link_status(uint16_t port_num, uint32_t port_mask)
 	uint16_t portid;
 	uint8_t count, all_ports_up, print_flag = 0;
 	struct rte_eth_link link;
+	struct rte_eth_link_text link_text;
 	int ret;
 
 	printf("Checking link statuses...\n");
@@ -147,11 +148,12 @@ check_all_ports_link_status(uint16_t port_num, uint32_t port_mask)
 			/* print link status if flag set */
 			if (print_flag == 1) {
 				if (link.link_status) {
+					rte_eth_link_prepare_text(&link,
+					ETH_SPEED_UNIT_MBPS, &link_text);
 					printf(
-					"Port%d Link Up. Speed %u Mbps - %s\n",
-						portid, link.link_speed,
-				(link.link_duplex == ETH_LINK_FULL_DUPLEX) ?
-					("full-duplex") : ("half-duplex"));
+					"Port%d Link Up. Speed %s Mbps - %s\n",
+						portid, link_text.link_speed,
+						link_text.link_duplex);
 					if (link_mbps == 0)
 						link_mbps = link.link_speed;
 				} else
-- 
2.17.1


^ permalink raw reply	[flat|nested] 359+ messages in thread

* [dpdk-dev] [PATCH v2 4/7] doc: update sample app with unknown speed
       [not found]                             ` <CGME20200526191054eucas1p27defd4f1d656f07f1d9d5a95be369de9@eucas1p2.samsung.com>
@ 2020-05-26 19:10                               ` Ivan Dyukov
  0 siblings, 0 replies; 359+ messages in thread
From: Ivan Dyukov @ 2020-05-26 19:10 UTC (permalink / raw)
  To: dev, i.dyukov, v.kuramshin, thomas, david.marchand, ferruh.yigit,
	arybchenko, wei.zhao1, jia.guo, beilei.xing, qiming.yang,
	wenzhuo.lu

Add usage of rte_eth_link_prepare_text function to example
applications

Signed-off-by: Ivan Dyukov <i.dyukov@samsung.com>
---
 doc/guides/sample_app_ug/link_status_intr.rst | 6 ++++--
 1 file changed, 4 insertions(+), 2 deletions(-)

diff --git a/doc/guides/sample_app_ug/link_status_intr.rst b/doc/guides/sample_app_ug/link_status_intr.rst
index 04c40f285..bdefcd17b 100644
--- a/doc/guides/sample_app_ug/link_status_intr.rst
+++ b/doc/guides/sample_app_ug/link_status_intr.rst
@@ -157,6 +157,7 @@ An example callback function that has been written as indicated below.
     lsi_event_callback(uint16_t port_id, enum rte_eth_event_type type, void *param)
     {
         struct rte_eth_link link;
+        struct rte_eth_link_text link_text;
         int ret;
 
         RTE_SET_USED(param);
@@ -170,8 +171,9 @@ An example callback function that has been written as indicated below.
             printf("Failed to get port %d link status: %s\n\n",
                    port_id, rte_strerror(-ret));
         } else if (link.link_status) {
-            printf("Port %d Link Up - speed %u Mbps - %s\n\n", port_id, (unsigned)link.link_speed,
-                  (link.link_duplex == ETH_LINK_FULL_DUPLEX) ? ("full-duplex") : ("half-duplex"));
+            rte_eth_link_prepare_text(&link), ETH_SPEED_UNIT_MBPS, &link_text);
+            printf("Port %d Link Up - speed %s Mbps - %s\n\n", port_id, link_text.link_speed,
+                  link_text.link_duplex);
         } else
             printf("Port %d Link Down\n\n", port_id);
     }
-- 
2.17.1


^ permalink raw reply	[flat|nested] 359+ messages in thread

* [dpdk-dev] [PATCH v2 5/7] net/ixgbe: return unknown speed in status
       [not found]                             ` <CGME20200526191056eucas1p2985e531db4a95745ca70e0bc4e9d6cdb@eucas1p2.samsung.com>
@ 2020-05-26 19:10                               ` Ivan Dyukov
  0 siblings, 0 replies; 359+ messages in thread
From: Ivan Dyukov @ 2020-05-26 19:10 UTC (permalink / raw)
  To: dev, i.dyukov, v.kuramshin, thomas, david.marchand, ferruh.yigit,
	arybchenko, wei.zhao1, jia.guo, beilei.xing, qiming.yang,
	wenzhuo.lu

rte_ethdev has declared new NUM_UNKNOWN speed which
could be used in case when no speed information is available

Signed-off-by: Ivan Dyukov <i.dyukov@samsung.com>
---
 drivers/net/ixgbe/ixgbe_ethdev.c | 6 +-----
 1 file changed, 1 insertion(+), 5 deletions(-)

diff --git a/drivers/net/ixgbe/ixgbe_ethdev.c b/drivers/net/ixgbe/ixgbe_ethdev.c
index a4e5c539d..5b9b13058 100644
--- a/drivers/net/ixgbe/ixgbe_ethdev.c
+++ b/drivers/net/ixgbe/ixgbe_ethdev.c
@@ -4311,11 +4311,7 @@ ixgbe_dev_link_update_share(struct rte_eth_dev *dev,
 	switch (link_speed) {
 	default:
 	case IXGBE_LINK_SPEED_UNKNOWN:
-		if (hw->device_id == IXGBE_DEV_ID_X550EM_A_1G_T ||
-			hw->device_id == IXGBE_DEV_ID_X550EM_A_1G_T_L)
-			link.link_speed = ETH_SPEED_NUM_10M;
-		else
-			link.link_speed = ETH_SPEED_NUM_100M;
+		link.link_speed = ETH_SPEED_NUM_UNKNOWN;
 		break;
 
 	case IXGBE_LINK_SPEED_100_FULL:
-- 
2.17.1


^ permalink raw reply	[flat|nested] 359+ messages in thread

* [dpdk-dev] [PATCH v2 6/7] net/i40e: return unknown speed in status
       [not found]                             ` <CGME20200526191058eucas1p11a8a5007144ba3b0e66ab1286a85c84b@eucas1p1.samsung.com>
@ 2020-05-26 19:10                               ` " Ivan Dyukov
  0 siblings, 0 replies; 359+ messages in thread
From: Ivan Dyukov @ 2020-05-26 19:10 UTC (permalink / raw)
  To: dev, i.dyukov, v.kuramshin, thomas, david.marchand, ferruh.yigit,
	arybchenko, wei.zhao1, jia.guo, beilei.xing, qiming.yang,
	wenzhuo.lu

rte_ethdev has declared new NUM_UNKNOWN speed which
could be used in case when no speed information is available and
link is up. NUM_NONE should be returned, if link is down.

Signed-off-by: Ivan Dyukov <i.dyukov@samsung.com>
---
 drivers/net/i40e/i40e_ethdev.c    |  5 ++++-
 drivers/net/i40e/i40e_ethdev_vf.c | 10 +++++-----
 2 files changed, 9 insertions(+), 6 deletions(-)

diff --git a/drivers/net/i40e/i40e_ethdev.c b/drivers/net/i40e/i40e_ethdev.c
index 749d85f54..d09b77674 100644
--- a/drivers/net/i40e/i40e_ethdev.c
+++ b/drivers/net/i40e/i40e_ethdev.c
@@ -2889,7 +2889,10 @@ update_link_aq(struct i40e_hw *hw, struct rte_eth_link *link,
 		link->link_speed = ETH_SPEED_NUM_40G;
 		break;
 	default:
-		link->link_speed = ETH_SPEED_NUM_NONE;
+		if (link->link_status)
+			link->link_speed = ETH_SPEED_NUM_UNKNOWN;
+		else
+			link->link_speed = ETH_SPEED_NUM_NONE;
 		break;
 	}
 }
diff --git a/drivers/net/i40e/i40e_ethdev_vf.c b/drivers/net/i40e/i40e_ethdev_vf.c
index bb5d28a44..1da185485 100644
--- a/drivers/net/i40e/i40e_ethdev_vf.c
+++ b/drivers/net/i40e/i40e_ethdev_vf.c
@@ -2165,15 +2165,15 @@ i40evf_dev_link_update(struct rte_eth_dev *dev,
 		new_link.link_speed = ETH_SPEED_NUM_40G;
 		break;
 	default:
-		new_link.link_speed = ETH_SPEED_NUM_NONE;
+		if (vf->link_up)
+			new_link.link_speed = ETH_SPEED_NUM_UNKNOWN;
+		else
+			new_link.link_speed = ETH_SPEED_NUM_NONE;
 		break;
 	}
 	/* full duplex only */
 	new_link.link_duplex = ETH_LINK_FULL_DUPLEX;
-	new_link.link_status = vf->link_up &&
-				new_link.link_speed != ETH_SPEED_NUM_NONE
-				? ETH_LINK_UP
-				: ETH_LINK_DOWN;
+	new_link.link_status = vf->link_up ? ETH_LINK_UP : ETH_LINK_DOWN;
 	new_link.link_autoneg =
 		!(dev->data->dev_conf.link_speeds & ETH_LINK_SPEED_FIXED);
 
-- 
2.17.1


^ permalink raw reply	[flat|nested] 359+ messages in thread

* [dpdk-dev] [PATCH v2 7/7] net/ice: return unknown speed in status
       [not found]                             ` <CGME20200526191100eucas1p2505b82b041fdb64fd2ceceadd67749dc@eucas1p2.samsung.com>
@ 2020-05-26 19:10                               ` " Ivan Dyukov
  0 siblings, 0 replies; 359+ messages in thread
From: Ivan Dyukov @ 2020-05-26 19:10 UTC (permalink / raw)
  To: dev, i.dyukov, v.kuramshin, thomas, david.marchand, ferruh.yigit,
	arybchenko, wei.zhao1, jia.guo, beilei.xing, qiming.yang,
	wenzhuo.lu

rte_ethdev has declared new NUM_UNKNOWN speed which
could be used in case when no speed information is available and
link is up. NUM_NONE should be returned, if link is down.

Signed-off-by: Ivan Dyukov <i.dyukov@samsung.com>
---
 drivers/net/ice/ice_ethdev.c | 5 ++++-
 1 file changed, 4 insertions(+), 1 deletion(-)

diff --git a/drivers/net/ice/ice_ethdev.c b/drivers/net/ice/ice_ethdev.c
index d5110c439..1c0c087ea 100644
--- a/drivers/net/ice/ice_ethdev.c
+++ b/drivers/net/ice/ice_ethdev.c
@@ -3112,8 +3112,11 @@ ice_link_update(struct rte_eth_dev *dev, int wait_to_complete)
 		link.link_speed = ETH_SPEED_NUM_100G;
 		break;
 	case ICE_AQ_LINK_SPEED_UNKNOWN:
-	default:
 		PMD_DRV_LOG(ERR, "Unknown link speed");
+		link.link_speed = ETH_SPEED_NUM_UNKNOWN;
+		break;
+	default:
+		PMD_DRV_LOG(ERR, "None link speed");
 		link.link_speed = ETH_SPEED_NUM_NONE;
 		break;
 	}
-- 
2.17.1


^ permalink raw reply	[flat|nested] 359+ messages in thread

* Re: [dpdk-dev] [PATCH v2 2/7] ethdev: add a link status textrepresentation
  2020-05-26 19:10                               ` [dpdk-dev] [PATCH v2 2/7] ethdev: add a link status text representation Ivan Dyukov
@ 2020-05-27  7:45                                 ` Morten Brørup
  2020-05-27 14:53                                   ` Stephen Hemminger
  2020-06-05 11:45                                   ` Ferruh Yigit
  0 siblings, 2 replies; 359+ messages in thread
From: Morten Brørup @ 2020-05-27  7:45 UTC (permalink / raw)
  To: i.dyukov
  Cc: dev, v.kuramshin, thomas, david.marchand, ferruh.yigit,
	arybchenko, wei.zhao1, jia.guo, beilei.xing, qiming.yang,
	wenzhuo.lu

> From: dev [mailto:dev-bounces@dpdk.org] On Behalf Of Ivan Dyukov
> Sent: Tuesday, May 26, 2020 9:10 PM
> 
> This commit add function which treat link status structure
> and format it to text representation.
> 
> Signed-off-by: Ivan Dyukov <i.dyukov@samsung.com>
> ---
>  lib/librte_ethdev/rte_ethdev.c | 39 ++++++++++++++++++++++++++++++++++
>  lib/librte_ethdev/rte_ethdev.h | 31 +++++++++++++++++++++++++++
>  2 files changed, 70 insertions(+)
> 
> diff --git a/lib/librte_ethdev/rte_ethdev.c
> b/lib/librte_ethdev/rte_ethdev.c
> index 8e10a6fc3..8d75c2440 100644
> --- a/lib/librte_ethdev/rte_ethdev.c
> +++ b/lib/librte_ethdev/rte_ethdev.c
> @@ -2385,6 +2385,45 @@ rte_eth_link_get_nowait(uint16_t port_id, struct
> rte_eth_link *eth_link)
>  	return 0;
>  }
> 
> +void
> +rte_eth_link_prepare_text(struct rte_eth_link *eth_link, uint32_t
> speed_unit,
> +			  struct rte_eth_link_text *link_text)
> +{
> +	uint32_t link_speed = 0;
> +	/* prepare link speed */
> +	if (eth_link->link_speed == ETH_SPEED_NUM_UNKNOWN)
> +		memcpy(link_text->link_speed, "unknown",
> sizeof("unknown"));
> +	else {
> +		if (speed_unit == ETH_SPEED_UNIT_GBPS)
> +			link_speed = eth_link->link_speed / 1000;
> +		else
> +			link_speed = eth_link->link_speed;
> +		snprintf(link_text->link_speed, sizeof(link_text-
> >link_speed),
> +			 "%u", link_speed);
> +	}
> +	/* prepare link duplex */
> +	if (eth_link->link_duplex == ETH_LINK_FULL_DUPLEX)
> +		memcpy(link_text->link_duplex, "full-duplex",
> +			sizeof("full-duplex"));
> +	else
> +		memcpy(link_text->link_duplex, "half-duplex",
> +			sizeof("half-duplex"));
> +	/* prepare autoneg */
> +	if (eth_link->link_autoneg == ETH_LINK_AUTONEG)
> +		memcpy(link_text->link_autoneg, "autoneg",
> +			sizeof("autoneg"));
> +	else
> +		memcpy(link_text->link_autoneg, "fixed",
> +			sizeof("fixed"));
> +	/* prepare status */
> +	if (eth_link->link_status == ETH_LINK_DOWN)
> +		memcpy(link_text->link_status, "down",
> +			sizeof("down"));
> +	else
> +		memcpy(link_text->link_status, "up",
> +			sizeof("up"));
> +}
> +
>  int
>  rte_eth_stats_get(uint16_t port_id, struct rte_eth_stats *stats)
>  {
> diff --git a/lib/librte_ethdev/rte_ethdev.h
> b/lib/librte_ethdev/rte_ethdev.h
> index 2090af501..53d2f0c78 100644
> --- a/lib/librte_ethdev/rte_ethdev.h
> +++ b/lib/librte_ethdev/rte_ethdev.h
> @@ -316,6 +316,19 @@ struct rte_eth_link {
>  	uint16_t link_status  : 1;  /**< ETH_LINK_[DOWN/UP] */
>  } __rte_aligned(8);      /**< aligned for atomic64 read/write */
> 
> +/**
> + * Link speed units
> + */
> +#define ETH_SPEED_UNIT_GBPS 0
> +#define ETH_SPEED_UNIT_MBPS 1
> +
> +
> +struct rte_eth_link_text {
> +	char link_speed[14];  /** link speed */
> +	char link_duplex[12];  /** full-duplex or half-duplex */
> +	char link_autoneg[8];  /** autoneg or fixed */
> +	char link_status[5];  /** down or up */
> +};
>  /* Utility constants */
>  #define ETH_LINK_HALF_DUPLEX 0 /**< Half-duplex connection (see
> link_duplex). */
>  #define ETH_LINK_FULL_DUPLEX 1 /**< Full-duplex connection (see
> link_duplex). */
> @@ -2295,6 +2308,24 @@ int rte_eth_link_get(uint16_t port_id, struct
> rte_eth_link *link);
>   */
>  int rte_eth_link_get_nowait(uint16_t port_id, struct rte_eth_link
> *link);
> 
> +/**
> + * Format link status to textual representation. speed_unit is used to
> convert
> + * link_speed to specified unit. Also this function threats a special
> + * ETH_SPEED_NUM_UNKNOWN value of link_speed and return 'UNKNOWN'
> speed
> + * in this case.
> + *
> + * @param link
> + *   Link status provided by rte_eth_link_get function
> + * @param speed_unit
> + *   Target units for the speed. Following values are available:
> + *    - ETH_SPEED_UNIT_GBPS
> + *    - ETH_SPEED_UNIT_MBPS
> + * @param link_text
> + *   A pointer to an *rte_eth_link_text* structure to be filled with
> + *   textual representation of device status
> + */
> +void rte_eth_link_prepare_text(struct rte_eth_link *link, uint32_t
> speed_unit,
> +				struct rte_eth_link_text *link_text);
>  /**
>   * Retrieve the general I/O statistics of an Ethernet device.
>   *
> --
> 2.17.1
> 

Considering that this function will only be used by applications that don't need to follow a vendor-specific textual format for their link status, you can choose your own text format, and don't need the struct for the text strings. The function can simply write the entire information into a single string. It also makes speed_unit superfluous. E.g. like this:

void rte_eth_link_prepare_text(char *str, const struct rte_eth_link *const link)
{
    if (link.link_status == ETH_LINK_DOWN) {
        str += sprintf(str, "Link down");
    } else {
        str += sprintf(str, "Link up at ");
        if (link.link_speed == ETH_SPEED_NUM_UNKNOWN) {
            str += sprintf("Unknown speed");
        } else {
            if (link.link_speed < ETH_SPEED_NUM_1G)
                str += sprintf(str, "%u Mbit/s", link.link_speed);
            else if (link.link_speed == ETH_SPEED_NUM_2_5G)
                str += sprintf(str, "2.5 Gbit/s");
            else
                str += sprintf(str, "%u Gbit/s", link.link_speed / 1000);
            str += sprintf(str, " %cDX", link.link_duplex ? 'F' : 'H');
            str += sprintf(str, " %s", link.link_autoneg ? "Autoneg" : "Fixed");
        }
    }
}


And if DPDK already has an established style for "convert information to human readable text" functions regarding function name and parameter order, the function should follow such style.


Med venlig hilsen / kind regards
- Morten Brørup


^ permalink raw reply	[flat|nested] 359+ messages in thread

* Re: [dpdk-dev] [PATCH v2 2/7] ethdev: add a link status textrepresentation
  2020-05-27  7:45                                 ` [dpdk-dev] [PATCH v2 2/7] ethdev: add a link status textrepresentation Morten Brørup
@ 2020-05-27 14:53                                   ` Stephen Hemminger
  2020-06-05 11:45                                   ` Ferruh Yigit
  1 sibling, 0 replies; 359+ messages in thread
From: Stephen Hemminger @ 2020-05-27 14:53 UTC (permalink / raw)
  To: Morten Brørup
  Cc: i.dyukov, dev, v.kuramshin, thomas, david.marchand, ferruh.yigit,
	arybchenko, wei.zhao1, jia.guo, beilei.xing, qiming.yang,
	wenzhuo.lu

On Wed, 27 May 2020 09:45:49 +0200
Morten Brørup <mb@smartsharesystems.com> wrote:

> void rte_eth_link_prepare_text(char *str, const struct rte_eth_link *const link)
> {
>     if (link.link_status == ETH_LINK_DOWN) {
>         str += sprintf(str, "Link down");
>     } else {
>         str += sprintf(str, "Link up at ");
>         if (link.link_speed == ETH_SPEED_NUM_UNKNOWN) {
>             str += sprintf("Unknown speed");
>         } else {
>             if (link.link_speed < ETH_SPEED_NUM_1G)
>                 str += sprintf(str, "%u Mbit/s", link.link_speed);
>             else if (link.link_speed == ETH_SPEED_NUM_2_5G)
>                 str += sprintf(str, "2.5 Gbit/s");
>             else
>                 str += sprintf(str, "%u Gbit/s", link.link_speed / 1000);
>             str += sprintf(str, " %cDX", link.link_duplex ? 'F' : 'H');
>             str += sprintf(str, " %s", link.link_autoneg ? "Autoneg" : "Fixed");
>         }
>     }
> }

Having a semi-standard link status text is good. This version of
the code needs work before it is ready.

Using sprintf() rather than snprintf() is going to upset the security folks.
The API must take string and length, or use asprintf();
You don't want to do last increment or Coverity will complain about useless assignment.

^ permalink raw reply	[flat|nested] 359+ messages in thread

* Re: [dpdk-dev] [PATCH v2 2/7] ethdev: add a link status textrepresentation
  2020-05-27  7:45                                 ` [dpdk-dev] [PATCH v2 2/7] ethdev: add a link status textrepresentation Morten Brørup
  2020-05-27 14:53                                   ` Stephen Hemminger
@ 2020-06-05 11:45                                   ` Ferruh Yigit
  2020-06-08  7:22                                     ` Morten Brørup
  1 sibling, 1 reply; 359+ messages in thread
From: Ferruh Yigit @ 2020-06-05 11:45 UTC (permalink / raw)
  To: Morten Brørup, i.dyukov
  Cc: dev, v.kuramshin, thomas, david.marchand, arybchenko, wei.zhao1,
	jia.guo, beilei.xing, qiming.yang, wenzhuo.lu

On 5/27/2020 8:45 AM, Morten Brørup wrote:
>> From: dev [mailto:dev-bounces@dpdk.org] On Behalf Of Ivan Dyukov
>> Sent: Tuesday, May 26, 2020 9:10 PM
>>
>> This commit add function which treat link status structure
>> and format it to text representation.
>>
>> Signed-off-by: Ivan Dyukov <i.dyukov@samsung.com>
>> ---
>>  lib/librte_ethdev/rte_ethdev.c | 39 ++++++++++++++++++++++++++++++++++
>>  lib/librte_ethdev/rte_ethdev.h | 31 +++++++++++++++++++++++++++
>>  2 files changed, 70 insertions(+)
>>
>> diff --git a/lib/librte_ethdev/rte_ethdev.c
>> b/lib/librte_ethdev/rte_ethdev.c
>> index 8e10a6fc3..8d75c2440 100644
>> --- a/lib/librte_ethdev/rte_ethdev.c
>> +++ b/lib/librte_ethdev/rte_ethdev.c
>> @@ -2385,6 +2385,45 @@ rte_eth_link_get_nowait(uint16_t port_id, struct
>> rte_eth_link *eth_link)
>>  	return 0;
>>  }
>>
>> +void
>> +rte_eth_link_prepare_text(struct rte_eth_link *eth_link, uint32_t
>> speed_unit,
>> +			  struct rte_eth_link_text *link_text)
>> +{
>> +	uint32_t link_speed = 0;
>> +	/* prepare link speed */
>> +	if (eth_link->link_speed == ETH_SPEED_NUM_UNKNOWN)
>> +		memcpy(link_text->link_speed, "unknown",
>> sizeof("unknown"));
>> +	else {
>> +		if (speed_unit == ETH_SPEED_UNIT_GBPS)
>> +			link_speed = eth_link->link_speed / 1000;
>> +		else
>> +			link_speed = eth_link->link_speed;
>> +		snprintf(link_text->link_speed, sizeof(link_text-
>>> link_speed),
>> +			 "%u", link_speed);
>> +	}
>> +	/* prepare link duplex */
>> +	if (eth_link->link_duplex == ETH_LINK_FULL_DUPLEX)
>> +		memcpy(link_text->link_duplex, "full-duplex",
>> +			sizeof("full-duplex"));
>> +	else
>> +		memcpy(link_text->link_duplex, "half-duplex",
>> +			sizeof("half-duplex"));
>> +	/* prepare autoneg */
>> +	if (eth_link->link_autoneg == ETH_LINK_AUTONEG)
>> +		memcpy(link_text->link_autoneg, "autoneg",
>> +			sizeof("autoneg"));
>> +	else
>> +		memcpy(link_text->link_autoneg, "fixed",
>> +			sizeof("fixed"));
>> +	/* prepare status */
>> +	if (eth_link->link_status == ETH_LINK_DOWN)
>> +		memcpy(link_text->link_status, "down",
>> +			sizeof("down"));
>> +	else
>> +		memcpy(link_text->link_status, "up",
>> +			sizeof("up"));
>> +}
>> +
>>  int
>>  rte_eth_stats_get(uint16_t port_id, struct rte_eth_stats *stats)
>>  {
>> diff --git a/lib/librte_ethdev/rte_ethdev.h
>> b/lib/librte_ethdev/rte_ethdev.h
>> index 2090af501..53d2f0c78 100644
>> --- a/lib/librte_ethdev/rte_ethdev.h
>> +++ b/lib/librte_ethdev/rte_ethdev.h
>> @@ -316,6 +316,19 @@ struct rte_eth_link {
>>  	uint16_t link_status  : 1;  /**< ETH_LINK_[DOWN/UP] */
>>  } __rte_aligned(8);      /**< aligned for atomic64 read/write */
>>
>> +/**
>> + * Link speed units
>> + */
>> +#define ETH_SPEED_UNIT_GBPS 0
>> +#define ETH_SPEED_UNIT_MBPS 1
>> +
>> +
>> +struct rte_eth_link_text {
>> +	char link_speed[14];  /** link speed */
>> +	char link_duplex[12];  /** full-duplex or half-duplex */
>> +	char link_autoneg[8];  /** autoneg or fixed */
>> +	char link_status[5];  /** down or up */
>> +};
>>  /* Utility constants */
>>  #define ETH_LINK_HALF_DUPLEX 0 /**< Half-duplex connection (see
>> link_duplex). */
>>  #define ETH_LINK_FULL_DUPLEX 1 /**< Full-duplex connection (see
>> link_duplex). */
>> @@ -2295,6 +2308,24 @@ int rte_eth_link_get(uint16_t port_id, struct
>> rte_eth_link *link);
>>   */
>>  int rte_eth_link_get_nowait(uint16_t port_id, struct rte_eth_link
>> *link);
>>
>> +/**
>> + * Format link status to textual representation. speed_unit is used to
>> convert
>> + * link_speed to specified unit. Also this function threats a special
>> + * ETH_SPEED_NUM_UNKNOWN value of link_speed and return 'UNKNOWN'
>> speed
>> + * in this case.
>> + *
>> + * @param link
>> + *   Link status provided by rte_eth_link_get function
>> + * @param speed_unit
>> + *   Target units for the speed. Following values are available:
>> + *    - ETH_SPEED_UNIT_GBPS
>> + *    - ETH_SPEED_UNIT_MBPS
>> + * @param link_text
>> + *   A pointer to an *rte_eth_link_text* structure to be filled with
>> + *   textual representation of device status
>> + */
>> +void rte_eth_link_prepare_text(struct rte_eth_link *link, uint32_t
>> speed_unit,
>> +				struct rte_eth_link_text *link_text);
>>  /**
>>   * Retrieve the general I/O statistics of an Ethernet device.
>>   *
>> --
>> 2.17.1
>>
> 
> Considering that this function will only be used by applications that don't need to follow a vendor-specific textual format for their link status, you can choose your own text format, and don't need the struct for the text strings. The function can simply write the entire information into a single string. It also makes speed_unit superfluous. E.g. like this:
> 
> void rte_eth_link_prepare_text(char *str, const struct rte_eth_link *const link)
> {
>     if (link.link_status == ETH_LINK_DOWN) {
>         str += sprintf(str, "Link down");
>     } else {
>         str += sprintf(str, "Link up at ");
>         if (link.link_speed == ETH_SPEED_NUM_UNKNOWN) {
>             str += sprintf("Unknown speed");
>         } else {
>             if (link.link_speed < ETH_SPEED_NUM_1G)
>                 str += sprintf(str, "%u Mbit/s", link.link_speed);
>             else if (link.link_speed == ETH_SPEED_NUM_2_5G)
>                 str += sprintf(str, "2.5 Gbit/s");
>             else
>                 str += sprintf(str, "%u Gbit/s", link.link_speed / 1000);
>             str += sprintf(str, " %cDX", link.link_duplex ? 'F' : 'H');
>             str += sprintf(str, " %s", link.link_autoneg ? "Autoneg" : "Fixed");
>         }
>     }
> }
> 
> 
> And if DPDK already has an established style for "convert information to human readable text" functions regarding function name and parameter order, the function should follow such style.
> 

What about having them both, a per-formatted string that can make life easy for
applications, and struct for text strings for the apps need some granularity.


^ permalink raw reply	[flat|nested] 359+ messages in thread

* Re: [dpdk-dev] [PATCH v2 2/7] ethdev: add a link status textrepresentation
  2020-06-05 11:45                                   ` Ferruh Yigit
@ 2020-06-08  7:22                                     ` Morten Brørup
  0 siblings, 0 replies; 359+ messages in thread
From: Morten Brørup @ 2020-06-08  7:22 UTC (permalink / raw)
  To: Ferruh Yigit, i.dyukov
  Cc: dev, v.kuramshin, thomas, david.marchand, arybchenko, wei.zhao1,
	jia.guo, beilei.xing, qiming.yang, wenzhuo.lu

> From: dev [mailto:dev-bounces@dpdk.org] On Behalf Of Ferruh Yigit
> Sent: Friday, June 5, 2020 1:45 PM
> 
> On 5/27/2020 8:45 AM, Morten Brørup wrote:
> >> From: dev [mailto:dev-bounces@dpdk.org] On Behalf Of Ivan Dyukov
> >> Sent: Tuesday, May 26, 2020 9:10 PM
> >>
> >> This commit add function which treat link status structure
> >> and format it to text representation.
> >>
> >> Signed-off-by: Ivan Dyukov <i.dyukov@samsung.com>
> >> ---
> >>  lib/librte_ethdev/rte_ethdev.c | 39
> ++++++++++++++++++++++++++++++++++
> >>  lib/librte_ethdev/rte_ethdev.h | 31 +++++++++++++++++++++++++++
> >>  2 files changed, 70 insertions(+)
> >>
> >> diff --git a/lib/librte_ethdev/rte_ethdev.c
> >> b/lib/librte_ethdev/rte_ethdev.c
> >> index 8e10a6fc3..8d75c2440 100644
> >> --- a/lib/librte_ethdev/rte_ethdev.c
> >> +++ b/lib/librte_ethdev/rte_ethdev.c
> >> @@ -2385,6 +2385,45 @@ rte_eth_link_get_nowait(uint16_t port_id,
> struct
> >> rte_eth_link *eth_link)
> >>  	return 0;
> >>  }
> >>
> >> +void
> >> +rte_eth_link_prepare_text(struct rte_eth_link *eth_link, uint32_t
> >> speed_unit,
> >> +			  struct rte_eth_link_text *link_text)
> >> +{
> >> +	uint32_t link_speed = 0;
> >> +	/* prepare link speed */
> >> +	if (eth_link->link_speed == ETH_SPEED_NUM_UNKNOWN)
> >> +		memcpy(link_text->link_speed, "unknown",
> >> sizeof("unknown"));
> >> +	else {
> >> +		if (speed_unit == ETH_SPEED_UNIT_GBPS)
> >> +			link_speed = eth_link->link_speed / 1000;
> >> +		else
> >> +			link_speed = eth_link->link_speed;
> >> +		snprintf(link_text->link_speed, sizeof(link_text-
> >>> link_speed),
> >> +			 "%u", link_speed);
> >> +	}
> >> +	/* prepare link duplex */
> >> +	if (eth_link->link_duplex == ETH_LINK_FULL_DUPLEX)
> >> +		memcpy(link_text->link_duplex, "full-duplex",
> >> +			sizeof("full-duplex"));
> >> +	else
> >> +		memcpy(link_text->link_duplex, "half-duplex",
> >> +			sizeof("half-duplex"));
> >> +	/* prepare autoneg */
> >> +	if (eth_link->link_autoneg == ETH_LINK_AUTONEG)
> >> +		memcpy(link_text->link_autoneg, "autoneg",
> >> +			sizeof("autoneg"));
> >> +	else
> >> +		memcpy(link_text->link_autoneg, "fixed",
> >> +			sizeof("fixed"));
> >> +	/* prepare status */
> >> +	if (eth_link->link_status == ETH_LINK_DOWN)
> >> +		memcpy(link_text->link_status, "down",
> >> +			sizeof("down"));
> >> +	else
> >> +		memcpy(link_text->link_status, "up",
> >> +			sizeof("up"));
> >> +}
> >> +
> >>  int
> >>  rte_eth_stats_get(uint16_t port_id, struct rte_eth_stats *stats)
> >>  {
> >> diff --git a/lib/librte_ethdev/rte_ethdev.h
> >> b/lib/librte_ethdev/rte_ethdev.h
> >> index 2090af501..53d2f0c78 100644
> >> --- a/lib/librte_ethdev/rte_ethdev.h
> >> +++ b/lib/librte_ethdev/rte_ethdev.h
> >> @@ -316,6 +316,19 @@ struct rte_eth_link {
> >>  	uint16_t link_status  : 1;  /**< ETH_LINK_[DOWN/UP] */
> >>  } __rte_aligned(8);      /**< aligned for atomic64 read/write */
> >>
> >> +/**
> >> + * Link speed units
> >> + */
> >> +#define ETH_SPEED_UNIT_GBPS 0
> >> +#define ETH_SPEED_UNIT_MBPS 1
> >> +
> >> +
> >> +struct rte_eth_link_text {
> >> +	char link_speed[14];  /** link speed */
> >> +	char link_duplex[12];  /** full-duplex or half-duplex */
> >> +	char link_autoneg[8];  /** autoneg or fixed */
> >> +	char link_status[5];  /** down or up */
> >> +};
> >>  /* Utility constants */
> >>  #define ETH_LINK_HALF_DUPLEX 0 /**< Half-duplex connection (see
> >> link_duplex). */
> >>  #define ETH_LINK_FULL_DUPLEX 1 /**< Full-duplex connection (see
> >> link_duplex). */
> >> @@ -2295,6 +2308,24 @@ int rte_eth_link_get(uint16_t port_id, struct
> >> rte_eth_link *link);
> >>   */
> >>  int rte_eth_link_get_nowait(uint16_t port_id, struct rte_eth_link
> >> *link);
> >>
> >> +/**
> >> + * Format link status to textual representation. speed_unit is used
> to
> >> convert
> >> + * link_speed to specified unit. Also this function threats a
> special
> >> + * ETH_SPEED_NUM_UNKNOWN value of link_speed and return 'UNKNOWN'
> >> speed
> >> + * in this case.
> >> + *
> >> + * @param link
> >> + *   Link status provided by rte_eth_link_get function
> >> + * @param speed_unit
> >> + *   Target units for the speed. Following values are available:
> >> + *    - ETH_SPEED_UNIT_GBPS
> >> + *    - ETH_SPEED_UNIT_MBPS
> >> + * @param link_text
> >> + *   A pointer to an *rte_eth_link_text* structure to be filled
> with
> >> + *   textual representation of device status
> >> + */
> >> +void rte_eth_link_prepare_text(struct rte_eth_link *link, uint32_t
> >> speed_unit,
> >> +				struct rte_eth_link_text *link_text);
> >>  /**
> >>   * Retrieve the general I/O statistics of an Ethernet device.
> >>   *
> >> --
> >> 2.17.1
> >>
> >
> > Considering that this function will only be used by applications that
> don't need to follow a vendor-specific textual format for their link
> status, you can choose your own text format, and don't need the struct
> for the text strings. The function can simply write the entire
> information into a single string. It also makes speed_unit superfluous.
> E.g. like this:
> >
> > void rte_eth_link_prepare_text(char *str, const struct rte_eth_link
> *const link)
> > {
> >     if (link.link_status == ETH_LINK_DOWN) {
> >         str += sprintf(str, "Link down");
> >     } else {
> >         str += sprintf(str, "Link up at ");
> >         if (link.link_speed == ETH_SPEED_NUM_UNKNOWN) {
> >             str += sprintf("Unknown speed");
> >         } else {
> >             if (link.link_speed < ETH_SPEED_NUM_1G)
> >                 str += sprintf(str, "%u Mbit/s", link.link_speed);
> >             else if (link.link_speed == ETH_SPEED_NUM_2_5G)
> >                 str += sprintf(str, "2.5 Gbit/s");
> >             else
> >                 str += sprintf(str, "%u Gbit/s", link.link_speed /
> 1000);
> >             str += sprintf(str, " %cDX", link.link_duplex ? 'F' :
> 'H');
> >             str += sprintf(str, " %s", link.link_autoneg ? "Autoneg"
> : "Fixed");
> >         }
> >     }
> > }
> >
> >
> > And if DPDK already has an established style for "convert information
> to human readable text" functions regarding function name and parameter
> order, the function should follow such style.
> >
> 
> What about having them both, a per-formatted string that can make life
> easy for
> applications, and struct for text strings for the apps need some
> granularity.
> 

Not necessary. Application developers can easily write their own link status formatting functions.

And the formatting function provided by DPDK can be used as a reference if the application developer needs more detailed information. That is one of the beauties of Open Source Software - the source code supplements the documentation.

^ permalink raw reply	[flat|nested] 359+ messages in thread

* [dpdk-dev] [PATCH v3 0/7] ethdev: allow unknown link speed
       [not found]                         ` <CGME20200615090206eucas1p2372f00a6246d36c6d9c3575e17b53edc@eucas1p2.samsung.com>
@ 2020-06-15  9:01                           ` Ivan Dyukov
       [not found]                             ` <CGME20200615090209eucas1p15c676b9ad46b95ce91d63f4fad92dab8@eucas1p1.samsung.com>
                                               ` (6 more replies)
  0 siblings, 7 replies; 359+ messages in thread
From: Ivan Dyukov @ 2020-06-15  9:01 UTC (permalink / raw)
  To: dev, i.dyukov, v.kuramshin, thomas, david.marchand, ferruh.yigit,
	arybchenko, wei.zhao1, jia.guo, beilei.xing, qiming.yang,
	wenzhuo.lu

 MAINTAINERS                                   |   1 +
 app/proc-info/main.c                          |   9 +-
 app/test-pipeline/init.c                      |  10 +-
 app/test-pmd/config.c                         |  19 +--
 app/test-pmd/testpmd.c                        |   9 +-
 app/test/Makefile                             |   3 +
 app/test/meson.build                          |   2 +
 app/test/test_ethdev_link.c                   | 253 +++++++++++++++++++++++++++++++++++++
 app/test/test_pmd_perf.c                      |  17 +--
 doc/guides/sample_app_ug/link_status_intr.rst |  10 +-
 drivers/net/i40e/i40e_ethdev.c                |   5 +-
 drivers/net/i40e/i40e_ethdev_vf.c             |  10 +-
 drivers/net/ice/ice_ethdev.c                  |   5 +-
 drivers/net/ixgbe/ixgbe_ethdev.c              |   6 +-
 lib/librte_ethdev/rte_ethdev.c                | 163 ++++++++++++++++++++++++
 lib/librte_ethdev/rte_ethdev.h                |  72 +++++++++--
 16 files changed, 529 insertions(+), 65 deletions(-)


 
v3 changes:
* remove rte_eth_link_prepare_text function
* add rte_eth_link_format and rte_eth_link_printf functions
* added unit tests for rte_eth_link_format function
TBD:
update examples in 'example' folder with new status printing mechanism
update remaining nic drivers with 'unknown' speed

v2 changes:
* add function which format link status to textual representation
* update drivers for Intel nics with 'unknown' speed
TBD:
update examples in 'example' folder with new status printing mechanism
update remaining nic drivers with 'unknown' speed

v1 changes:
This is initial patchset which introduces UNKNOWN speed to dpdk
applications. Also it contains changes related to printf formating.
Patchset contains changes for app/ and doc/ folders.
examples/ folder will be provided later.


^ permalink raw reply	[flat|nested] 359+ messages in thread

* [dpdk-dev] [PATCH v3 1/7] ethdev: allow unknown link speed
       [not found]                             ` <CGME20200615090209eucas1p15c676b9ad46b95ce91d63f4fad92dab8@eucas1p1.samsung.com>
@ 2020-06-15  9:01                               ` " Ivan Dyukov
  2020-06-17 16:45                                 ` Ferruh Yigit
  0 siblings, 1 reply; 359+ messages in thread
From: Ivan Dyukov @ 2020-06-15  9:01 UTC (permalink / raw)
  To: dev, i.dyukov, v.kuramshin, thomas, david.marchand, ferruh.yigit,
	arybchenko, wei.zhao1, jia.guo, beilei.xing, qiming.yang,
	wenzhuo.lu

From: Thomas Monjalon <thomas@monjalon.net>

When querying the link information, the link status is
a mandatory major information.
Other boolean values are supposed to be accurate:
	- duplex mode (half/full)
	- negotiation (auto/fixed)

This API update is making explicit that the link speed information
is optional.
The value ETH_SPEED_NUM_NONE (0) was already part of the API.
The value ETH_SPEED_NUM_UNKNOWN (infinite) is added to cover
two different cases:
	- speed is not known by the driver
	- device is virtual

Suggested-by: Morten Brørup <mb@smartsharesystems.com>
Suggested-by: Benoit Ganne <bganne@cisco.com>
Signed-off-by: Thomas Monjalon <thomas@monjalon.net>
---
 lib/librte_ethdev/rte_ethdev.h | 20 ++++++++++----------
 1 file changed, 10 insertions(+), 10 deletions(-)

diff --git a/lib/librte_ethdev/rte_ethdev.h b/lib/librte_ethdev/rte_ethdev.h
index a49242bcd..2090af501 100644
--- a/lib/librte_ethdev/rte_ethdev.h
+++ b/lib/librte_ethdev/rte_ethdev.h
@@ -303,6 +303,7 @@ struct rte_eth_stats {
 #define ETH_SPEED_NUM_56G      56000 /**<  56 Gbps */
 #define ETH_SPEED_NUM_100G    100000 /**< 100 Gbps */
 #define ETH_SPEED_NUM_200G    200000 /**< 200 Gbps */
+#define ETH_SPEED_NUM_UNKNOWN UINT32_MAX /**< Unknown */
 
 /**
  * A structure used to retrieve link-level information of an Ethernet port.
@@ -2262,15 +2263,16 @@ int rte_eth_allmulticast_disable(uint16_t port_id);
 int rte_eth_allmulticast_get(uint16_t port_id);
 
 /**
- * Retrieve the status (ON/OFF), the speed (in Mbps) and the mode (HALF-DUPLEX
- * or FULL-DUPLEX) of the physical link of an Ethernet device. It might need
- * to wait up to 9 seconds in it.
+ * Retrieve the link status (up/down), the duplex mode (half/full),
+ * the negotiation (auto/fixed), and if available, the speed (Mbps).
+ *
+ * It might need to wait up to 9 seconds.
+ * @see rte_eth_link_get_nowait.
  *
  * @param port_id
  *   The port identifier of the Ethernet device.
  * @param link
- *   A pointer to an *rte_eth_link* structure to be filled with
- *   the status, the speed and the mode of the Ethernet device link.
+ *   Link information written back.
  * @return
  *   - (0) if successful.
  *   - (-ENOTSUP) if the function is not supported in PMD driver.
@@ -2279,15 +2281,13 @@ int rte_eth_allmulticast_get(uint16_t port_id);
 int rte_eth_link_get(uint16_t port_id, struct rte_eth_link *link);
 
 /**
- * Retrieve the status (ON/OFF), the speed (in Mbps) and the mode (HALF-DUPLEX
- * or FULL-DUPLEX) of the physical link of an Ethernet device. It is a no-wait
- * version of rte_eth_link_get().
+ * Retrieve the link status (up/down), the duplex mode (half/full),
+ * the negotiation (auto/fixed), and if available, the speed (Mbps).
  *
  * @param port_id
  *   The port identifier of the Ethernet device.
  * @param link
- *   A pointer to an *rte_eth_link* structure to be filled with
- *   the status, the speed and the mode of the Ethernet device link.
+ *   Link information written back.
  * @return
  *   - (0) if successful.
  *   - (-ENOTSUP) if the function is not supported in PMD driver.
-- 
2.17.1


^ permalink raw reply	[flat|nested] 359+ messages in thread

* [dpdk-dev] [PATCH v3 2/7] ethdev: add a link status text representation
       [not found]                             ` <CGME20200615090211eucas1p2f9951f582b14d602cbf4d51e228b12a0@eucas1p2.samsung.com>
@ 2020-06-15  9:01                               ` Ivan Dyukov
  2020-06-17 16:45                                 ` Ferruh Yigit
  0 siblings, 1 reply; 359+ messages in thread
From: Ivan Dyukov @ 2020-06-15  9:01 UTC (permalink / raw)
  To: dev, i.dyukov, v.kuramshin, thomas, david.marchand, ferruh.yigit,
	arybchenko, wei.zhao1, jia.guo, beilei.xing, qiming.yang,
	wenzhuo.lu

This commit add function which treat link status structure
and format it to text representation.

Signed-off-by: Ivan Dyukov <i.dyukov@samsung.com>
---
 MAINTAINERS                    |   1 +
 app/test/Makefile              |   3 +
 app/test/meson.build           |   2 +
 app/test/test_ethdev_link.c    | 253 +++++++++++++++++++++++++++++++++
 lib/librte_ethdev/rte_ethdev.c | 163 +++++++++++++++++++++
 lib/librte_ethdev/rte_ethdev.h |  52 +++++++
 6 files changed, 474 insertions(+)
 create mode 100644 app/test/test_ethdev_link.c

diff --git a/MAINTAINERS b/MAINTAINERS
index 6a14622a0..94c5cd58e 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -378,6 +378,7 @@ T: git://dpdk.org/next/dpdk-next-net
 F: lib/librte_ethdev/
 F: devtools/test-null.sh
 F: doc/guides/prog_guide/switch_representation.rst
+F: app/test/test_ethdev*
 
 Flow API
 M: Ori Kam <orika@mellanox.com>
diff --git a/app/test/Makefile b/app/test/Makefile
index 5b119aa61..14552073d 100644
--- a/app/test/Makefile
+++ b/app/test/Makefile
@@ -249,6 +249,9 @@ SRCS-$(CONFIG_RTE_LIBRTE_SECURITY) += test_security.c
 
 SRCS-$(CONFIG_RTE_LIBRTE_IPSEC) += test_ipsec.c test_ipsec_perf.c
 SRCS-$(CONFIG_RTE_LIBRTE_IPSEC) += test_ipsec_sad.c
+
+SRCS-$(CONFIG_RTE_LIBRTE_ETHER) += test_ethdev_link.c
+
 ifeq ($(CONFIG_RTE_LIBRTE_IPSEC),y)
 LDLIBS += -lrte_ipsec
 endif
diff --git a/app/test/meson.build b/app/test/meson.build
index 1715ddbcb..c5b742c15 100644
--- a/app/test/meson.build
+++ b/app/test/meson.build
@@ -38,6 +38,7 @@ test_sources = files('commands.c',
 	'test_efd.c',
 	'test_efd_perf.c',
 	'test_errno.c',
+	'test_ethdev_link.c',
 	'test_event_crypto_adapter.c',
 	'test_event_eth_rx_adapter.c',
 	'test_event_ring.c',
@@ -196,6 +197,7 @@ fast_tests = [
         ['eal_flags_misc_autotest', false],
         ['eal_fs_autotest', true],
         ['errno_autotest', true],
+        ['ethdev_link_status' true],
         ['event_ring_autotest', true],
         ['fib_autotest', true],
         ['fib6_autotest', true],
diff --git a/app/test/test_ethdev_link.c b/app/test/test_ethdev_link.c
new file mode 100644
index 000000000..9d04dfb81
--- /dev/null
+++ b/app/test/test_ethdev_link.c
@@ -0,0 +1,253 @@
+/* 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[128];
+	ret = rte_eth_link_format(text, 128, NULL, &link_status);
+	RTE_TEST_ASSERT(ret > 0, "Failed to format default string\n");
+	TEST_ASSERT_BUFFERS_ARE_EQUAL("Link up at 2.5 Gbit/s 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_format(text, 128, NULL, &link_status);
+	RTE_TEST_ASSERT(ret > 0, "Failed to format default string\n");
+	TEST_ASSERT_BUFFERS_ARE_EQUAL("Link up at 10 Mbit/s HDX Fixed",
+		text, strlen(text), "Invalid default link status "
+		"string with HDX");
+
+	link_status.link_speed = ETH_SPEED_NUM_UNKNOWN,
+	ret = rte_eth_link_format(text, 128, NULL, &link_status);
+	RTE_TEST_ASSERT(ret > 0, "Failed to format default string\n");
+	TEST_ASSERT_BUFFERS_ARE_EQUAL("Link up at Unknown speed HDX Fixed",
+		text, strlen(text), "Invalid default link status "
+		"string with HDX");
+	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[128];
+	ret = rte_eth_link_format(text, 128, NULL, &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_string_overflow(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[128];
+	int i = 0;
+	for (i = 0; i < 128; i++)
+		text[i] = 'Y';
+
+
+	ret = rte_eth_link_format(NULL, 2, "status %S, %G Gbits/s",
+		&link_status);
+	RTE_TEST_ASSERT(ret < 0, "Format string should fail, but it's ok\n");
+
+	ret = rte_eth_link_format(text, 2, "status %S, %G Gbits/s",
+		&link_status);
+	RTE_TEST_ASSERT(ret < 0, "Format string should fail, but it's ok\n");
+	RTE_TEST_ASSERT(text[2] == 'Y', "String1 overflow\n");
+
+	ret = rte_eth_link_format(text, 8, NULL,
+		&link_status);
+	RTE_TEST_ASSERT(ret < 0, "Default format string should fail,"
+			" but it's ok\n");
+	RTE_TEST_ASSERT(text[8] == 'Y', "String1 overflow\n");
+
+	ret = rte_eth_link_format(text, 10, NULL,
+		&link_status);
+	RTE_TEST_ASSERT(ret < 0, "Default format string should fail,"
+			" but it's ok\n");
+	RTE_TEST_ASSERT(text[10] == 'Y', "String1 overflow\n");
+
+	ret = rte_eth_link_format(text, 2, "%S",
+		&link_status);
+	RTE_TEST_ASSERT(ret < 0, "Status string should fail, but it's ok\n");
+
+	return TEST_SUCCESS;
+}
+
+static int32_t
+test_link_status_format(void)
+{
+	int ret = 0;
+	struct rte_eth_link link_status = {
+		.link_speed = ETH_SPEED_NUM_40G,
+		.link_status = ETH_LINK_UP,
+		.link_autoneg = ETH_LINK_AUTONEG,
+		.link_duplex = ETH_LINK_FULL_DUPLEX
+	};
+	char text[128];
+	int i = 0;
+	for (i = 0; i < 128; i++)
+		text[i] = 'Y';
+	ret = rte_eth_link_format(text, 128, "status = %S, duplex = %D\n",
+		&link_status);
+	RTE_TEST_ASSERT(ret > 0, "Failed to format string\n");
+	TEST_ASSERT_BUFFERS_ARE_EQUAL("status = Up, duplex = FDX\n",
+		text, strlen(text), "Invalid status string1.");
+
+	ret = rte_eth_link_format(text, 128,
+		"%A",
+		&link_status);
+	RTE_TEST_ASSERT(ret > 0, "Failed to format string\n");
+	TEST_ASSERT_BUFFERS_ARE_EQUAL("Autoneg",
+		text, strlen(text), "Invalid status string2.");
+
+	ret = rte_eth_link_format(text, 128,
+		"%G",
+		&link_status);
+	RTE_TEST_ASSERT(ret > 0, "Failed to format string\n");
+	TEST_ASSERT_BUFFERS_ARE_EQUAL("40.0",
+		text, strlen(text), "Invalid status string3.");
+	return TEST_SUCCESS;
+}
+
+static int32_t
+test_link_status_return_value(void)
+{
+	int ret = 0;
+	struct rte_eth_link link_status = {
+		.link_speed = ETH_SPEED_NUM_40G,
+		.link_status = ETH_LINK_UP,
+		.link_autoneg = ETH_LINK_AUTONEG,
+		.link_duplex = ETH_LINK_FULL_DUPLEX
+	};
+	char text[128];
+	int i = 0;
+	for (i = 0; i < 128; i++)
+		text[i] = 'Y';
+	ret = rte_eth_link_format(text, 128, "status = %S, ",
+		&link_status);
+	ret += rte_eth_link_format(text + ret, 128 - ret,
+		"%A",
+		&link_status);
+	ret += rte_eth_link_format(text + ret, 128 - ret,
+		", duplex = %D\n",
+		&link_status);
+	ret += rte_eth_link_format(text + ret, 128 - ret,
+		"%M Mbits/s\n",
+		&link_status);
+	RTE_TEST_ASSERT(ret > 0, "Failed to format string\n");
+	TEST_ASSERT_BUFFERS_ARE_EQUAL("status = Up, Autoneg, duplex = FDX\n"
+		"40000 Mbits/s\n",
+		text, strlen(text), "Invalid status string");
+
+	return TEST_SUCCESS;
+}
+
+static int32_t
+test_link_status_invalid_fmt(void)
+{
+	int ret = 0;
+	struct rte_eth_link link_status = {
+		.link_speed = ETH_SPEED_NUM_40G,
+		.link_status = ETH_LINK_UP,
+		.link_autoneg = ETH_LINK_AUTONEG,
+		.link_duplex = ETH_LINK_FULL_DUPLEX
+	};
+	char text[128];
+	ret = rte_eth_link_format(text, 128, "status = %",
+		&link_status);
+	RTE_TEST_ASSERT(ret < 0, "Status string1 should fail, but it's ok\n");
+	ret = rte_eth_link_format(text, 128,
+		", duplex = %d\n",
+		&link_status);
+	RTE_TEST_ASSERT(ret < 0, "Status string2 should fail, but it's ok\n");
+	ret = rte_eth_link_format(text, 128,
+		"% Mbits/s\n",
+		&link_status);
+	RTE_TEST_ASSERT(ret < 0, "Status string3 should fail, but it's ok\n");
+
+	return TEST_SUCCESS;
+}
+
+static int32_t
+test_link_status_format_edges(void)
+{
+	int ret = 0;
+	struct rte_eth_link link_status = {
+		.link_speed = ETH_SPEED_NUM_UNKNOWN,
+		.link_status = ETH_LINK_DOWN,
+		.link_autoneg = ETH_LINK_AUTONEG,
+		.link_duplex = ETH_LINK_HALF_DUPLEX
+	};
+	char text[128];
+	ret = rte_eth_link_format(text, 4, "%S", &link_status);
+	RTE_TEST_ASSERT(ret < 0, "It should fail. No space for "
+				 "zero terminator\n");
+	ret = rte_eth_link_format(text, 6, "123%D", &link_status);
+	RTE_TEST_ASSERT(ret < 0, "It should fail. No space for "
+				 "zero terminator\n");
+	ret = rte_eth_link_format(text, 7, "%A", &link_status);
+	RTE_TEST_ASSERT(ret < 0, "It should fail. No space for "
+				 "zero terminator\n");
+	ret = rte_eth_link_format(text, 8, "%A", &link_status);
+	RTE_TEST_ASSERT(ret > 0, "It should ok, but it fails\n");
+	return TEST_SUCCESS;
+}
+static struct unit_test_suite link_status_testsuite = {
+	.suite_name = "link status formating",
+	.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_status_string_overflow),
+		TEST_CASE(test_link_status_format),
+		TEST_CASE(test_link_status_format_edges),
+		TEST_CASE(test_link_status_invalid_fmt),
+		TEST_CASE(test_link_status_return_value),
+		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);
diff --git a/lib/librte_ethdev/rte_ethdev.c b/lib/librte_ethdev/rte_ethdev.c
index 8e10a6fc3..108be1902 100644
--- a/lib/librte_ethdev/rte_ethdev.c
+++ b/lib/librte_ethdev/rte_ethdev.c
@@ -2385,6 +2385,169 @@ rte_eth_link_get_nowait(uint16_t port_id, struct rte_eth_link *eth_link)
 	return 0;
 }
 
+int
+rte_eth_link_printf(const char *const fmt,
+		    struct rte_eth_link *link)
+{
+	char text[200];
+	int ret;
+	ret = rte_eth_link_format(text, 200, fmt, link);
+	printf("%s", text);
+	return ret;
+}
+
+int
+rte_eth_link_format(char *str, int32_t len, const char *const fmt,
+		    struct rte_eth_link *link)
+{
+	int offset = 0;
+	int32_t clen = len;
+	const char *fmt_cur = fmt;
+	double gbits = (double)link->link_speed / 1000.;
+	/* TBD: make it international? */
+	static const char LINK_DOWN_STR[]     = "Link down";
+	static const char LINK_UP_STR[]       = "Link up at ";
+	static const char UNKNOWN_SPEED_STR[] = "Unknown speed";
+	static const char MBITS_STR[]	      = "Mbit/s";
+	static const char GBITS_STR[]	      = "Gbit/s";
+	static const char AUTONEG_STR[]       = "Autoneg";
+	static const char FIXED_STR[]         = "Fixed";
+	static const char FDX_STR[]           = "FDX";
+	static const char HDX_STR[]           = "HDX";
+	static const char UNKNOWN_STR[]       = "Unknown";
+	static const char UP_STR[]            = "Up";
+	static const char DOWN_STR[]          = "Down";
+	if (str == NULL || len == 0)
+		return -1;
+	/* default format string, if no fmt is specified */
+	if (fmt == NULL) {
+		if (link->link_status == ETH_LINK_DOWN)
+			return snprintf(str, (size_t)clen, "%s", LINK_DOWN_STR);
+
+		offset = snprintf(str, (size_t)clen, "%s", LINK_UP_STR);
+		if (offset < 0 || (clen - offset) <= 0)
+			return -1;
+		clen -= offset;
+		str += offset;
+		if (link->link_speed == ETH_SPEED_NUM_UNKNOWN) {
+			offset = snprintf(str, clen, "%s",
+					  UNKNOWN_SPEED_STR);
+			if (offset < 0 || (clen - offset) <= 0)
+				return -1;
+			clen -= offset;
+			str += offset;
+		} else {
+			if (link->link_speed < ETH_SPEED_NUM_1G) {
+				offset = snprintf(str, clen,
+						  "%u %s",
+						  link->link_speed,
+						  MBITS_STR);
+				if (offset < 0 || (clen - offset) <= 0)
+					return -1;
+				clen -= offset;
+				str += offset;
+
+			} else {
+				offset = snprintf(str, clen,
+						  "%.1f %s",
+						  gbits,
+						  GBITS_STR);
+				if (offset < 0 || (clen - offset) <= 0)
+					return -1;
+				clen -= offset;
+				str += offset;
+			}
+		}
+		offset = snprintf(str, clen, " %s", link->link_duplex ?
+			       FDX_STR : HDX_STR);
+		if (offset < 0 || (clen - offset) <= 0)
+			return -1;
+		clen -= offset;
+		str += offset;
+		offset = snprintf(str, clen, " %s", link->link_autoneg ?
+			       AUTONEG_STR : FIXED_STR);
+		if (offset < 0 || (clen - offset) <= 0)
+			return -1;
+		clen -= offset;
+		str += offset;
+	/* Formated status */
+	} else {
+		char c = *fmt_cur;
+		while (c) {
+			if (clen <= 0)
+				return -1;
+			if (c == '%') {
+				c = *++fmt_cur;
+				switch (c) {
+				/* Speed in Mbits/s */
+				case 'M':
+					if (link->link_speed ==
+					    ETH_SPEED_NUM_UNKNOWN)
+						offset = snprintf(str,
+						  clen, "%s",
+						  UNKNOWN_STR);
+					else
+						offset = snprintf(str,
+						  clen, "%u",
+						  link->link_speed);
+					break;
+				/* Speed in Gbits/s */
+				case 'G':
+					if (link->link_speed ==
+					    ETH_SPEED_NUM_UNKNOWN)
+						offset = snprintf(str,
+						  clen, "%s",
+						  UNKNOWN_STR);
+					else {
+						offset = snprintf(str,
+						  clen, "%.1f",
+						  gbits);
+					}
+					break;
+				/* Link status */
+				case 'S':
+					offset = snprintf(str, clen,
+						"%s",
+						link->link_status ?
+						UP_STR : DOWN_STR);
+					break;
+				/* Link autoneg */
+				case 'A':
+					offset = snprintf(str, clen,
+						"%s",
+						link->link_autoneg ?
+						AUTONEG_STR :
+						FIXED_STR);
+					break;
+				/* Link duplex */
+				case 'D':
+					offset = snprintf(str, clen,
+						"%s",
+						link->link_duplex ?
+						FDX_STR : HDX_STR);
+					break;
+				/* Error cases */
+				default:
+					return -1;
+
+				}
+				if (offset < 0 || (clen - offset) <= 0)
+					return -1;
+				clen -= offset;
+				str += offset;
+			} else {
+				*str++ = c;
+				clen--;
+			}
+			c = *++fmt_cur;
+		}
+	}
+	/* teminate string */
+	clen = len - clen;
+	*str = 0;
+	return clen;
+}
+
 int
 rte_eth_stats_get(uint16_t port_id, struct rte_eth_stats *stats)
 {
diff --git a/lib/librte_ethdev/rte_ethdev.h b/lib/librte_ethdev/rte_ethdev.h
index 2090af501..83291e656 100644
--- a/lib/librte_ethdev/rte_ethdev.h
+++ b/lib/librte_ethdev/rte_ethdev.h
@@ -2295,6 +2295,58 @@ int rte_eth_link_get(uint16_t port_id, struct rte_eth_link *link);
  */
 int rte_eth_link_get_nowait(uint16_t port_id, struct rte_eth_link *link);
 
+
+/**
+ * print formated link status to stdout. This function threats all
+ * special values like ETH_SPEED_NUM_UNKNOWN, ETH_LINK_DOWN etc. and convert
+ * them to textual representation.
+ *
+ * @param fmt
+ *   Format string which allow to format link status. If NULL is provided
+ *   , default formating will be applied.
+ *   Following specifiers are available:
+ *    - '%M' link speed in Mbits/s
+ *    - '%G' link speed in Gbits/s
+ *    - '%S' link status. e.g. Up or Down
+ *    - '%A' link autonegotiation state
+ *    - '%D' link duplex state
+ * @param link
+ *   Link status provided by rte_eth_link_get function
+ * @return
+ *   - Number of bytes written to stdout. In case of error, -1 is returned.
+ *
+ */
+int rte_eth_link_printf(const char *const fmt,
+			struct rte_eth_link *link);
+
+/**
+ * Format link status to textual representation. This function threats all
+ * special values like ETH_SPEED_NUM_UNKNOWN, ETH_LINK_DOWN etc. and convert
+ * them to textual representation.
+ *
+ * @param str
+ *   A pointer to a string to be filled with textual representation of
+ *   device status.
+ * @param len
+ *   Length of available memory at 'str' string.
+ * @param fmt
+ *   Format string which allow to format link status. If NULL is provided
+ *   , default formating will be applied.
+ *   Following specifiers are available:
+ *    - '%M' link speed in Mbits/s
+ *    - '%G' link speed in Gbits/s
+ *    - '%S' link status. e.g. Up or Down
+ *    - '%A' link autonegotiation state
+ *    - '%D' link duplex state
+ * @param link
+ *   Link status provided by rte_eth_link_get function
+ * @return
+ *   - Number of bytes written to str array. In case of error, -1 is returned.
+ *
+ */
+int rte_eth_link_format(char *str, int32_t len, const char *const fmt,
+			struct rte_eth_link *eth_link);
+
 /**
  * Retrieve the general I/O statistics of an Ethernet device.
  *
-- 
2.17.1


^ permalink raw reply	[flat|nested] 359+ messages in thread

* [dpdk-dev] [PATCH v3 3/7] app: UNKNOWN link speed print format
       [not found]                             ` <CGME20200615090213eucas1p15932ac08c443956186734940fcd03e28@eucas1p1.samsung.com>
@ 2020-06-15  9:01                               ` Ivan Dyukov
  2020-06-17 16:49                                 ` Ferruh Yigit
  0 siblings, 1 reply; 359+ messages in thread
From: Ivan Dyukov @ 2020-06-15  9:01 UTC (permalink / raw)
  To: dev, i.dyukov, v.kuramshin, thomas, david.marchand, ferruh.yigit,
	arybchenko, wei.zhao1, jia.guo, beilei.xing, qiming.yang,
	wenzhuo.lu

Add usage of rte_eth_link_format function to example
applications

Signed-off-by: Ivan Dyukov <i.dyukov@samsung.com>
---
 app/proc-info/main.c     |  9 +++------
 app/test-pipeline/init.c | 10 ++++------
 app/test-pmd/config.c    | 19 +++++++++++--------
 app/test-pmd/testpmd.c   |  9 +--------
 app/test/test_pmd_perf.c | 17 +++++++----------
 5 files changed, 26 insertions(+), 38 deletions(-)

diff --git a/app/proc-info/main.c b/app/proc-info/main.c
index abeca4aab..4a4c572c3 100644
--- a/app/proc-info/main.c
+++ b/app/proc-info/main.c
@@ -685,12 +685,9 @@ show_port(void)
 			printf("Link get failed (port %u): %s\n",
 			       i, rte_strerror(-ret));
 		} else {
-			printf("\t  -- link speed %d duplex %d,"
-					" auto neg %d status %d\n",
-					link.link_speed,
-					link.link_duplex,
-					link.link_autoneg,
-					link.link_status);
+			rte_eth_link_printf("\t  -- link speed: %M, duplex: %D,"
+					" auto neg: %A, status: %S\n",
+					&link);
 		}
 		printf("\t  -- promiscuous (%d)\n",
 				rte_eth_promiscuous_get(i));
diff --git a/app/test-pipeline/init.c b/app/test-pipeline/init.c
index 67d54ae05..9d5d209ea 100644
--- a/app/test-pipeline/init.c
+++ b/app/test-pipeline/init.c
@@ -155,7 +155,7 @@ static void
 app_ports_check_link(void)
 {
 	uint32_t all_ports_up, i;
-
+	char status_text[50];
 	all_ports_up = 1;
 
 	for (i = 0; i < app.n_ports; i++) {
@@ -173,12 +173,10 @@ app_ports_check_link(void)
 			all_ports_up = 0;
 			continue;
 		}
-
-		RTE_LOG(INFO, USER1, "Port %u (%u Gbps) %s\n",
+		rte_eth_link_format(status_text, 50, "(%G Gbps) %S", &link);
+		RTE_LOG(INFO, USER1, "Port %u %s\n",
 			port,
-			link.link_speed / 1000,
-			link.link_status ? "UP" : "DOWN");
-
+			status_text);
 		if (link.link_status == ETH_LINK_DOWN)
 			all_ports_up = 0;
 	}
diff --git a/app/test-pmd/config.c b/app/test-pmd/config.c
index 5381207cc..77fa9a0e9 100644
--- a/app/test-pmd/config.c
+++ b/app/test-pmd/config.c
@@ -600,10 +600,9 @@ port_infos_display(portid_t port_id)
 	} else
 		printf("\nmemory allocation on the socket: %u",port->socket_id);
 
-	printf("\nLink status: %s\n", (link.link_status) ? ("up") : ("down"));
-	printf("Link speed: %u Mbps\n", (unsigned) link.link_speed);
-	printf("Link duplex: %s\n", (link.link_duplex == ETH_LINK_FULL_DUPLEX) ?
-	       ("full-duplex") : ("half-duplex"));
+	rte_eth_link_printf("\nLink status: %S\n"
+			    "Link speed: %M Mbps\n"
+			    "Link duplex: %D\n", &link);
 
 	if (!rte_eth_dev_get_mtu(port_id, &mtu))
 		printf("MTU: %u\n", mtu);
@@ -726,6 +725,8 @@ port_summary_display(portid_t port_id)
 	struct rte_eth_link link;
 	struct rte_eth_dev_info dev_info;
 	char name[RTE_ETH_NAME_MAX_LEN];
+	char status_text[6];
+	char speed_text[12];
 	int ret;
 
 	if (port_id_is_invalid(port_id, ENABLED_WARN)) {
@@ -746,12 +747,14 @@ port_summary_display(portid_t port_id)
 	if (ret != 0)
 		return;
 
-	printf("%-4d %02X:%02X:%02X:%02X:%02X:%02X %-12s %-14s %-8s %uMbps\n",
+	rte_eth_link_format(status_text, 6, "%S", &link);
+	rte_eth_link_format(speed_text, 12, "%M", &link);
+	printf("%-4d %02X:%02X:%02X:%02X:%02X:%02X %-12s %-14s %-8s %sMbps\n",
 		port_id, mac_addr.addr_bytes[0], mac_addr.addr_bytes[1],
 		mac_addr.addr_bytes[2], mac_addr.addr_bytes[3],
 		mac_addr.addr_bytes[4], mac_addr.addr_bytes[5], name,
-		dev_info.driver_name, (link.link_status) ? ("up") : ("down"),
-		(unsigned int) link.link_speed);
+		dev_info.driver_name, status_text,
+		speed_text);
 }
 
 void
@@ -3897,7 +3900,7 @@ set_queue_rate_limit(portid_t port_id, uint16_t queue_idx, uint16_t rate)
 	ret = eth_link_get_nowait_print_err(port_id, &link);
 	if (ret < 0)
 		return 1;
-	if (rate > link.link_speed) {
+	if (link.link_speed != UINT32_MAX && rate > link.link_speed) {
 		printf("Invalid rate value:%u bigger than link speed: %u\n",
 			rate, link.link_speed);
 		return 1;
diff --git a/app/test-pmd/testpmd.c b/app/test-pmd/testpmd.c
index 9cbe6e9f6..621a1055c 100644
--- a/app/test-pmd/testpmd.c
+++ b/app/test-pmd/testpmd.c
@@ -3007,14 +3007,7 @@ check_all_ports_link_status(uint32_t port_mask)
 			}
 			/* print link status if flag set */
 			if (print_flag == 1) {
-				if (link.link_status)
-					printf(
-					"Port%d Link Up. speed %u Mbps- %s\n",
-					portid, link.link_speed,
-				(link.link_duplex == ETH_LINK_FULL_DUPLEX) ?
-					("full-duplex") : ("half-duplex"));
-				else
-					printf("Port %d Link Down\n", portid);
+				rte_eth_link_printf(NULL, &link);
 				continue;
 			}
 			/* clear all_ports_up flag if any link down */
diff --git a/app/test/test_pmd_perf.c b/app/test/test_pmd_perf.c
index 352cd4715..8ce464b56 100644
--- a/app/test/test_pmd_perf.c
+++ b/app/test/test_pmd_perf.c
@@ -126,6 +126,7 @@ check_all_ports_link_status(uint16_t port_num, uint32_t port_mask)
 	uint8_t count, all_ports_up, print_flag = 0;
 	struct rte_eth_link link;
 	int ret;
+	char link_status[50];
 
 	printf("Checking link statuses...\n");
 	fflush(stdout);
@@ -146,16 +147,12 @@ check_all_ports_link_status(uint16_t port_num, uint32_t port_mask)
 
 			/* print link status if flag set */
 			if (print_flag == 1) {
-				if (link.link_status) {
-					printf(
-					"Port%d Link Up. Speed %u Mbps - %s\n",
-						portid, link.link_speed,
-				(link.link_duplex == ETH_LINK_FULL_DUPLEX) ?
-					("full-duplex") : ("half-duplex"));
-					if (link_mbps == 0)
-						link_mbps = link.link_speed;
-				} else
-					printf("Port %d Link Down\n", portid);
+				if (link.link_status && link_mbps == 0)
+					link_mbps = link.link_speed;
+
+				rte_eth_link_format(link_status, 50, NULL,
+						    &link);
+				printf("Port %d %s\n", portid, link_status);
 				continue;
 			}
 			/* clear all_ports_up flag if any link down */
-- 
2.17.1


^ permalink raw reply	[flat|nested] 359+ messages in thread

* [dpdk-dev] [PATCH v3 4/7] doc: update sample app with unknown speed
       [not found]                             ` <CGME20200615090214eucas1p21d345bc83cb8b8403c54958b0e7f6462@eucas1p2.samsung.com>
@ 2020-06-15  9:01                               ` Ivan Dyukov
  2020-06-17 16:50                                 ` Ferruh Yigit
  0 siblings, 1 reply; 359+ messages in thread
From: Ivan Dyukov @ 2020-06-15  9:01 UTC (permalink / raw)
  To: dev, i.dyukov, v.kuramshin, thomas, david.marchand, ferruh.yigit,
	arybchenko, wei.zhao1, jia.guo, beilei.xing, qiming.yang,
	wenzhuo.lu

Add usage of rte_eth_link_format function to example
applications

Signed-off-by: Ivan Dyukov <i.dyukov@samsung.com>
---
 doc/guides/sample_app_ug/link_status_intr.rst | 10 +++++-----
 1 file changed, 5 insertions(+), 5 deletions(-)

diff --git a/doc/guides/sample_app_ug/link_status_intr.rst b/doc/guides/sample_app_ug/link_status_intr.rst
index 04c40f285..d1ac35be8 100644
--- a/doc/guides/sample_app_ug/link_status_intr.rst
+++ b/doc/guides/sample_app_ug/link_status_intr.rst
@@ -158,6 +158,7 @@ An example callback function that has been written as indicated below.
     {
         struct rte_eth_link link;
         int ret;
+        char text[200];
 
         RTE_SET_USED(param);
 
@@ -169,11 +170,10 @@ An example callback function that has been written as indicated below.
         if (ret < 0) {
             printf("Failed to get port %d link status: %s\n\n",
                    port_id, rte_strerror(-ret));
-        } else if (link.link_status) {
-            printf("Port %d Link Up - speed %u Mbps - %s\n\n", port_id, (unsigned)link.link_speed,
-                  (link.link_duplex == ETH_LINK_FULL_DUPLEX) ? ("full-duplex") : ("half-duplex"));
-        } else
-            printf("Port %d Link Down\n\n", port_id);
+        } else {
+            rte_eth_link_format(text, 200, NULL, &link);
+            printf("Port %d %s\n\n", port_id, text);
+        }
     }
 
 This function is called when a link status interrupt is present for the right port.
-- 
2.17.1


^ permalink raw reply	[flat|nested] 359+ messages in thread

* [dpdk-dev] [PATCH v3 5/7] net/ixgbe: return unknown speed in status
       [not found]                             ` <CGME20200615090216eucas1p2bb5a2c7d6e0baff96990aeba2623bb3d@eucas1p2.samsung.com>
@ 2020-06-15  9:01                               ` Ivan Dyukov
  2020-06-15  9:28                                 ` Zhao1, Wei
                                                   ` (2 more replies)
  0 siblings, 3 replies; 359+ messages in thread
From: Ivan Dyukov @ 2020-06-15  9:01 UTC (permalink / raw)
  To: dev, i.dyukov, v.kuramshin, thomas, david.marchand, ferruh.yigit,
	arybchenko, wei.zhao1, jia.guo, beilei.xing, qiming.yang,
	wenzhuo.lu

rte_ethdev has declared new NUM_UNKNOWN speed which
could be used in case when no speed information is available

Signed-off-by: Ivan Dyukov <i.dyukov@samsung.com>
---
 drivers/net/ixgbe/ixgbe_ethdev.c | 6 +-----
 1 file changed, 1 insertion(+), 5 deletions(-)

diff --git a/drivers/net/ixgbe/ixgbe_ethdev.c b/drivers/net/ixgbe/ixgbe_ethdev.c
index a4e5c539d..5b9b13058 100644
--- a/drivers/net/ixgbe/ixgbe_ethdev.c
+++ b/drivers/net/ixgbe/ixgbe_ethdev.c
@@ -4311,11 +4311,7 @@ ixgbe_dev_link_update_share(struct rte_eth_dev *dev,
 	switch (link_speed) {
 	default:
 	case IXGBE_LINK_SPEED_UNKNOWN:
-		if (hw->device_id == IXGBE_DEV_ID_X550EM_A_1G_T ||
-			hw->device_id == IXGBE_DEV_ID_X550EM_A_1G_T_L)
-			link.link_speed = ETH_SPEED_NUM_10M;
-		else
-			link.link_speed = ETH_SPEED_NUM_100M;
+		link.link_speed = ETH_SPEED_NUM_UNKNOWN;
 		break;
 
 	case IXGBE_LINK_SPEED_100_FULL:
-- 
2.17.1


^ permalink raw reply	[flat|nested] 359+ messages in thread

* [dpdk-dev] [PATCH v3 6/7] net/i40e: return unknown speed in status
       [not found]                             ` <CGME20200615090218eucas1p10282f1948a11d170ca0cec20ed3c7ad9@eucas1p1.samsung.com>
@ 2020-06-15  9:01                               ` " Ivan Dyukov
  2020-06-17 16:52                                 ` Ferruh Yigit
  0 siblings, 1 reply; 359+ messages in thread
From: Ivan Dyukov @ 2020-06-15  9:01 UTC (permalink / raw)
  To: dev, i.dyukov, v.kuramshin, thomas, david.marchand, ferruh.yigit,
	arybchenko, wei.zhao1, jia.guo, beilei.xing, qiming.yang,
	wenzhuo.lu

rte_ethdev has declared new NUM_UNKNOWN speed which
could be used in case when no speed information is available and
link is up. NUM_NONE should be returned, if link is down.

Signed-off-by: Ivan Dyukov <i.dyukov@samsung.com>
---
 drivers/net/i40e/i40e_ethdev.c    |  5 ++++-
 drivers/net/i40e/i40e_ethdev_vf.c | 10 +++++-----
 2 files changed, 9 insertions(+), 6 deletions(-)

diff --git a/drivers/net/i40e/i40e_ethdev.c b/drivers/net/i40e/i40e_ethdev.c
index 749d85f54..d09b77674 100644
--- a/drivers/net/i40e/i40e_ethdev.c
+++ b/drivers/net/i40e/i40e_ethdev.c
@@ -2889,7 +2889,10 @@ update_link_aq(struct i40e_hw *hw, struct rte_eth_link *link,
 		link->link_speed = ETH_SPEED_NUM_40G;
 		break;
 	default:
-		link->link_speed = ETH_SPEED_NUM_NONE;
+		if (link->link_status)
+			link->link_speed = ETH_SPEED_NUM_UNKNOWN;
+		else
+			link->link_speed = ETH_SPEED_NUM_NONE;
 		break;
 	}
 }
diff --git a/drivers/net/i40e/i40e_ethdev_vf.c b/drivers/net/i40e/i40e_ethdev_vf.c
index bb5d28a44..1da185485 100644
--- a/drivers/net/i40e/i40e_ethdev_vf.c
+++ b/drivers/net/i40e/i40e_ethdev_vf.c
@@ -2165,15 +2165,15 @@ i40evf_dev_link_update(struct rte_eth_dev *dev,
 		new_link.link_speed = ETH_SPEED_NUM_40G;
 		break;
 	default:
-		new_link.link_speed = ETH_SPEED_NUM_NONE;
+		if (vf->link_up)
+			new_link.link_speed = ETH_SPEED_NUM_UNKNOWN;
+		else
+			new_link.link_speed = ETH_SPEED_NUM_NONE;
 		break;
 	}
 	/* full duplex only */
 	new_link.link_duplex = ETH_LINK_FULL_DUPLEX;
-	new_link.link_status = vf->link_up &&
-				new_link.link_speed != ETH_SPEED_NUM_NONE
-				? ETH_LINK_UP
-				: ETH_LINK_DOWN;
+	new_link.link_status = vf->link_up ? ETH_LINK_UP : ETH_LINK_DOWN;
 	new_link.link_autoneg =
 		!(dev->data->dev_conf.link_speeds & ETH_LINK_SPEED_FIXED);
 
-- 
2.17.1


^ permalink raw reply	[flat|nested] 359+ messages in thread

* [dpdk-dev] [PATCH v3 7/7] net/ice: return unknown speed in status
       [not found]                             ` <CGME20200615090219eucas1p2d6b0f803bec9e0e6570ca4a4806b17bd@eucas1p2.samsung.com>
@ 2020-06-15  9:01                               ` " Ivan Dyukov
  2020-06-17 16:54                                 ` Ferruh Yigit
  0 siblings, 1 reply; 359+ messages in thread
From: Ivan Dyukov @ 2020-06-15  9:01 UTC (permalink / raw)
  To: dev, i.dyukov, v.kuramshin, thomas, david.marchand, ferruh.yigit,
	arybchenko, wei.zhao1, jia.guo, beilei.xing, qiming.yang,
	wenzhuo.lu

rte_ethdev has declared new NUM_UNKNOWN speed which
could be used in case when no speed information is available and
link is up. NUM_NONE should be returned, if link is down.

Signed-off-by: Ivan Dyukov <i.dyukov@samsung.com>
---
 drivers/net/ice/ice_ethdev.c | 5 ++++-
 1 file changed, 4 insertions(+), 1 deletion(-)

diff --git a/drivers/net/ice/ice_ethdev.c b/drivers/net/ice/ice_ethdev.c
index d5110c439..1c0c087ea 100644
--- a/drivers/net/ice/ice_ethdev.c
+++ b/drivers/net/ice/ice_ethdev.c
@@ -3112,8 +3112,11 @@ ice_link_update(struct rte_eth_dev *dev, int wait_to_complete)
 		link.link_speed = ETH_SPEED_NUM_100G;
 		break;
 	case ICE_AQ_LINK_SPEED_UNKNOWN:
-	default:
 		PMD_DRV_LOG(ERR, "Unknown link speed");
+		link.link_speed = ETH_SPEED_NUM_UNKNOWN;
+		break;
+	default:
+		PMD_DRV_LOG(ERR, "None link speed");
 		link.link_speed = ETH_SPEED_NUM_NONE;
 		break;
 	}
-- 
2.17.1


^ permalink raw reply	[flat|nested] 359+ messages in thread

* Re: [dpdk-dev] [PATCH v3 5/7] net/ixgbe: return unknown speed in status
  2020-06-15  9:01                               ` [dpdk-dev] [PATCH v3 5/7] net/ixgbe: return unknown speed in status Ivan Dyukov
@ 2020-06-15  9:28                                 ` Zhao1, Wei
  2020-06-17 16:50                                 ` Ferruh Yigit
  2020-06-20  3:56                                 ` Zhao1, Wei
  2 siblings, 0 replies; 359+ messages in thread
From: Zhao1, Wei @ 2020-06-15  9:28 UTC (permalink / raw)
  To: i.dyukov, dev, v.kuramshin, thomas, david.marchand, Yigit,
	Ferruh, arybchenko, Guo, Jia, Xing, Beilei, Yang, Qiming, Lu,
	Wenzhuo

Hi, dyukov

> -----Original Message-----
> From: Ivan Dyukov <i.dyukov@samsung.com>
> Sent: Monday, June 15, 2020 5:02 PM
> To: dev@dpdk.org; i.dyukov@samsung.com; v.kuramshin@samsung.com;
> thomas@monjalon.net; david.marchand@redhat.com; Yigit, Ferruh
> <ferruh.yigit@intel.com>; arybchenko@solarflare.com; Zhao1, Wei
> <wei.zhao1@intel.com>; Guo, Jia <jia.guo@intel.com>; Xing, Beilei
> <beilei.xing@intel.com>; Yang, Qiming <qiming.yang@intel.com>; Lu,
> Wenzhuo <wenzhuo.lu@intel.com>
> Subject: [PATCH v3 5/7] net/ixgbe: return unknown speed in status
> 
> rte_ethdev has declared new NUM_UNKNOWN speed which could be used in
> case when no speed information is available
> 
> Signed-off-by: Ivan Dyukov <i.dyukov@samsung.com>
> ---
>  drivers/net/ixgbe/ixgbe_ethdev.c | 6 +-----
>  1 file changed, 1 insertion(+), 5 deletions(-)
> 
> diff --git a/drivers/net/ixgbe/ixgbe_ethdev.c
> b/drivers/net/ixgbe/ixgbe_ethdev.c
> index a4e5c539d..5b9b13058 100644
> --- a/drivers/net/ixgbe/ixgbe_ethdev.c
> +++ b/drivers/net/ixgbe/ixgbe_ethdev.c
> @@ -4311,11 +4311,7 @@ ixgbe_dev_link_update_share(struct rte_eth_dev
> *dev,
>  	switch (link_speed) {
>  	default:
>  	case IXGBE_LINK_SPEED_UNKNOWN:
> -		if (hw->device_id == IXGBE_DEV_ID_X550EM_A_1G_T ||
> -			hw->device_id == IXGBE_DEV_ID_X550EM_A_1G_T_L)
> -			link.link_speed = ETH_SPEED_NUM_10M;
> -		else
> -			link.link_speed = ETH_SPEED_NUM_100M;

You can not delete these specific code for some kind of ixgbe nic!!!


> +		link.link_speed = ETH_SPEED_NUM_UNKNOWN;
>  		break;
> 
>  	case IXGBE_LINK_SPEED_100_FULL:
> --
> 2.17.1


^ permalink raw reply	[flat|nested] 359+ messages in thread

* Re: [dpdk-dev] [PATCH v3 2/7] ethdev: add a link status text representation
  2020-06-15  9:01                               ` [dpdk-dev] [PATCH v3 2/7] ethdev: add a link status text representation Ivan Dyukov
@ 2020-06-17 16:45                                 ` Ferruh Yigit
  2020-06-18 10:08                                   ` Ivan Dyukov
  0 siblings, 1 reply; 359+ messages in thread
From: Ferruh Yigit @ 2020-06-17 16:45 UTC (permalink / raw)
  To: i.dyukov, dev, v.kuramshin, thomas, david.marchand, arybchenko,
	wei.zhao1, jia.guo, beilei.xing, qiming.yang, wenzhuo.lu

On 6/15/2020 10:01 AM, Ivan Dyukov wrote:
> This commit add function which treat link status structure
> and format it to text representation.

If I am following correctly, the initial need was to escape from speed checks
everytime loging link information caused by this new 'unknown' speed.

And later suggestion was to have a pre-formatted text for link logging.

This patch brings additional link status printing/formatting capability with
custom format string support and with new format specifiers for link (like, '%D'
link duplex state),
although this is nice work and thanks for it, I am not sure this complexity and
two new APIs are really needed.
For me only 'rte_eth_link_format()' without custom format support looks good
enough but I won't object if the concensus is to have them.
I am aware there are multiple applications you are updating logging slightly
different which requires this flexibility but what happens if they use same
pre-formatted text, is that difference really required or happened by time based
on developers taste?
I will put some comments below in any case.

> 
> Signed-off-by: Ivan Dyukov <i.dyukov@samsung.com>

<...>

> @@ -249,6 +249,9 @@ SRCS-$(CONFIG_RTE_LIBRTE_SECURITY) += test_security.c
>  
>  SRCS-$(CONFIG_RTE_LIBRTE_IPSEC) += test_ipsec.c test_ipsec_perf.c
>  SRCS-$(CONFIG_RTE_LIBRTE_IPSEC) += test_ipsec_sad.c
> +
> +SRCS-$(CONFIG_RTE_LIBRTE_ETHER) += test_ethdev_link.c

+1 to unit test.

<...>

> +int
> +rte_eth_link_printf(const char *const fmt,
> +		    struct rte_eth_link *link)
> +{
> +	char text[200];
> +	int ret;
> +	ret = rte_eth_link_format(text, 200, fmt, link);

Will it be paranoid to add "text[199] = 0" to be sure any custom 'fmt' won't
cause any harm?

> +	printf("%s", text);

Not sure if the error still should be printed on error case?
Like for example what the code does when fmt="%X"?

> +	return ret;
> +}
> +
> +int
> +rte_eth_link_format(char *str, int32_t len, const char *const fmt,
> +		    struct rte_eth_link *link)

Why not have the 'len' type 'size_t'?

> +	int offset = 0;
> +	int32_t clen = len;
> +	const char *fmt_cur = fmt;
> +	double gbits = (double)link->link_speed / 1000.;
> +	/* TBD: make it international? */
> +	static const char LINK_DOWN_STR[]     = "Link down";
> +	static const char LINK_UP_STR[]       = "Link up at ";
> +	static const char UNKNOWN_SPEED_STR[] = "Unknown speed";
> +	static const char MBITS_STR[]	      = "Mbit/s";
> +	static const char GBITS_STR[]	      = "Gbit/s";
> +	static const char AUTONEG_STR[]       = "Autoneg";
> +	static const char FIXED_STR[]         = "Fixed";
> +	static const char FDX_STR[]           = "FDX";
> +	static const char HDX_STR[]           = "HDX";
> +	static const char UNKNOWN_STR[]       = "Unknown";
> +	static const char UP_STR[]            = "Up";
> +	static const char DOWN_STR[]          = "Down";
> +	if (str == NULL || len == 0)
> +		return -1;
> +	/* default format string, if no fmt is specified */
> +	if (fmt == NULL) {
> +		if (link->link_status == ETH_LINK_DOWN)
> +			return snprintf(str, (size_t)clen, "%s", LINK_DOWN_STR);
> +
> +		offset = snprintf(str, (size_t)clen, "%s", LINK_UP_STR);
> +		if (offset < 0 || (clen - offset) <= 0)
> +			return -1;
> +		clen -= offset;
> +		str += offset;
> +		if (link->link_speed == ETH_SPEED_NUM_UNKNOWN) {
> +			offset = snprintf(str, clen, "%s",
> +					  UNKNOWN_SPEED_STR);
> +			if (offset < 0 || (clen - offset) <= 0)
> +				return -1;

better to use 'strlcpy' & 'strlcat', they are easier to use for these kind of
checks.

<...>

> +	/* Formated status */
> +	} else {
> +		char c = *fmt_cur;
> +		while (c) {
> +			if (clen <= 0)
> +				return -1;
> +			if (c == '%') {
> +				c = *++fmt_cur;
> +				switch (c) {
> +				/* Speed in Mbits/s */
> +				case 'M':
> +					if (link->link_speed ==
> +					    ETH_SPEED_NUM_UNKNOWN)
> +						offset = snprintf(str,
> +						  clen, "%s",
> +						  UNKNOWN_STR);
> +					else
> +						offset = snprintf(str,
> +						  clen, "%u",
> +						  link->link_speed);

Code readiblity is not great here because you hit the 80char limit, this is a
sign that something is wrong like function is already too long.
Can you please try to fix this, like extracting some part of the code to its own
function or return after end of the 'if' statement which can save one more level
indentation etc...

<...>

> diff --git a/lib/librte_ethdev/rte_ethdev.h b/lib/librte_ethdev/rte_ethdev.h
> index 2090af501..83291e656 100644
> --- a/lib/librte_ethdev/rte_ethdev.h
> +++ b/lib/librte_ethdev/rte_ethdev.h
> @@ -2295,6 +2295,58 @@ int rte_eth_link_get(uint16_t port_id, struct rte_eth_link *link);
>   */
>  int rte_eth_link_get_nowait(uint16_t port_id, struct rte_eth_link *link);
>  
> +
> +/**
> + * print formated link status to stdout. This function threats all
> + * special values like ETH_SPEED_NUM_UNKNOWN, ETH_LINK_DOWN etc. and convert
> + * them to textual representation.
> + *
> + * @param fmt
> + *   Format string which allow to format link status. If NULL is provided
> + *   , default formating will be applied.
> + *   Following specifiers are available:
> + *    - '%M' link speed in Mbits/s
> + *    - '%G' link speed in Gbits/s
> + *    - '%S' link status. e.g. Up or Down
> + *    - '%A' link autonegotiation state
> + *    - '%D' link duplex state
> + * @param link
> + *   Link status provided by rte_eth_link_get function
> + * @return
> + *   - Number of bytes written to stdout. In case of error, -1 is returned.

Does it worth to mention the log still will be printed on error?

> + *
> + */
> +int rte_eth_link_printf(const char *const fmt,
> +			struct rte_eth_link *link);
> +
> +/**
> + * Format link status to textual representation. This function threats all
> + * special values like ETH_SPEED_NUM_UNKNOWN, ETH_LINK_DOWN etc. and convert
> + * them to textual representation.
> + *
> + * @param str
> + *   A pointer to a string to be filled with textual representation of
> + *   device status.
> + * @param len
> + *   Length of available memory at 'str' string.
> + * @param fmt
> + *   Format string which allow to format link status. If NULL is provided
> + *   , default formating will be applied.
> + *   Following specifiers are available:
> + *    - '%M' link speed in Mbits/s
> + *    - '%G' link speed in Gbits/s
> + *    - '%S' link status. e.g. Up or Down
> + *    - '%A' link autonegotiation state
> + *    - '%D' link duplex state
> + * @param link
> + *   Link status provided by rte_eth_link_get function
> + * @return
> + *   - Number of bytes written to str array. In case of error, -1 is returned.
> + *
> + */
> +int rte_eth_link_format(char *str, int32_t len, const char *const fmt,
> +			struct rte_eth_link *eth_link);
> +

These new APIs needs to be experimental by process (__rte_experimental).

Need the add these APIs to the .map file (rte_ethdev_version.map), so that they
will be exported in the dynamic library (.so).


^ permalink raw reply	[flat|nested] 359+ messages in thread

* Re: [dpdk-dev] [PATCH v3 1/7] ethdev: allow unknown link speed
  2020-06-15  9:01                               ` [dpdk-dev] [PATCH v3 1/7] " Ivan Dyukov
@ 2020-06-17 16:45                                 ` Ferruh Yigit
  0 siblings, 0 replies; 359+ messages in thread
From: Ferruh Yigit @ 2020-06-17 16:45 UTC (permalink / raw)
  To: i.dyukov, dev, v.kuramshin, thomas, david.marchand, arybchenko,
	wei.zhao1, jia.guo, beilei.xing, qiming.yang, wenzhuo.lu

On 6/15/2020 10:01 AM, Ivan Dyukov wrote:
> From: Thomas Monjalon <thomas@monjalon.net>
> 
> When querying the link information, the link status is
> a mandatory major information.
> Other boolean values are supposed to be accurate:
> 	- duplex mode (half/full)
> 	- negotiation (auto/fixed)
> 
> This API update is making explicit that the link speed information
> is optional.
> The value ETH_SPEED_NUM_NONE (0) was already part of the API.
> The value ETH_SPEED_NUM_UNKNOWN (infinite) is added to cover
> two different cases:
> 	- speed is not known by the driver
> 	- device is virtual
> 
> Suggested-by: Morten Brørup <mb@smartsharesystems.com>
> Suggested-by: Benoit Ganne <bganne@cisco.com>
> Signed-off-by: Thomas Monjalon <thomas@monjalon.net>

Reviewed-by: Ferruh Yigit <ferruh.yigit@intel.com>


^ permalink raw reply	[flat|nested] 359+ messages in thread

* Re: [dpdk-dev] [PATCH v3 3/7] app: UNKNOWN link speed print format
  2020-06-15  9:01                               ` [dpdk-dev] [PATCH v3 3/7] app: UNKNOWN link speed print format Ivan Dyukov
@ 2020-06-17 16:49                                 ` Ferruh Yigit
  0 siblings, 0 replies; 359+ messages in thread
From: Ferruh Yigit @ 2020-06-17 16:49 UTC (permalink / raw)
  To: i.dyukov, dev, v.kuramshin, thomas, david.marchand, arybchenko,
	wei.zhao1, jia.guo, beilei.xing, qiming.yang, wenzhuo.lu

On 6/15/2020 10:01 AM, Ivan Dyukov wrote:
> Add usage of rte_eth_link_format function to example
> applications
> 
> Signed-off-by: Ivan Dyukov <i.dyukov@samsung.com>

<...>

> @@ -155,7 +155,7 @@ static void
>  app_ports_check_link(void)
>  {
>  	uint32_t all_ports_up, i;
> -
> +	char status_text[50];

I think better to add 'link' to variable name to clarify, like 'link_status' as
done in other app, or 'link_status_text' if you prefer, etc...

^ permalink raw reply	[flat|nested] 359+ messages in thread

* Re: [dpdk-dev] [PATCH v3 4/7] doc: update sample app with unknown speed
  2020-06-15  9:01                               ` [dpdk-dev] [PATCH v3 4/7] doc: update sample app with unknown speed Ivan Dyukov
@ 2020-06-17 16:50                                 ` Ferruh Yigit
  0 siblings, 0 replies; 359+ messages in thread
From: Ferruh Yigit @ 2020-06-17 16:50 UTC (permalink / raw)
  To: i.dyukov, dev, v.kuramshin, thomas, david.marchand, arybchenko,
	wei.zhao1, jia.guo, beilei.xing, qiming.yang, wenzhuo.lu

On 6/15/2020 10:01 AM, Ivan Dyukov wrote:
> Add usage of rte_eth_link_format function to example
> applications
> 
> Signed-off-by: Ivan Dyukov <i.dyukov@samsung.com>
> ---
>  doc/guides/sample_app_ug/link_status_intr.rst | 10 +++++-----
>  1 file changed, 5 insertions(+), 5 deletions(-)
> 
> diff --git a/doc/guides/sample_app_ug/link_status_intr.rst b/doc/guides/sample_app_ug/link_status_intr.rst
> index 04c40f285..d1ac35be8 100644
> --- a/doc/guides/sample_app_ug/link_status_intr.rst
> +++ b/doc/guides/sample_app_ug/link_status_intr.rst
> @@ -158,6 +158,7 @@ An example callback function that has been written as indicated below.
>      {
>          struct rte_eth_link link;
>          int ret;
> +        char text[200];

similarly, better to say something like 'link_status' instead of just 'text'.

^ permalink raw reply	[flat|nested] 359+ messages in thread

* Re: [dpdk-dev] [PATCH v3 5/7] net/ixgbe: return unknown speed in status
  2020-06-15  9:01                               ` [dpdk-dev] [PATCH v3 5/7] net/ixgbe: return unknown speed in status Ivan Dyukov
  2020-06-15  9:28                                 ` Zhao1, Wei
@ 2020-06-17 16:50                                 ` Ferruh Yigit
  2020-06-18  1:23                                   ` Zhao1, Wei
  2020-06-20  3:56                                 ` Zhao1, Wei
  2 siblings, 1 reply; 359+ messages in thread
From: Ferruh Yigit @ 2020-06-17 16:50 UTC (permalink / raw)
  To: i.dyukov, dev, v.kuramshin, thomas, david.marchand, arybchenko,
	wei.zhao1, jia.guo, beilei.xing, qiming.yang, wenzhuo.lu

On 6/15/2020 10:01 AM, Ivan Dyukov wrote:
> rte_ethdev has declared new NUM_UNKNOWN speed which
> could be used in case when no speed information is available
> 
> Signed-off-by: Ivan Dyukov <i.dyukov@samsung.com>
> ---
>  drivers/net/ixgbe/ixgbe_ethdev.c | 6 +-----
>  1 file changed, 1 insertion(+), 5 deletions(-)
> 
> diff --git a/drivers/net/ixgbe/ixgbe_ethdev.c b/drivers/net/ixgbe/ixgbe_ethdev.c
> index a4e5c539d..5b9b13058 100644
> --- a/drivers/net/ixgbe/ixgbe_ethdev.c
> +++ b/drivers/net/ixgbe/ixgbe_ethdev.c
> @@ -4311,11 +4311,7 @@ ixgbe_dev_link_update_share(struct rte_eth_dev *dev,
>  	switch (link_speed) {
>  	default:
>  	case IXGBE_LINK_SPEED_UNKNOWN:
> -		if (hw->device_id == IXGBE_DEV_ID_X550EM_A_1G_T ||
> -			hw->device_id == IXGBE_DEV_ID_X550EM_A_1G_T_L)
> -			link.link_speed = ETH_SPEED_NUM_10M;
> -		else
> -			link.link_speed = ETH_SPEED_NUM_100M;
> +		link.link_speed = ETH_SPEED_NUM_UNKNOWN;
>  		break;
>  
>  	case IXGBE_LINK_SPEED_100_FULL:
> 

looks good to me.

^ permalink raw reply	[flat|nested] 359+ messages in thread

* Re: [dpdk-dev] [PATCH v3 6/7] net/i40e: return unknown speed in status
  2020-06-15  9:01                               ` [dpdk-dev] [PATCH v3 6/7] net/i40e: " Ivan Dyukov
@ 2020-06-17 16:52                                 ` Ferruh Yigit
  0 siblings, 0 replies; 359+ messages in thread
From: Ferruh Yigit @ 2020-06-17 16:52 UTC (permalink / raw)
  To: i.dyukov, dev, v.kuramshin, thomas, david.marchand, arybchenko,
	wei.zhao1, jia.guo, beilei.xing, qiming.yang, wenzhuo.lu

On 6/15/2020 10:01 AM, Ivan Dyukov wrote:
> rte_ethdev has declared new NUM_UNKNOWN speed which
> could be used in case when no speed information is available and
> link is up. NUM_NONE should be returned, if link is down.
> 
> Signed-off-by: Ivan Dyukov <i.dyukov@samsung.com>
> ---
>  drivers/net/i40e/i40e_ethdev.c    |  5 ++++-
>  drivers/net/i40e/i40e_ethdev_vf.c | 10 +++++-----
>  2 files changed, 9 insertions(+), 6 deletions(-)
> 
> diff --git a/drivers/net/i40e/i40e_ethdev.c b/drivers/net/i40e/i40e_ethdev.c
> index 749d85f54..d09b77674 100644
> --- a/drivers/net/i40e/i40e_ethdev.c
> +++ b/drivers/net/i40e/i40e_ethdev.c
> @@ -2889,7 +2889,10 @@ update_link_aq(struct i40e_hw *hw, struct rte_eth_link *link,
>  		link->link_speed = ETH_SPEED_NUM_40G;
>  		break;
>  	default:
> -		link->link_speed = ETH_SPEED_NUM_NONE;
> +		if (link->link_status)
> +			link->link_speed = ETH_SPEED_NUM_UNKNOWN;
> +		else
> +			link->link_speed = ETH_SPEED_NUM_NONE;
>  		break;
>  	}
>  }
> diff --git a/drivers/net/i40e/i40e_ethdev_vf.c b/drivers/net/i40e/i40e_ethdev_vf.c
> index bb5d28a44..1da185485 100644
> --- a/drivers/net/i40e/i40e_ethdev_vf.c
> +++ b/drivers/net/i40e/i40e_ethdev_vf.c
> @@ -2165,15 +2165,15 @@ i40evf_dev_link_update(struct rte_eth_dev *dev,
>  		new_link.link_speed = ETH_SPEED_NUM_40G;
>  		break;
>  	default:
> -		new_link.link_speed = ETH_SPEED_NUM_NONE;
> +		if (vf->link_up)
> +			new_link.link_speed = ETH_SPEED_NUM_UNKNOWN;
> +		else
> +			new_link.link_speed = ETH_SPEED_NUM_NONE;
>  		break;
>  	}
>  	/* full duplex only */
>  	new_link.link_duplex = ETH_LINK_FULL_DUPLEX;
> -	new_link.link_status = vf->link_up &&
> -				new_link.link_speed != ETH_SPEED_NUM_NONE
> -				? ETH_LINK_UP
> -				: ETH_LINK_DOWN;
> +	new_link.link_status = vf->link_up ? ETH_LINK_UP : ETH_LINK_DOWN;
>  	new_link.link_autoneg =
>  		!(dev->data->dev_conf.link_speeds & ETH_LINK_SPEED_FIXED);
>  
> 

lgtm

^ permalink raw reply	[flat|nested] 359+ messages in thread

* Re: [dpdk-dev] [PATCH v3 7/7] net/ice: return unknown speed in status
  2020-06-15  9:01                               ` [dpdk-dev] [PATCH v3 7/7] net/ice: " Ivan Dyukov
@ 2020-06-17 16:54                                 ` Ferruh Yigit
  0 siblings, 0 replies; 359+ messages in thread
From: Ferruh Yigit @ 2020-06-17 16:54 UTC (permalink / raw)
  To: i.dyukov, dev, v.kuramshin, thomas, david.marchand, arybchenko,
	wei.zhao1, jia.guo, beilei.xing, qiming.yang, wenzhuo.lu

On 6/15/2020 10:01 AM, Ivan Dyukov wrote:
> rte_ethdev has declared new NUM_UNKNOWN speed which
> could be used in case when no speed information is available and
> link is up. NUM_NONE should be returned, if link is down.
> 
> Signed-off-by: Ivan Dyukov <i.dyukov@samsung.com>
> ---
>  drivers/net/ice/ice_ethdev.c | 5 ++++-
>  1 file changed, 4 insertions(+), 1 deletion(-)
> 
> diff --git a/drivers/net/ice/ice_ethdev.c b/drivers/net/ice/ice_ethdev.c
> index d5110c439..1c0c087ea 100644
> --- a/drivers/net/ice/ice_ethdev.c
> +++ b/drivers/net/ice/ice_ethdev.c
> @@ -3112,8 +3112,11 @@ ice_link_update(struct rte_eth_dev *dev, int wait_to_complete)
>  		link.link_speed = ETH_SPEED_NUM_100G;
>  		break;
>  	case ICE_AQ_LINK_SPEED_UNKNOWN:
> -	default:
>  		PMD_DRV_LOG(ERR, "Unknown link speed");
> +		link.link_speed = ETH_SPEED_NUM_UNKNOWN;
> +		break;
> +	default:
> +		PMD_DRV_LOG(ERR, "None link speed");
>  		link.link_speed = ETH_SPEED_NUM_NONE;
>  		break;
>  	}
> 

Reviewed-by: Ferruh Yigit <ferruh.yigit@intel.com>

^ permalink raw reply	[flat|nested] 359+ messages in thread

* Re: [dpdk-dev] [PATCH v3 5/7] net/ixgbe: return unknown speed in status
  2020-06-17 16:50                                 ` Ferruh Yigit
@ 2020-06-18  1:23                                   ` Zhao1, Wei
  2020-06-18 11:12                                     ` Ferruh Yigit
  0 siblings, 1 reply; 359+ messages in thread
From: Zhao1, Wei @ 2020-06-18  1:23 UTC (permalink / raw)
  To: Yigit, Ferruh, i.dyukov, dev, v.kuramshin, thomas,
	david.marchand, arybchenko, Guo, Jia, Xing, Beilei, Yang, Qiming,
	Lu, Wenzhuo

Hi, ferruh

> -----Original Message-----
> From: Yigit, Ferruh <ferruh.yigit@intel.com>
> Sent: Thursday, June 18, 2020 12:51 AM
> To: i.dyukov@samsung.com; dev@dpdk.org; v.kuramshin@samsung.com;
> thomas@monjalon.net; david.marchand@redhat.com;
> arybchenko@solarflare.com; Zhao1, Wei <wei.zhao1@intel.com>; Guo, Jia
> <jia.guo@intel.com>; Xing, Beilei <beilei.xing@intel.com>; Yang, Qiming
> <qiming.yang@intel.com>; Lu, Wenzhuo <wenzhuo.lu@intel.com>
> Subject: Re: [PATCH v3 5/7] net/ixgbe: return unknown speed in status
> 
> On 6/15/2020 10:01 AM, Ivan Dyukov wrote:
> > rte_ethdev has declared new NUM_UNKNOWN speed which could be used in
> > case when no speed information is available
> >
> > Signed-off-by: Ivan Dyukov <i.dyukov@samsung.com>
> > ---
> >  drivers/net/ixgbe/ixgbe_ethdev.c | 6 +-----
> >  1 file changed, 1 insertion(+), 5 deletions(-)
> >
> > diff --git a/drivers/net/ixgbe/ixgbe_ethdev.c
> > b/drivers/net/ixgbe/ixgbe_ethdev.c
> > index a4e5c539d..5b9b13058 100644
> > --- a/drivers/net/ixgbe/ixgbe_ethdev.c
> > +++ b/drivers/net/ixgbe/ixgbe_ethdev.c
> > @@ -4311,11 +4311,7 @@ ixgbe_dev_link_update_share(struct
> rte_eth_dev *dev,
> >  	switch (link_speed) {
> >  	default:
> >  	case IXGBE_LINK_SPEED_UNKNOWN:
> > -		if (hw->device_id == IXGBE_DEV_ID_X550EM_A_1G_T ||
> > -			hw->device_id == IXGBE_DEV_ID_X550EM_A_1G_T_L)
> > -			link.link_speed = ETH_SPEED_NUM_10M;
> > -		else
> > -			link.link_speed = ETH_SPEED_NUM_100M;

For ixgbe x553(IXGBE_DEV_ID_X550EM_A_1G_T),  we must do some adaption, we can not delete these specific code for the kind of ixgbe nic.


> > +		link.link_speed = ETH_SPEED_NUM_UNKNOWN;
> >  		break;



> >
> >  	case IXGBE_LINK_SPEED_100_FULL:
> >
> 
> looks good to me.

^ permalink raw reply	[flat|nested] 359+ messages in thread

* Re: [dpdk-dev] [PATCH v3 2/7] ethdev: add a link status text representation
  2020-06-17 16:45                                 ` Ferruh Yigit
@ 2020-06-18 10:08                                   ` Ivan Dyukov
  2020-06-18 12:03                                     ` Ferruh Yigit
  0 siblings, 1 reply; 359+ messages in thread
From: Ivan Dyukov @ 2020-06-18 10:08 UTC (permalink / raw)
  To: Ferruh Yigit, dev, v.kuramshin, thomas, david.marchand,
	arybchenko, wei.zhao1, jia.guo, beilei.xing, qiming.yang,
	wenzhuo.lu

Hi Ferruh,

Thank you for the comments.

My answers are inlined.

Best regards,
Ivan
17.06.2020 19:45, Ferruh Yigit пишет:
> On 6/15/2020 10:01 AM, Ivan Dyukov wrote:
>> This commit add function which treat link status structure
>> and format it to text representation.
> If I am following correctly, the initial need was to escape from speed checks
> everytime loging link information caused by this new 'unknown' speed.
>
> And later suggestion was to have a pre-formatted text for link logging.
Correct.
>
> This patch brings additional link status printing/formatting capability with
> custom format string support and with new format specifiers for link (like, '%D'
> link duplex state),
> although this is nice work and thanks for it, I am not sure this complexity and
> two new APIs are really needed.
Yep.
> For me only 'rte_eth_link_format()' without custom format support looks good
> enough but I won't object if the concensus is to have them.
> I am aware there are multiple applications you are updating logging slightly
> different which requires this flexibility but what happens if they use same
> pre-formatted text, is that difference really required or happened by time based
> on developers taste?
I have changed only few applications but I have plan to change all dpdk 
examples. Even in those few apps, we have various link status logging 
text. e.g  app/test-pmd/config.c
@@ -600,10 +600,9 @@ port_infos_display(portid_t port_id)
         } else
                 printf("\nmemory allocation on the socket: 
%u",port->socket_id);

-       printf("\nLink status: %s\n", (link.link_status) ? ("up") : 
("down"));
-       printf("Link speed: %u Mbps\n", (unsigned) link.link_speed);
-       printf("Link duplex: %s\n", (link.link_duplex == 
ETH_LINK_FULL_DUPLEX) ?
-              ("full-duplex") : ("half-duplex"));
+       rte_eth_link_printf("\nLink status: %S\n"
+                           "Link speed: %M Mbps\n"
+                           "Link duplex: %D\n", &link);
the status is logged in 3 lines. this is special text layoting and I 
don't know how it will look in one line. Myabe it will require reformat 
all screen. I don't want to change screen layoting in this patchset.

> I will put some comments below in any case.
>
>> Signed-off-by: Ivan Dyukov <i.dyukov@samsung.com>
> <...>
>
>> @@ -249,6 +249,9 @@ SRCS-$(CONFIG_RTE_LIBRTE_SECURITY) += test_security.c
>>   
>>   SRCS-$(CONFIG_RTE_LIBRTE_IPSEC) += test_ipsec.c test_ipsec_perf.c
>>   SRCS-$(CONFIG_RTE_LIBRTE_IPSEC) += test_ipsec_sad.c
>> +
>> +SRCS-$(CONFIG_RTE_LIBRTE_ETHER) += test_ethdev_link.c
> +1 to unit test.
>
> <...>
>
>> +int
>> +rte_eth_link_printf(const char *const fmt,
>> +		    struct rte_eth_link *link)
>> +{
>> +	char text[200];
>> +	int ret;
>> +	ret = rte_eth_link_format(text, 200, fmt, link);
> Will it be paranoid to add "text[199] = 0" to be sure any custom 'fmt' won't
> cause any harm?

rte_eth_link_format already do that and it must do that. I would prefer to don't hide rte_eth_link_format bugs in rte_eth_link_printf function.

>
>> +	printf("%s", text);
> Not sure if the error still should be printed on error case?
> Like for example what the code does when fmt="%X"?
yep. I'll add 'ret' check.
>
>> +	return ret;
>> +}
>> +
>> +int
>> +rte_eth_link_format(char *str, int32_t len, const char *const fmt,
>> +		    struct rte_eth_link *link)
> Why not have the 'len' type 'size_t'?

Yes, I can change type of the len but internally we have 'int32_t clen = 
len;'

defined below.  clen should be signed variable because rte_eth_link_format

much more simpler then snprintf. e.g. snprintf may be called with

snprintf(buff, 0, "some text %d", val); no errors returned in this case.

it returns length of formated string.so internally I use signed clen

to detect end of line and avoid uint overflow.

rte_eth_link_format with incorrect or short buffer returns error.

>
>> +	int offset = 0;
>> +	int32_t clen = len;
>> +	const char *fmt_cur = fmt;
>> +	double gbits = (double)link->link_speed / 1000.;
>> +	/* TBD: make it international? */
>> +	static const char LINK_DOWN_STR[]     = "Link down";
>> +	static const char LINK_UP_STR[]       = "Link up at ";
>> +	static const char UNKNOWN_SPEED_STR[] = "Unknown speed";
>> +	static const char MBITS_STR[]	      = "Mbit/s";
>> +	static const char GBITS_STR[]	      = "Gbit/s";
>> +	static const char AUTONEG_STR[]       = "Autoneg";
>> +	static const char FIXED_STR[]         = "Fixed";
>> +	static const char FDX_STR[]           = "FDX";
>> +	static const char HDX_STR[]           = "HDX";
>> +	static const char UNKNOWN_STR[]       = "Unknown";
>> +	static const char UP_STR[]            = "Up";
>> +	static const char DOWN_STR[]          = "Down";
>> +	if (str == NULL || len == 0)
>> +		return -1;
>> +	/* default format string, if no fmt is specified */
>> +	if (fmt == NULL) {
>> +		if (link->link_status == ETH_LINK_DOWN)
>> +			return snprintf(str, (size_t)clen, "%s", LINK_DOWN_STR);
>> +
>> +		offset = snprintf(str, (size_t)clen, "%s", LINK_UP_STR);
>> +		if (offset < 0 || (clen - offset) <= 0)
>> +			return -1;
>> +		clen -= offset;
>> +		str += offset;
>> +		if (link->link_speed == ETH_SPEED_NUM_UNKNOWN) {
>> +			offset = snprintf(str, clen, "%s",
>> +					  UNKNOWN_SPEED_STR);
>> +			if (offset < 0 || (clen - offset) <= 0)
>> +				return -1;
> better to use 'strlcpy' & 'strlcat', they are easier to use for these kind of
> checks.
OK
>
> <...>
>
>> +	/* Formated status */
>> +	} else {
>> +		char c = *fmt_cur;
>> +		while (c) {
>> +			if (clen <= 0)
>> +				return -1;
>> +			if (c == '%') {
>> +				c = *++fmt_cur;
>> +				switch (c) {
>> +				/* Speed in Mbits/s */
>> +				case 'M':
>> +					if (link->link_speed ==
>> +					    ETH_SPEED_NUM_UNKNOWN)
>> +						offset = snprintf(str,
>> +						  clen, "%s",
>> +						  UNKNOWN_STR);
>> +					else
>> +						offset = snprintf(str,
>> +						  clen, "%u",
>> +						  link->link_speed);
> Code readiblity is not great here because you hit the 80char limit, this is a
> sign that something is wrong like function is already too long.
> Can you please try to fix this, like extracting some part of the code to its own
> function or return after end of the 'if' statement which can save one more level
> indentation etc...
agree. I'll define one static function and move part of the code to it. 
It should reduce indent.
>
> <...>
>
>> diff --git a/lib/librte_ethdev/rte_ethdev.h b/lib/librte_ethdev/rte_ethdev.h
>> index 2090af501..83291e656 100644
>> --- a/lib/librte_ethdev/rte_ethdev.h
>> +++ b/lib/librte_ethdev/rte_ethdev.h
>> @@ -2295,6 +2295,58 @@ int rte_eth_link_get(uint16_t port_id, struct rte_eth_link *link);
>>    */
>>   int rte_eth_link_get_nowait(uint16_t port_id, struct rte_eth_link *link);
>>   
>> +
>> +/**
>> + * print formated link status to stdout. This function threats all
>> + * special values like ETH_SPEED_NUM_UNKNOWN, ETH_LINK_DOWN etc. and convert
>> + * them to textual representation.
>> + *
>> + * @param fmt
>> + *   Format string which allow to format link status. If NULL is provided
>> + *   , default formating will be applied.
>> + *   Following specifiers are available:
>> + *    - '%M' link speed in Mbits/s
>> + *    - '%G' link speed in Gbits/s
>> + *    - '%S' link status. e.g. Up or Down
>> + *    - '%A' link autonegotiation state
>> + *    - '%D' link duplex state
>> + * @param link
>> + *   Link status provided by rte_eth_link_get function
>> + * @return
>> + *   - Number of bytes written to stdout. In case of error, -1 is returned.
> Does it worth to mention the log still will be printed on error?
I'll change the function. It will print nothing on error.
>
>> + *
>> + */
>> +int rte_eth_link_printf(const char *const fmt,
>> +			struct rte_eth_link *link);
>> +
>> +/**
>> + * Format link status to textual representation. This function threats all
>> + * special values like ETH_SPEED_NUM_UNKNOWN, ETH_LINK_DOWN etc. and convert
>> + * them to textual representation.
>> + *
>> + * @param str
>> + *   A pointer to a string to be filled with textual representation of
>> + *   device status.
>> + * @param len
>> + *   Length of available memory at 'str' string.
>> + * @param fmt
>> + *   Format string which allow to format link status. If NULL is provided
>> + *   , default formating will be applied.
>> + *   Following specifiers are available:
>> + *    - '%M' link speed in Mbits/s
>> + *    - '%G' link speed in Gbits/s
>> + *    - '%S' link status. e.g. Up or Down
>> + *    - '%A' link autonegotiation state
>> + *    - '%D' link duplex state
>> + * @param link
>> + *   Link status provided by rte_eth_link_get function
>> + * @return
>> + *   - Number of bytes written to str array. In case of error, -1 is returned.
>> + *
>> + */
>> +int rte_eth_link_format(char *str, int32_t len, const char *const fmt,
>> +			struct rte_eth_link *eth_link);
>> +
> These new APIs needs to be experimental by process (__rte_experimental).
>
> Need the add these APIs to the .map file (rte_ethdev_version.map), so that they
> will be exported in the dynamic library (.so).
>
>


^ permalink raw reply	[flat|nested] 359+ messages in thread

* Re: [dpdk-dev] [PATCH v3 5/7] net/ixgbe: return unknown speed in status
  2020-06-18  1:23                                   ` Zhao1, Wei
@ 2020-06-18 11:12                                     ` Ferruh Yigit
  2020-06-20  3:53                                       ` Zhao1, Wei
  0 siblings, 1 reply; 359+ messages in thread
From: Ferruh Yigit @ 2020-06-18 11:12 UTC (permalink / raw)
  To: Zhao1, Wei, i.dyukov, dev, v.kuramshin, thomas, david.marchand,
	arybchenko, Guo, Jia, Xing, Beilei, Yang, Qiming, Lu, Wenzhuo

On 6/18/2020 2:23 AM, Zhao1, Wei wrote:
> Hi, ferruh
> 
>> -----Original Message-----
>> From: Yigit, Ferruh <ferruh.yigit@intel.com>
>> Sent: Thursday, June 18, 2020 12:51 AM
>> To: i.dyukov@samsung.com; dev@dpdk.org; v.kuramshin@samsung.com;
>> thomas@monjalon.net; david.marchand@redhat.com;
>> arybchenko@solarflare.com; Zhao1, Wei <wei.zhao1@intel.com>; Guo, Jia
>> <jia.guo@intel.com>; Xing, Beilei <beilei.xing@intel.com>; Yang, Qiming
>> <qiming.yang@intel.com>; Lu, Wenzhuo <wenzhuo.lu@intel.com>
>> Subject: Re: [PATCH v3 5/7] net/ixgbe: return unknown speed in status
>>
>> On 6/15/2020 10:01 AM, Ivan Dyukov wrote:
>>> rte_ethdev has declared new NUM_UNKNOWN speed which could be used in
>>> case when no speed information is available
>>>
>>> Signed-off-by: Ivan Dyukov <i.dyukov@samsung.com>
>>> ---
>>>  drivers/net/ixgbe/ixgbe_ethdev.c | 6 +-----
>>>  1 file changed, 1 insertion(+), 5 deletions(-)
>>>
>>> diff --git a/drivers/net/ixgbe/ixgbe_ethdev.c
>>> b/drivers/net/ixgbe/ixgbe_ethdev.c
>>> index a4e5c539d..5b9b13058 100644
>>> --- a/drivers/net/ixgbe/ixgbe_ethdev.c
>>> +++ b/drivers/net/ixgbe/ixgbe_ethdev.c
>>> @@ -4311,11 +4311,7 @@ ixgbe_dev_link_update_share(struct
>> rte_eth_dev *dev,
>>>  switch (link_speed) {
>>>  default:
>>>  case IXGBE_LINK_SPEED_UNKNOWN:
>>> -if (hw->device_id == IXGBE_DEV_ID_X550EM_A_1G_T ||
>>> -hw->device_id == IXGBE_DEV_ID_X550EM_A_1G_T_L)
>>> -link.link_speed = ETH_SPEED_NUM_10M;
>>> -else
>>> -link.link_speed = ETH_SPEED_NUM_100M;
> 
> For ixgbe x553(IXGBE_DEV_ID_X550EM_A_1G_T),  we must do some adaption, we can not delete these specific code for the kind of ixgbe nic.

Hi Wei,

These checks are done when 'link_speed' is 'IXGBE_LINK_SPEED_UNKNOWN'.

I assume we are setting some default values based on device type when link speed
is unknown. Using new 'ETH_SPEED_NUM_UNKNOWN' type when link speed is unknown
can be more accurate.

For 'IXGBE_DEV_ID_X550EM_A_1G_T', is link speed 'IXGBE_LINK_SPEED_UNKNOWN'
explicitly means 'ETH_SPEED_NUM_10M'?
If so why it doesn't return 'IXGBE_LINK_SPEED_10_FULL' instead?


> 
> 
>>> +link.link_speed = ETH_SPEED_NUM_UNKNOWN;
>>>  break;
> 
> 
> 
>>>
>>>  case IXGBE_LINK_SPEED_100_FULL:
>>>
>>
>> looks good to me.


^ permalink raw reply	[flat|nested] 359+ messages in thread

* Re: [dpdk-dev] [PATCH v3 2/7] ethdev: add a link status text representation
  2020-06-18 10:08                                   ` Ivan Dyukov
@ 2020-06-18 12:03                                     ` Ferruh Yigit
  2020-06-18 12:32                                       ` [dpdk-dev] [PATCH v3 2/7] ethdev: add a link status textrepresentation Morten Brørup
  0 siblings, 1 reply; 359+ messages in thread
From: Ferruh Yigit @ 2020-06-18 12:03 UTC (permalink / raw)
  To: Ivan Dyukov, dev, v.kuramshin, thomas, david.marchand,
	arybchenko, wei.zhao1, jia.guo, beilei.xing, qiming.yang,
	wenzhuo.lu, Morten Brørup, Stephen Hemminger

On 6/18/2020 11:08 AM, Ivan Dyukov wrote:
> Hi Ferruh,
> 
> Thank you for the comments.
> 
> My answers are inlined.
> 
> Best regards,
> Ivan
> 17.06.2020 19:45, Ferruh Yigit пишет:
>> On 6/15/2020 10:01 AM, Ivan Dyukov wrote:
>>> This commit add function which treat link status structure
>>> and format it to text representation.
>> If I am following correctly, the initial need was to escape from speed checks
>> everytime loging link information caused by this new 'unknown' speed.
>>
>> And later suggestion was to have a pre-formatted text for link logging.
> Correct.
>>
>> This patch brings additional link status printing/formatting capability with
>> custom format string support and with new format specifiers for link (like, '%D'
>> link duplex state),
>> although this is nice work and thanks for it, I am not sure this complexity and
>> two new APIs are really needed.
> Yep.
>> For me only 'rte_eth_link_format()' without custom format support looks good
>> enough but I won't object if the concensus is to have them.
>> I am aware there are multiple applications you are updating logging slightly
>> different which requires this flexibility but what happens if they use same
>> pre-formatted text, is that difference really required or happened by time based
>> on developers taste?
> I have changed only few applications but I have plan to change all dpdk 
> examples. Even in those few apps, we have various link status logging 
> text. e.g  app/test-pmd/config.c
> @@ -600,10 +600,9 @@ port_infos_display(portid_t port_id)
>          } else
>                  printf("\nmemory allocation on the socket: 
> %u",port->socket_id);
> 
> -       printf("\nLink status: %s\n", (link.link_status) ? ("up") : 
> ("down"));
> -       printf("Link speed: %u Mbps\n", (unsigned) link.link_speed);
> -       printf("Link duplex: %s\n", (link.link_duplex == 
> ETH_LINK_FULL_DUPLEX) ?
> -              ("full-duplex") : ("half-duplex"));
> +       rte_eth_link_printf("\nLink status: %S\n"
> +                           "Link speed: %M Mbps\n"
> +                           "Link duplex: %D\n", &link);
> the status is logged in 3 lines. this is special text layoting and I 
> don't know how it will look in one line. Myabe it will require reformat 
> all screen. I don't want to change screen layoting in this patchset.

cc'ed Morten & Stephen.

To keep existing layout in the applications yes you need more flexibility, a
pre-formatted text won't cut it, but I guess I prefer your approach in v2 for
simplicity.

And I would prefer extending the one in v2 with a larger string for the
pre-formatted text, so both flexibility and the standard output can be provided,
Morten didn't like it but if I understand correctly his comment was to keep more
simple solution in ethdev and applications can do it themselves if they want
more custom log formatting, but this patch adds more complex and flexible
logging support to the ethdev.

> 
>> I will put some comments below in any case.
>>
>>> Signed-off-by: Ivan Dyukov <i.dyukov@samsung.com>
>> <...>
>>
>>> @@ -249,6 +249,9 @@ SRCS-$(CONFIG_RTE_LIBRTE_SECURITY) += test_security.c
>>>   
>>>   SRCS-$(CONFIG_RTE_LIBRTE_IPSEC) += test_ipsec.c test_ipsec_perf.c
>>>   SRCS-$(CONFIG_RTE_LIBRTE_IPSEC) += test_ipsec_sad.c
>>> +
>>> +SRCS-$(CONFIG_RTE_LIBRTE_ETHER) += test_ethdev_link.c
>> +1 to unit test.
>>
>> <...>
>>
>>> +int
>>> +rte_eth_link_printf(const char *const fmt,
>>> +		    struct rte_eth_link *link)
>>> +{
>>> +	char text[200];
>>> +	int ret;
>>> +	ret = rte_eth_link_format(text, 200, fmt, link);
>> Will it be paranoid to add "text[199] = 0" to be sure any custom 'fmt' won't
>> cause any harm?
> 
> rte_eth_link_format already do that and it must do that. I would prefer to don't hide rte_eth_link_format bugs in rte_eth_link_printf function.

OK, makes sense.

What do you think putting an assert (RTE_ASSERT) to check that formatted buffer
is proper C string?

> 
>>
>>> +	printf("%s", text);
>> Not sure if the error still should be printed on error case?
>> Like for example what the code does when fmt="%X"?
> yep. I'll add 'ret' check.
>>
>>> +	return ret;
>>> +}
>>> +
>>> +int
>>> +rte_eth_link_format(char *str, int32_t len, const char *const fmt,
>>> +		    struct rte_eth_link *link)
>> Why not have the 'len' type 'size_t'?
> 
> Yes, I can change type of the len but internally we have 'int32_t clen = 
> len;'
> defined below.  clen should be signed variable because rte_eth_link_format
> much more simpler then snprintf. e.g. snprintf may be called with
> snprintf(buff, 0, "some text %d", val); no errors returned in this case.
> it returns length of formated string.so internally I use signed clen
> to detect end of line and avoid uint overflow.
> rte_eth_link_format with incorrect or short buffer returns error.

I see, using 'strlcat' and 'strlcpy' may help here, since both does get full
size of the buffer as parameter which removes the need of offset calculations
and possible negative values there. And both returns positive values, again
prevents using signed variables to capture return value.
So I think this can make possible to only use size_t variable as length.

> 
>>
>>> +	int offset = 0;
>>> +	int32_t clen = len;
>>> +	const char *fmt_cur = fmt;
>>> +	double gbits = (double)link->link_speed / 1000.;
>>> +	/* TBD: make it international? */
>>> +	static const char LINK_DOWN_STR[]     = "Link down";
>>> +	static const char LINK_UP_STR[]       = "Link up at ";
>>> +	static const char UNKNOWN_SPEED_STR[] = "Unknown speed";
>>> +	static const char MBITS_STR[]	      = "Mbit/s";
>>> +	static const char GBITS_STR[]	      = "Gbit/s";
>>> +	static const char AUTONEG_STR[]       = "Autoneg";
>>> +	static const char FIXED_STR[]         = "Fixed";
>>> +	static const char FDX_STR[]           = "FDX";
>>> +	static const char HDX_STR[]           = "HDX";
>>> +	static const char UNKNOWN_STR[]       = "Unknown";
>>> +	static const char UP_STR[]            = "Up";
>>> +	static const char DOWN_STR[]          = "Down";
>>> +	if (str == NULL || len == 0)
>>> +		return -1;
>>> +	/* default format string, if no fmt is specified */
>>> +	if (fmt == NULL) {
>>> +		if (link->link_status == ETH_LINK_DOWN)
>>> +			return snprintf(str, (size_t)clen, "%s", LINK_DOWN_STR);
>>> +
>>> +		offset = snprintf(str, (size_t)clen, "%s", LINK_UP_STR);
>>> +		if (offset < 0 || (clen - offset) <= 0)
>>> +			return -1;
>>> +		clen -= offset;
>>> +		str += offset;
>>> +		if (link->link_speed == ETH_SPEED_NUM_UNKNOWN) {
>>> +			offset = snprintf(str, clen, "%s",
>>> +					  UNKNOWN_SPEED_STR);
>>> +			if (offset < 0 || (clen - offset) <= 0)
>>> +				return -1;
>> better to use 'strlcpy' & 'strlcat', they are easier to use for these kind of
>> checks.
> OK
>>
>> <...>
>>
>>> +	/* Formated status */
>>> +	} else {
>>> +		char c = *fmt_cur;
>>> +		while (c) {
>>> +			if (clen <= 0)
>>> +				return -1;
>>> +			if (c == '%') {
>>> +				c = *++fmt_cur;
>>> +				switch (c) {
>>> +				/* Speed in Mbits/s */
>>> +				case 'M':
>>> +					if (link->link_speed ==
>>> +					    ETH_SPEED_NUM_UNKNOWN)
>>> +						offset = snprintf(str,
>>> +						  clen, "%s",
>>> +						  UNKNOWN_STR);
>>> +					else
>>> +						offset = snprintf(str,
>>> +						  clen, "%u",
>>> +						  link->link_speed);
>> Code readiblity is not great here because you hit the 80char limit, this is a
>> sign that something is wrong like function is already too long.
>> Can you please try to fix this, like extracting some part of the code to its own
>> function or return after end of the 'if' statement which can save one more level
>> indentation etc...
> agree. I'll define one static function and move part of the code to it. 
> It should reduce indent.
>>
>> <...>
>>
>>> diff --git a/lib/librte_ethdev/rte_ethdev.h b/lib/librte_ethdev/rte_ethdev.h
>>> index 2090af501..83291e656 100644
>>> --- a/lib/librte_ethdev/rte_ethdev.h
>>> +++ b/lib/librte_ethdev/rte_ethdev.h
>>> @@ -2295,6 +2295,58 @@ int rte_eth_link_get(uint16_t port_id, struct rte_eth_link *link);
>>>    */
>>>   int rte_eth_link_get_nowait(uint16_t port_id, struct rte_eth_link *link);
>>>   
>>> +
>>> +/**
>>> + * print formated link status to stdout. This function threats all
>>> + * special values like ETH_SPEED_NUM_UNKNOWN, ETH_LINK_DOWN etc. and convert
>>> + * them to textual representation.
>>> + *
>>> + * @param fmt
>>> + *   Format string which allow to format link status. If NULL is provided
>>> + *   , default formating will be applied.
>>> + *   Following specifiers are available:
>>> + *    - '%M' link speed in Mbits/s
>>> + *    - '%G' link speed in Gbits/s
>>> + *    - '%S' link status. e.g. Up or Down
>>> + *    - '%A' link autonegotiation state
>>> + *    - '%D' link duplex state
>>> + * @param link
>>> + *   Link status provided by rte_eth_link_get function
>>> + * @return
>>> + *   - Number of bytes written to stdout. In case of error, -1 is returned.
>> Does it worth to mention the log still will be printed on error?
> I'll change the function. It will print nothing on error.
>>
>>> + *
>>> + */
>>> +int rte_eth_link_printf(const char *const fmt,
>>> +			struct rte_eth_link *link);
>>> +
>>> +/**
>>> + * Format link status to textual representation. This function threats all
>>> + * special values like ETH_SPEED_NUM_UNKNOWN, ETH_LINK_DOWN etc. and convert
>>> + * them to textual representation.
>>> + *
>>> + * @param str
>>> + *   A pointer to a string to be filled with textual representation of
>>> + *   device status.
>>> + * @param len
>>> + *   Length of available memory at 'str' string.
>>> + * @param fmt
>>> + *   Format string which allow to format link status. If NULL is provided
>>> + *   , default formating will be applied.
>>> + *   Following specifiers are available:
>>> + *    - '%M' link speed in Mbits/s
>>> + *    - '%G' link speed in Gbits/s
>>> + *    - '%S' link status. e.g. Up or Down
>>> + *    - '%A' link autonegotiation state
>>> + *    - '%D' link duplex state
>>> + * @param link
>>> + *   Link status provided by rte_eth_link_get function
>>> + * @return
>>> + *   - Number of bytes written to str array. In case of error, -1 is returned.
>>> + *
>>> + */
>>> +int rte_eth_link_format(char *str, int32_t len, const char *const fmt,
>>> +			struct rte_eth_link *eth_link);
>>> +
>> These new APIs needs to be experimental by process (__rte_experimental).
>>
>> Need the add these APIs to the .map file (rte_ethdev_version.map), so that they
>> will be exported in the dynamic library (.so).
>>
>>
> 


^ permalink raw reply	[flat|nested] 359+ messages in thread

* Re: [dpdk-dev] [PATCH v3 2/7] ethdev: add a link status textrepresentation
  2020-06-18 12:03                                     ` Ferruh Yigit
@ 2020-06-18 12:32                                       ` Morten Brørup
  2020-06-22  7:05                                         ` Ferruh Yigit
  0 siblings, 1 reply; 359+ messages in thread
From: Morten Brørup @ 2020-06-18 12:32 UTC (permalink / raw)
  To: Ferruh Yigit, Ivan Dyukov, dev, v.kuramshin, thomas,
	david.marchand, arybchenko, wei.zhao1, jia.guo, beilei.xing,
	qiming.yang, wenzhuo.lu, Stephen Hemminger

> From: dev [mailto:dev-bounces@dpdk.org] On Behalf Of Ferruh Yigit
> Sent: Thursday, June 18, 2020 2:03 PM
> 
> On 6/18/2020 11:08 AM, Ivan Dyukov wrote:
> > Hi Ferruh,
> >
> > Thank you for the comments.
> >
> > My answers are inlined.
> >
> > Best regards,
> > Ivan
> > 17.06.2020 19:45, Ferruh Yigit пишет:
> >> On 6/15/2020 10:01 AM, Ivan Dyukov wrote:
> >>> This commit add function which treat link status structure
> >>> and format it to text representation.
> >> If I am following correctly, the initial need was to escape from
> speed checks
> >> everytime loging link information caused by this new 'unknown'
> speed.
> >>
> >> And later suggestion was to have a pre-formatted text for link
> logging.
> > Correct.
> >>
> >> This patch brings additional link status printing/formatting
> capability with
> >> custom format string support and with new format specifiers for link
> (like, '%D'
> >> link duplex state),
> >> although this is nice work and thanks for it, I am not sure this
> complexity and
> >> two new APIs are really needed.
> > Yep.
> >> For me only 'rte_eth_link_format()' without custom format support
> looks good
> >> enough but I won't object if the concensus is to have them.
> >> I am aware there are multiple applications you are updating logging
> slightly
> >> different which requires this flexibility but what happens if they
> use same
> >> pre-formatted text, is that difference really required or happened
> by time based
> >> on developers taste?
> > I have changed only few applications but I have plan to change all
> dpdk
> > examples. Even in those few apps, we have various link status logging
> > text. e.g  app/test-pmd/config.c
> > @@ -600,10 +600,9 @@ port_infos_display(portid_t port_id)
> >          } else
> >                  printf("\nmemory allocation on the socket:
> > %u",port->socket_id);
> >
> > -       printf("\nLink status: %s\n", (link.link_status) ? ("up") :
> > ("down"));
> > -       printf("Link speed: %u Mbps\n", (unsigned) link.link_speed);
> > -       printf("Link duplex: %s\n", (link.link_duplex ==
> > ETH_LINK_FULL_DUPLEX) ?
> > -              ("full-duplex") : ("half-duplex"));
> > +       rte_eth_link_printf("\nLink status: %S\n"
> > +                           "Link speed: %M Mbps\n"
> > +                           "Link duplex: %D\n", &link);
> > the status is logged in 3 lines. this is special text layoting and I
> > don't know how it will look in one line. Myabe it will require
> reformat
> > all screen. I don't want to change screen layoting in this patchset.
> 
> cc'ed Morten & Stephen.
> 
> To keep existing layout in the applications yes you need more
> flexibility, a
> pre-formatted text won't cut it, but I guess I prefer your approach in
> v2 for
> simplicity.
> 
> And I would prefer extending the one in v2 with a larger string for the
> pre-formatted text, so both flexibility and the standard output can be
> provided,
> Morten didn't like it but if I understand correctly his comment was to
> keep more
> simple solution in ethdev and applications can do it themselves if they
> want
> more custom log formatting, but this patch adds more complex and
> flexible
> logging support to the ethdev.
> 

If you are going to add a flexible link status formatting function, like strftime(), it should not print to stdout, but to a string buffer, like strftime(). It will also allow for new format specifiers in the future, e.g. %1D for "FDX"/"HDX", %2D for "Full"/"Half" or %3D for "full-duplex"/"half-duplex". This would provide more flexible support for a larger number of application specific formats.

Then the function for printing to stdout in a DPDK preferred format (if you add such a function to the library) can use the above eth_link_strf() function.



^ permalink raw reply	[flat|nested] 359+ messages in thread

* Re: [dpdk-dev] [PATCH v3 5/7] net/ixgbe: return unknown speed in status
  2020-06-18 11:12                                     ` Ferruh Yigit
@ 2020-06-20  3:53                                       ` Zhao1, Wei
  0 siblings, 0 replies; 359+ messages in thread
From: Zhao1, Wei @ 2020-06-20  3:53 UTC (permalink / raw)
  To: Yigit, Ferruh, i.dyukov, dev, v.kuramshin, thomas,
	david.marchand, arybchenko, Guo, Jia, Xing, Beilei, Yang, Qiming,
	Lu, Wenzhuo

Hi, Ferruh

> -----Original Message-----
> From: Yigit, Ferruh <ferruh.yigit@intel.com>
> Sent: Thursday, June 18, 2020 7:12 PM
> To: Zhao1, Wei <wei.zhao1@intel.com>; i.dyukov@samsung.com;
> dev@dpdk.org; v.kuramshin@samsung.com; thomas@monjalon.net;
> david.marchand@redhat.com; arybchenko@solarflare.com; Guo, Jia
> <jia.guo@intel.com>; Xing, Beilei <beilei.xing@intel.com>; Yang, Qiming
> <qiming.yang@intel.com>; Lu, Wenzhuo <wenzhuo.lu@intel.com>
> Subject: Re: [PATCH v3 5/7] net/ixgbe: return unknown speed in status
> 
> On 6/18/2020 2:23 AM, Zhao1, Wei wrote:
> > Hi, ferruh
> >
> >> -----Original Message-----
> >> From: Yigit, Ferruh <ferruh.yigit@intel.com>
> >> Sent: Thursday, June 18, 2020 12:51 AM
> >> To: i.dyukov@samsung.com; dev@dpdk.org; v.kuramshin@samsung.com;
> >> thomas@monjalon.net; david.marchand@redhat.com;
> >> arybchenko@solarflare.com; Zhao1, Wei <wei.zhao1@intel.com>; Guo, Jia
> >> <jia.guo@intel.com>; Xing, Beilei <beilei.xing@intel.com>; Yang,
> >> Qiming <qiming.yang@intel.com>; Lu, Wenzhuo <wenzhuo.lu@intel.com>
> >> Subject: Re: [PATCH v3 5/7] net/ixgbe: return unknown speed in status
> >>
> >> On 6/15/2020 10:01 AM, Ivan Dyukov wrote:
> >>> rte_ethdev has declared new NUM_UNKNOWN speed which could be used
> in
> >>> case when no speed information is available
> >>>
> >>> Signed-off-by: Ivan Dyukov <i.dyukov@samsung.com>
> >>> ---
> >>>  drivers/net/ixgbe/ixgbe_ethdev.c | 6 +-----
> >>>  1 file changed, 1 insertion(+), 5 deletions(-)
> >>>
> >>> diff --git a/drivers/net/ixgbe/ixgbe_ethdev.c
> >>> b/drivers/net/ixgbe/ixgbe_ethdev.c
> >>> index a4e5c539d..5b9b13058 100644
> >>> --- a/drivers/net/ixgbe/ixgbe_ethdev.c
> >>> +++ b/drivers/net/ixgbe/ixgbe_ethdev.c
> >>> @@ -4311,11 +4311,7 @@ ixgbe_dev_link_update_share(struct
> >> rte_eth_dev *dev,
> >>>  switch (link_speed) {
> >>>  default:
> >>>  case IXGBE_LINK_SPEED_UNKNOWN:
> >>> -if (hw->device_id == IXGBE_DEV_ID_X550EM_A_1G_T ||
> >>> -hw->device_id == IXGBE_DEV_ID_X550EM_A_1G_T_L)
> >>> -link.link_speed = ETH_SPEED_NUM_10M; -else -link.link_speed =
> >>> ETH_SPEED_NUM_100M;
> >
> > For ixgbe x553(IXGBE_DEV_ID_X550EM_A_1G_T),  we must do some
> adaption, we can not delete these specific code for the kind of ixgbe nic.
> 
> Hi Wei,
> 
> These checks are done when 'link_speed' is 'IXGBE_LINK_SPEED_UNKNOWN'.
> 
> I assume we are setting some default values based on device type when link
> speed is unknown. Using new 'ETH_SPEED_NUM_UNKNOWN' type when link
> speed is unknown can be more accurate.
> 
> For 'IXGBE_DEV_ID_X550EM_A_1G_T', is link speed
> 'IXGBE_LINK_SPEED_UNKNOWN'
> explicitly means 'ETH_SPEED_NUM_10M'?
> If so why it doesn't return 'IXGBE_LINK_SPEED_10_FULL' instead?


After do a double check, it seems base code ixgbe_check_mac_link_generic() has do the adaption, 
		if (hw->device_id == IXGBE_DEV_ID_X550EM_A_1G_T ||
		    hw->device_id == IXGBE_DEV_ID_X550EM_A_1G_T_L)
			*speed = IXGBE_LINK_SPEED_10_FULL;
so we only need do some upodate in ixgbe_dev_link_update_share(), add the case IXGBE_LINK_SPEED_10_FULL.
So, this patch set is ok now, I think.


> 
> 
> >
> >
> >>> +link.link_speed = ETH_SPEED_NUM_UNKNOWN;
> >>>  break;
> >
> >
> >
> >>>
> >>>  case IXGBE_LINK_SPEED_100_FULL:
> >>>
> >>
> >> looks good to me.


^ permalink raw reply	[flat|nested] 359+ messages in thread

* Re: [dpdk-dev] [PATCH v3 5/7] net/ixgbe: return unknown speed in status
  2020-06-15  9:01                               ` [dpdk-dev] [PATCH v3 5/7] net/ixgbe: return unknown speed in status Ivan Dyukov
  2020-06-15  9:28                                 ` Zhao1, Wei
  2020-06-17 16:50                                 ` Ferruh Yigit
@ 2020-06-20  3:56                                 ` Zhao1, Wei
  2 siblings, 0 replies; 359+ messages in thread
From: Zhao1, Wei @ 2020-06-20  3:56 UTC (permalink / raw)
  To: i.dyukov, dev, v.kuramshin, thomas, david.marchand, Yigit,
	Ferruh, arybchenko, Guo, Jia, Xing, Beilei, Yang, Qiming, Lu,
	Wenzhuo


Reviewed-by: Wei Zhao <wei.zhao1@intel.com>

> -----Original Message-----
> From: Ivan Dyukov <i.dyukov@samsung.com>
> Sent: Monday, June 15, 2020 5:02 PM
> To: dev@dpdk.org; i.dyukov@samsung.com; v.kuramshin@samsung.com;
> thomas@monjalon.net; david.marchand@redhat.com; Yigit, Ferruh
> <ferruh.yigit@intel.com>; arybchenko@solarflare.com; Zhao1, Wei
> <wei.zhao1@intel.com>; Guo, Jia <jia.guo@intel.com>; Xing, Beilei
> <beilei.xing@intel.com>; Yang, Qiming <qiming.yang@intel.com>; Lu,
> Wenzhuo <wenzhuo.lu@intel.com>
> Subject: [PATCH v3 5/7] net/ixgbe: return unknown speed in status
> 
> rte_ethdev has declared new NUM_UNKNOWN speed which could be used in
> case when no speed information is available
> 
> Signed-off-by: Ivan Dyukov <i.dyukov@samsung.com>
> ---
>  drivers/net/ixgbe/ixgbe_ethdev.c | 6 +-----
>  1 file changed, 1 insertion(+), 5 deletions(-)
> 
> diff --git a/drivers/net/ixgbe/ixgbe_ethdev.c
> b/drivers/net/ixgbe/ixgbe_ethdev.c
> index a4e5c539d..5b9b13058 100644
> --- a/drivers/net/ixgbe/ixgbe_ethdev.c
> +++ b/drivers/net/ixgbe/ixgbe_ethdev.c
> @@ -4311,11 +4311,7 @@ ixgbe_dev_link_update_share(struct rte_eth_dev
> *dev,
>  	switch (link_speed) {
>  	default:
>  	case IXGBE_LINK_SPEED_UNKNOWN:
> -		if (hw->device_id == IXGBE_DEV_ID_X550EM_A_1G_T ||
> -			hw->device_id == IXGBE_DEV_ID_X550EM_A_1G_T_L)
> -			link.link_speed = ETH_SPEED_NUM_10M;
> -		else
> -			link.link_speed = ETH_SPEED_NUM_100M;
> +		link.link_speed = ETH_SPEED_NUM_UNKNOWN;
>  		break;
> 
>  	case IXGBE_LINK_SPEED_100_FULL:
> --
> 2.17.1


^ permalink raw reply	[flat|nested] 359+ messages in thread

* Re: [dpdk-dev] [PATCH v3 2/7] ethdev: add a link status textrepresentation
  2020-06-18 12:32                                       ` [dpdk-dev] [PATCH v3 2/7] ethdev: add a link status textrepresentation Morten Brørup
@ 2020-06-22  7:05                                         ` Ferruh Yigit
  2020-06-22  7:43                                           ` Morten Brørup
  0 siblings, 1 reply; 359+ messages in thread
From: Ferruh Yigit @ 2020-06-22  7:05 UTC (permalink / raw)
  To: Morten Brørup, Ivan Dyukov, dev, v.kuramshin, thomas,
	david.marchand, arybchenko, wei.zhao1, jia.guo, beilei.xing,
	qiming.yang, wenzhuo.lu, Stephen Hemminger

On 6/18/2020 1:32 PM, Morten Brørup wrote:
>> From: dev [mailto:dev-bounces@dpdk.org] On Behalf Of Ferruh Yigit
>> Sent: Thursday, June 18, 2020 2:03 PM
>>
>> On 6/18/2020 11:08 AM, Ivan Dyukov wrote:
>>> Hi Ferruh,
>>>
>>> Thank you for the comments.
>>>
>>> My answers are inlined.
>>>
>>> Best regards,
>>> Ivan
>>> 17.06.2020 19:45, Ferruh Yigit пишет:
>>>> On 6/15/2020 10:01 AM, Ivan Dyukov wrote:
>>>>> This commit add function which treat link status structure
>>>>> and format it to text representation.
>>>> If I am following correctly, the initial need was to escape from
>> speed checks
>>>> everytime loging link information caused by this new 'unknown'
>> speed.
>>>>
>>>> And later suggestion was to have a pre-formatted text for link
>> logging.
>>> Correct.
>>>>
>>>> This patch brings additional link status printing/formatting
>> capability with
>>>> custom format string support and with new format specifiers for link
>> (like, '%D'
>>>> link duplex state),
>>>> although this is nice work and thanks for it, I am not sure this
>> complexity and
>>>> two new APIs are really needed.
>>> Yep.
>>>> For me only 'rte_eth_link_format()' without custom format support
>> looks good
>>>> enough but I won't object if the concensus is to have them.
>>>> I am aware there are multiple applications you are updating logging
>> slightly
>>>> different which requires this flexibility but what happens if they
>> use same
>>>> pre-formatted text, is that difference really required or happened
>> by time based
>>>> on developers taste?
>>> I have changed only few applications but I have plan to change all
>> dpdk
>>> examples. Even in those few apps, we have various link status logging
>>> text. e.g  app/test-pmd/config.c
>>> @@ -600,10 +600,9 @@ port_infos_display(portid_t port_id)
>>>          } else
>>>                  printf("\nmemory allocation on the socket:
>>> %u",port->socket_id);
>>>
>>> -       printf("\nLink status: %s\n", (link.link_status) ? ("up") :
>>> ("down"));
>>> -       printf("Link speed: %u Mbps\n", (unsigned) link.link_speed);
>>> -       printf("Link duplex: %s\n", (link.link_duplex ==
>>> ETH_LINK_FULL_DUPLEX) ?
>>> -              ("full-duplex") : ("half-duplex"));
>>> +       rte_eth_link_printf("\nLink status: %S\n"
>>> +                           "Link speed: %M Mbps\n"
>>> +                           "Link duplex: %D\n", &link);
>>> the status is logged in 3 lines. this is special text layoting and I
>>> don't know how it will look in one line. Myabe it will require
>> reformat
>>> all screen. I don't want to change screen layoting in this patchset.
>>
>> cc'ed Morten & Stephen.
>>
>> To keep existing layout in the applications yes you need more
>> flexibility, a
>> pre-formatted text won't cut it, but I guess I prefer your approach in
>> v2 for
>> simplicity.
>>
>> And I would prefer extending the one in v2 with a larger string for the
>> pre-formatted text, so both flexibility and the standard output can be
>> provided,
>> Morten didn't like it but if I understand correctly his comment was to
>> keep more
>> simple solution in ethdev and applications can do it themselves if they
>> want
>> more custom log formatting, but this patch adds more complex and
>> flexible
>> logging support to the ethdev.
>>
> 
> If you are going to add a flexible link status formatting function, like strftime(), it should not print to stdout, but to a string buffer, like strftime(). It will also allow for new format specifiers in the future, e.g. %1D for "FDX"/"HDX", %2D for "Full"/"Half" or %3D for "full-duplex"/"half-duplex". This would provide more flexible support for a larger number of application specific formats.

These will make it even more complex, do we really need this?

> 
> Then the function for printing to stdout in a DPDK preferred format (if you add such a function to the library) can use the above eth_link_strf() function.
> 
> 


^ permalink raw reply	[flat|nested] 359+ messages in thread

* Re: [dpdk-dev] [PATCH v3 2/7] ethdev: add a link status textrepresentation
  2020-06-22  7:05                                         ` Ferruh Yigit
@ 2020-06-22  7:43                                           ` Morten Brørup
  0 siblings, 0 replies; 359+ messages in thread
From: Morten Brørup @ 2020-06-22  7:43 UTC (permalink / raw)
  To: Ferruh Yigit, Ivan Dyukov, dev, v.kuramshin, thomas,
	david.marchand, arybchenko, wei.zhao1, jia.guo, beilei.xing,
	qiming.yang, wenzhuo.lu, Stephen Hemminger

> From: Ferruh Yigit [mailto:ferruh.yigit@intel.com]
> Sent: Monday, June 22, 2020 9:05 AM
> 
> On 6/18/2020 1:32 PM, Morten Brørup wrote:
> >> From: dev [mailto:dev-bounces@dpdk.org] On Behalf Of Ferruh Yigit
> >> Sent: Thursday, June 18, 2020 2:03 PM
> >>
> >> On 6/18/2020 11:08 AM, Ivan Dyukov wrote:
> >>> Hi Ferruh,
> >>>
> >>> Thank you for the comments.
> >>>
> >>> My answers are inlined.
> >>>
> >>> Best regards,
> >>> Ivan
> >>> 17.06.2020 19:45, Ferruh Yigit пишет:
> >>>> On 6/15/2020 10:01 AM, Ivan Dyukov wrote:
> >>>>> This commit add function which treat link status structure
> >>>>> and format it to text representation.
> >>>> If I am following correctly, the initial need was to escape from
> >> speed checks
> >>>> everytime loging link information caused by this new 'unknown'
> >> speed.
> >>>>
> >>>> And later suggestion was to have a pre-formatted text for link
> >> logging.
> >>> Correct.
> >>>>
> >>>> This patch brings additional link status printing/formatting
> >> capability with
> >>>> custom format string support and with new format specifiers for
> link
> >> (like, '%D'
> >>>> link duplex state),
> >>>> although this is nice work and thanks for it, I am not sure this
> >> complexity and
> >>>> two new APIs are really needed.
> >>> Yep.
> >>>> For me only 'rte_eth_link_format()' without custom format support
> >> looks good
> >>>> enough but I won't object if the concensus is to have them.
> >>>> I am aware there are multiple applications you are updating
> logging
> >> slightly
> >>>> different which requires this flexibility but what happens if they
> >> use same
> >>>> pre-formatted text, is that difference really required or happened
> >> by time based
> >>>> on developers taste?
> >>> I have changed only few applications but I have plan to change all
> >> dpdk
> >>> examples. Even in those few apps, we have various link status
> logging
> >>> text. e.g  app/test-pmd/config.c
> >>> @@ -600,10 +600,9 @@ port_infos_display(portid_t port_id)
> >>>          } else
> >>>                  printf("\nmemory allocation on the socket:
> >>> %u",port->socket_id);
> >>>
> >>> -       printf("\nLink status: %s\n", (link.link_status) ? ("up") :
> >>> ("down"));
> >>> -       printf("Link speed: %u Mbps\n", (unsigned)
> link.link_speed);
> >>> -       printf("Link duplex: %s\n", (link.link_duplex ==
> >>> ETH_LINK_FULL_DUPLEX) ?
> >>> -              ("full-duplex") : ("half-duplex"));
> >>> +       rte_eth_link_printf("\nLink status: %S\n"
> >>> +                           "Link speed: %M Mbps\n"
> >>> +                           "Link duplex: %D\n", &link);
> >>> the status is logged in 3 lines. this is special text layoting and
> I
> >>> don't know how it will look in one line. Myabe it will require
> >> reformat
> >>> all screen. I don't want to change screen layoting in this
> patchset.
> >>
> >> cc'ed Morten & Stephen.
> >>
> >> To keep existing layout in the applications yes you need more
> >> flexibility, a
> >> pre-formatted text won't cut it, but I guess I prefer your approach
> in
> >> v2 for
> >> simplicity.
> >>
> >> And I would prefer extending the one in v2 with a larger string for
> the
> >> pre-formatted text, so both flexibility and the standard output can
> be
> >> provided,
> >> Morten didn't like it but if I understand correctly his comment was
> to
> >> keep more
> >> simple solution in ethdev and applications can do it themselves if
> they
> >> want
> >> more custom log formatting, but this patch adds more complex and
> >> flexible
> >> logging support to the ethdev.
> >>
> >
> > If you are going to add a flexible link status formatting function,
> like strftime(), it should not print to stdout, but to a string buffer,
> like strftime(). It will also allow for new format specifiers in the
> future, e.g. %1D for "FDX"/"HDX", %2D for "Full"/"Half" or %3D for
> "full-duplex"/"half-duplex". This would provide more flexible support
> for a larger number of application specific formats.
> 
> These will make it even more complex, do we really need this?

It only needs to support the format specifiers required for the preferred DPDK text format, initially. It can be extended at a later time with more format specifiers.

And the implementation could be somewhat simplified by specifying that the length of the provided string buffer should be large enough to hold the result, or only a partial (or possibly empty) string will be returned.

I prefer a flexible formatting function over the initially suggested function that takes a struct of string buffers with only one way of formatting the strings. Or, we can leave it up to the application to do the text formatting.

> 
> >
> > Then the function for printing to stdout in a DPDK preferred format
> (if you add such a function to the library) can use the above
> eth_link_strf() function.

^ permalink raw reply	[flat|nested] 359+ messages in thread

* [dpdk-dev] [PATCH v4 0/7] ethdev: allow unknown link speed
       [not found]                         ` <CGME20200702132203eucas1p2cf39d174c43185b6b825e5238f98acda@eucas1p2.samsung.com>
@ 2020-07-02 13:21                           ` Ivan Dyukov
       [not found]                             ` <CGME20200702132206eucas1p1d13fc23fe4d48b18435f79aa94efbc10@eucas1p1.samsung.com>
                                               ` (6 more replies)
  0 siblings, 7 replies; 359+ messages in thread
From: Ivan Dyukov @ 2020-07-02 13:21 UTC (permalink / raw)
  To: dev, i.dyukov, v.kuramshin, thomas, david.marchand, ferruh.yigit,
	arybchenko, wei.zhao1, jia.guo, beilei.xing, qiming.yang,
	wenzhuo.lu, mb, stephen

 MAINTAINERS                                   |   1 +
 app/proc-info/main.c                          |   9 +-
 app/test-pipeline/init.c                      |  11 +-
 app/test-pmd/config.c                         |  19 ++-
 app/test-pmd/testpmd.c                        |   9 +-
 app/test/Makefile                             |   3 +
 app/test/meson.build                          |   2 +
 app/test/test_ethdev_link.c                   | 278 ++++++++++++++++++++++++++++++++++
 app/test/test_pmd_perf.c                      |  17 +--
 doc/guides/sample_app_ug/link_status_intr.rst |  10 +-
 drivers/net/i40e/i40e_ethdev.c                |   5 +-
 drivers/net/i40e/i40e_ethdev_vf.c             |  10 +-
 drivers/net/ice/ice_ethdev.c                  |   5 +-
 drivers/net/ixgbe/ixgbe_ethdev.c              |   6 +-
 lib/librte_ethdev/rte_ethdev.c                | 168 ++++++++++++++++++++
 lib/librte_ethdev/rte_ethdev.h                |  74 +++++++--
 lib/librte_ethdev/rte_ethdev_version.map      |   4 +
 17 files changed, 566 insertions(+), 65 deletions(-)

v4 changes:
* refactor rte_eth_link_format using strlcat func instead of snprintf
* added new checks to unit tests
* few minor fixes according review comments
TBD:
update examples in 'example' folder with new status printing mechanism
update remaining nic drivers with 'unknown' speed

v3 changes:
* remove rte_eth_link_prepare_text function
* add rte_eth_link_format and rte_eth_link_printf functions
* added unit tests for rte_eth_link_format function
TBD:
update examples in 'example' folder with new status printing mechanism
update remaining nic drivers with 'unknown' speed

v2 changes:
* add function which format link status to textual representation
* update drivers for Intel nics with 'unknown' speed
TBD:
update examples in 'example' folder with new status printing mechanism
update remaining nic drivers with 'unknown' speed

v1 changes:
This is initial patchset which introduces UNKNOWN speed to dpdk
applications. Also it contains changes related to printf formating.
Patchset contains changes for app/ and doc/ folders.
examples/ folder will be provided later.



^ permalink raw reply	[flat|nested] 359+ messages in thread

* [dpdk-dev] [PATCH v4 1/7] ethdev: allow unknown link speed
       [not found]                             ` <CGME20200702132206eucas1p1d13fc23fe4d48b18435f79aa94efbc10@eucas1p1.samsung.com>
@ 2020-07-02 13:21                               ` " Ivan Dyukov
  0 siblings, 0 replies; 359+ messages in thread
From: Ivan Dyukov @ 2020-07-02 13:21 UTC (permalink / raw)
  To: dev, i.dyukov, v.kuramshin, thomas, david.marchand, ferruh.yigit,
	arybchenko, wei.zhao1, jia.guo, beilei.xing, qiming.yang,
	wenzhuo.lu, mb, stephen

From: Thomas Monjalon <thomas@monjalon.net>

When querying the link information, the link status is
a mandatory major information.
Other boolean values are supposed to be accurate:
	- duplex mode (half/full)
	- negotiation (auto/fixed)

This API update is making explicit that the link speed information
is optional.
The value ETH_SPEED_NUM_NONE (0) was already part of the API.
The value ETH_SPEED_NUM_UNKNOWN (infinite) is added to cover
two different cases:
	- speed is not known by the driver
	- device is virtual

Suggested-by: Morten Brørup <mb@smartsharesystems.com>
Suggested-by: Benoit Ganne <bganne@cisco.com>
Signed-off-by: Thomas Monjalon <thomas@monjalon.net>
Reviewed-by: Ferruh Yigit <ferruh.yigit@intel.com>
---
 lib/librte_ethdev/rte_ethdev.h | 20 ++++++++++----------
 1 file changed, 10 insertions(+), 10 deletions(-)

diff --git a/lib/librte_ethdev/rte_ethdev.h b/lib/librte_ethdev/rte_ethdev.h
index a49242bcd..2090af501 100644
--- a/lib/librte_ethdev/rte_ethdev.h
+++ b/lib/librte_ethdev/rte_ethdev.h
@@ -303,6 +303,7 @@ struct rte_eth_stats {
 #define ETH_SPEED_NUM_56G      56000 /**<  56 Gbps */
 #define ETH_SPEED_NUM_100G    100000 /**< 100 Gbps */
 #define ETH_SPEED_NUM_200G    200000 /**< 200 Gbps */
+#define ETH_SPEED_NUM_UNKNOWN UINT32_MAX /**< Unknown */
 
 /**
  * A structure used to retrieve link-level information of an Ethernet port.
@@ -2262,15 +2263,16 @@ int rte_eth_allmulticast_disable(uint16_t port_id);
 int rte_eth_allmulticast_get(uint16_t port_id);
 
 /**
- * Retrieve the status (ON/OFF), the speed (in Mbps) and the mode (HALF-DUPLEX
- * or FULL-DUPLEX) of the physical link of an Ethernet device. It might need
- * to wait up to 9 seconds in it.
+ * Retrieve the link status (up/down), the duplex mode (half/full),
+ * the negotiation (auto/fixed), and if available, the speed (Mbps).
+ *
+ * It might need to wait up to 9 seconds.
+ * @see rte_eth_link_get_nowait.
  *
  * @param port_id
  *   The port identifier of the Ethernet device.
  * @param link
- *   A pointer to an *rte_eth_link* structure to be filled with
- *   the status, the speed and the mode of the Ethernet device link.
+ *   Link information written back.
  * @return
  *   - (0) if successful.
  *   - (-ENOTSUP) if the function is not supported in PMD driver.
@@ -2279,15 +2281,13 @@ int rte_eth_allmulticast_get(uint16_t port_id);
 int rte_eth_link_get(uint16_t port_id, struct rte_eth_link *link);
 
 /**
- * Retrieve the status (ON/OFF), the speed (in Mbps) and the mode (HALF-DUPLEX
- * or FULL-DUPLEX) of the physical link of an Ethernet device. It is a no-wait
- * version of rte_eth_link_get().
+ * Retrieve the link status (up/down), the duplex mode (half/full),
+ * the negotiation (auto/fixed), and if available, the speed (Mbps).
  *
  * @param port_id
  *   The port identifier of the Ethernet device.
  * @param link
- *   A pointer to an *rte_eth_link* structure to be filled with
- *   the status, the speed and the mode of the Ethernet device link.
+ *   Link information written back.
  * @return
  *   - (0) if successful.
  *   - (-ENOTSUP) if the function is not supported in PMD driver.
-- 
2.17.1


^ permalink raw reply	[flat|nested] 359+ messages in thread

* [dpdk-dev] [PATCH v4 2/7] ethdev: add a link status text representation
       [not found]                             ` <CGME20200702132209eucas1p2d55db5b7637dadea4ccce549fd979377@eucas1p2.samsung.com>
@ 2020-07-02 13:21                               ` Ivan Dyukov
  0 siblings, 0 replies; 359+ messages in thread
From: Ivan Dyukov @ 2020-07-02 13:21 UTC (permalink / raw)
  To: dev, i.dyukov, v.kuramshin, thomas, david.marchand, ferruh.yigit,
	arybchenko, wei.zhao1, jia.guo, beilei.xing, qiming.yang,
	wenzhuo.lu, mb, stephen

This commit add function which treat link status structure
and format it to text representation.

Signed-off-by: Ivan Dyukov <i.dyukov@samsung.com>
---
 MAINTAINERS                              |   1 +
 app/test/Makefile                        |   3 +
 app/test/meson.build                     |   2 +
 app/test/test_ethdev_link.c              | 278 +++++++++++++++++++++++
 lib/librte_ethdev/rte_ethdev.c           | 168 ++++++++++++++
 lib/librte_ethdev/rte_ethdev.h           |  54 +++++
 lib/librte_ethdev/rte_ethdev_version.map |   4 +
 7 files changed, 510 insertions(+)
 create mode 100644 app/test/test_ethdev_link.c

diff --git a/MAINTAINERS b/MAINTAINERS
index 6a14622a0..94c5cd58e 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -378,6 +378,7 @@ T: git://dpdk.org/next/dpdk-next-net
 F: lib/librte_ethdev/
 F: devtools/test-null.sh
 F: doc/guides/prog_guide/switch_representation.rst
+F: app/test/test_ethdev*
 
 Flow API
 M: Ori Kam <orika@mellanox.com>
diff --git a/app/test/Makefile b/app/test/Makefile
index 5b119aa61..14552073d 100644
--- a/app/test/Makefile
+++ b/app/test/Makefile
@@ -249,6 +249,9 @@ SRCS-$(CONFIG_RTE_LIBRTE_SECURITY) += test_security.c
 
 SRCS-$(CONFIG_RTE_LIBRTE_IPSEC) += test_ipsec.c test_ipsec_perf.c
 SRCS-$(CONFIG_RTE_LIBRTE_IPSEC) += test_ipsec_sad.c
+
+SRCS-$(CONFIG_RTE_LIBRTE_ETHER) += test_ethdev_link.c
+
 ifeq ($(CONFIG_RTE_LIBRTE_IPSEC),y)
 LDLIBS += -lrte_ipsec
 endif
diff --git a/app/test/meson.build b/app/test/meson.build
index 1715ddbcb..c5b742c15 100644
--- a/app/test/meson.build
+++ b/app/test/meson.build
@@ -38,6 +38,7 @@ test_sources = files('commands.c',
 	'test_efd.c',
 	'test_efd_perf.c',
 	'test_errno.c',
+	'test_ethdev_link.c',
 	'test_event_crypto_adapter.c',
 	'test_event_eth_rx_adapter.c',
 	'test_event_ring.c',
@@ -196,6 +197,7 @@ fast_tests = [
         ['eal_flags_misc_autotest', false],
         ['eal_fs_autotest', true],
         ['errno_autotest', true],
+        ['ethdev_link_status' true],
         ['event_ring_autotest', true],
         ['fib_autotest', true],
         ['fib6_autotest', true],
diff --git a/app/test/test_ethdev_link.c b/app/test/test_ethdev_link.c
new file mode 100644
index 000000000..b019a61f8
--- /dev/null
+++ b/app/test/test_ethdev_link.c
@@ -0,0 +1,278 @@
+/* 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[128];
+	ret = rte_eth_link_format(text, 128, NULL, &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 Gbit/s 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_format(text, 128, NULL, &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 Mbit/s HDX Fixed",
+		text, strlen(text), "Invalid default link status "
+		"string with HDX");
+
+	link_status.link_speed = ETH_SPEED_NUM_UNKNOWN,
+	ret = rte_eth_link_format(text, 128, NULL, &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 speed HDX Fixed",
+		text, strlen(text), "Invalid default link status "
+		"string with HDX");
+	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[128];
+	ret = rte_eth_link_format(text, 128, NULL, &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_string_overflow(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[128];
+	int i = 0;
+	for (i = 0; i < 128; i++)
+		text[i] = 'Y';
+	text[127] = '\0';
+
+	ret = rte_eth_link_format(NULL, 2, "status %S, %G Gbits/s",
+		&link_status);
+	RTE_TEST_ASSERT(ret < 0, "Format string should fail, but it's ok\n");
+
+	ret = rte_eth_link_format(text, 2, "status %S, %G Gbits/s",
+		&link_status);
+	RTE_TEST_ASSERT(ret < 0, "Format string should fail, but it's ok\n");
+	RTE_TEST_ASSERT(text[2] == 'Y', "String1 overflow\n");
+
+	ret = rte_eth_link_format(text, 8, NULL,
+		&link_status);
+	RTE_TEST_ASSERT(ret < 0, "Default format string should fail,"
+			" but it's ok\n");
+	RTE_TEST_ASSERT(text[8] == 'Y', "String1 overflow\n");
+
+	ret = rte_eth_link_format(text, 10, NULL,
+		&link_status);
+	RTE_TEST_ASSERT(ret < 0, "Default format string should fail,"
+			" but it's ok\n");
+	RTE_TEST_ASSERT(text[10] == 'Y', "String1 overflow\n");
+
+	text[1] = 'Y';
+	ret = rte_eth_link_format(text, 1, "%S",
+		&link_status);
+	RTE_TEST_ASSERT(ret < 0, "Status string should fail, but it's ok\n");
+	RTE_TEST_ASSERT(text[1] == 'Y', "String1 overflow\n");
+
+	return TEST_SUCCESS;
+}
+
+static int32_t
+test_link_status_format(void)
+{
+	int ret = 0;
+	struct rte_eth_link link_status = {
+		.link_speed = ETH_SPEED_NUM_40G,
+		.link_status = ETH_LINK_UP,
+		.link_autoneg = ETH_LINK_AUTONEG,
+		.link_duplex = ETH_LINK_FULL_DUPLEX
+	};
+	char text[128];
+	int i = 0;
+	for (i = 0; i < 128; i++)
+		text[i] = 'Y';
+	text[127] = '\0';
+	printf("status format #1: %s\n", text);
+	ret = rte_eth_link_format(text, 128, "status = %S, duplex = %D\n",
+		&link_status);
+	printf("status format #2: %s\n", text);
+	RTE_TEST_ASSERT(ret > 0, "Failed to format string\n");
+	TEST_ASSERT_BUFFERS_ARE_EQUAL("status = Up, duplex = FDX\n",
+		text, strlen(text), "Invalid status string1.");
+
+	ret = rte_eth_link_format(text, 128, "%A", &link_status);
+	printf("status format #3: %s\n", text);
+	RTE_TEST_ASSERT(ret > 0, "Failed to format string\n");
+	TEST_ASSERT_BUFFERS_ARE_EQUAL("Autoneg",
+		text, strlen(text), "Invalid status string2.");
+
+	ret = rte_eth_link_format(text, 128,
+		"%G",
+		&link_status);
+	printf("status format #4: %s\n", text);
+	RTE_TEST_ASSERT(ret > 0, "Failed to format string\n");
+	TEST_ASSERT_BUFFERS_ARE_EQUAL("40.0",
+		text, strlen(text), "Invalid status string3.");
+
+	ret = rte_eth_link_format(text, 128,
+		"%M",
+		&link_status);
+	printf("status format #5: %s\n", text);
+	RTE_TEST_ASSERT(ret > 0, "Failed to format string\n");
+	TEST_ASSERT_BUFFERS_ARE_EQUAL("40000",
+		text, strlen(text), "Invalid status string4.");
+	return TEST_SUCCESS;
+}
+
+static int32_t
+test_link_status_return_value(void)
+{
+	int ret = 0;
+	struct rte_eth_link link_status = {
+		.link_speed = ETH_SPEED_NUM_40G,
+		.link_status = ETH_LINK_UP,
+		.link_autoneg = ETH_LINK_AUTONEG,
+		.link_duplex = ETH_LINK_FULL_DUPLEX
+	};
+	char text[128];
+	int i = 0;
+	for (i = 0; i < 128; i++)
+		text[i] = 'Y';
+	text[127] = '\0';
+	ret = rte_eth_link_format(text, 128, "status = %S, ",
+		&link_status);
+	printf("return value #1:ret=%u, text=%s\n", ret, text);
+	ret += rte_eth_link_format(text + ret, 128 - ret,
+		"%A",
+		&link_status);
+	printf("return value #2:ret=%u, text=%s\n", ret, text);
+	ret += rte_eth_link_format(text + ret, 128 - ret,
+		", duplex = %D\n",
+		&link_status);
+	printf("return value #3:ret=%u, text=%s\n", ret, text);
+	ret += rte_eth_link_format(text + ret, 128 - ret,
+		"%M Mbits/s\n",
+		&link_status);
+	printf("return value #4:ret=%u, text=%s\n", ret, text);
+	RTE_TEST_ASSERT(ret > 0, "Failed to format string\n");
+	TEST_ASSERT_BUFFERS_ARE_EQUAL("status = Up, Autoneg, duplex = FDX\n"
+		"40000 Mbits/s\n",
+		text, strlen(text), "Invalid status string");
+
+	return TEST_SUCCESS;
+}
+
+static int32_t
+test_link_status_invalid_fmt(void)
+{
+	int ret = 0;
+	struct rte_eth_link link_status = {
+		.link_speed = ETH_SPEED_NUM_40G,
+		.link_status = ETH_LINK_UP,
+		.link_autoneg = ETH_LINK_AUTONEG,
+		.link_duplex = ETH_LINK_FULL_DUPLEX
+	};
+	char text[128];
+	ret = rte_eth_link_format(text, 128, "status = %",
+		&link_status);
+	RTE_TEST_ASSERT(ret < 0, "Status string1 should fail, but it's ok\n");
+	ret = rte_eth_link_format(text, 128,
+		", duplex = %d\n",
+		&link_status);
+	RTE_TEST_ASSERT(ret < 0, "Status string2 should fail, but it's ok\n");
+	ret = rte_eth_link_format(text, 128,
+		"% Mbits/s\n",
+		&link_status);
+	RTE_TEST_ASSERT(ret < 0, "Status string3 should fail, but it's ok\n");
+
+	return TEST_SUCCESS;
+}
+
+static int32_t
+test_link_status_format_edges(void)
+{
+	int ret = 0;
+	struct rte_eth_link link_status = {
+		.link_speed = ETH_SPEED_NUM_UNKNOWN,
+		.link_status = ETH_LINK_DOWN,
+		.link_autoneg = ETH_LINK_AUTONEG,
+		.link_duplex = ETH_LINK_HALF_DUPLEX
+	};
+	char text[128];
+	ret = rte_eth_link_format(text, 4, "%S", &link_status);
+	printf("format edges #1: %s\n", text);
+	RTE_TEST_ASSERT(ret < 0, "It should fail. No space for "
+				 "zero terminator\n");
+	ret = rte_eth_link_format(text, 6, "123%D", &link_status);
+	printf("format edges #2: %s\n", text);
+	RTE_TEST_ASSERT(ret < 0, "It should fail. No space for "
+				 "zero terminator\n");
+	ret = rte_eth_link_format(text, 7, "%A", &link_status);
+	printf("format edges #3: %s\n", text);
+	RTE_TEST_ASSERT(ret < 0, "It should fail. No space for "
+				 "zero terminator\n");
+	ret = rte_eth_link_format(text, 8, "%A", &link_status);
+	printf("format edges #4: %s\n", text);
+	RTE_TEST_ASSERT(ret > 0, "It should ok, but it fails\n");
+	return TEST_SUCCESS;
+}
+static struct unit_test_suite link_status_testsuite = {
+	.suite_name = "link status formating",
+	.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_status_string_overflow),
+		TEST_CASE(test_link_status_format),
+		TEST_CASE(test_link_status_format_edges),
+		TEST_CASE(test_link_status_invalid_fmt),
+		TEST_CASE(test_link_status_return_value),
+		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);
diff --git a/lib/librte_ethdev/rte_ethdev.c b/lib/librte_ethdev/rte_ethdev.c
index 8e10a6fc3..79158f119 100644
--- a/lib/librte_ethdev/rte_ethdev.c
+++ b/lib/librte_ethdev/rte_ethdev.c
@@ -2385,6 +2385,174 @@ rte_eth_link_get_nowait(uint16_t port_id, struct rte_eth_link *eth_link)
 	return 0;
 }
 
+static int
+rte_eth_link_format_parser(char *str, size_t len, const char *const fmt,
+			   struct rte_eth_link *link)
+{
+	size_t offset = 0;
+	const char *fmt_cur = fmt;
+	char *str_cur = str;
+	double gbits = (double)link->link_speed / 1000.;
+	static const char AUTONEG_STR[]       = "Autoneg";
+	static const char FIXED_STR[]         = "Fixed";
+	static const char FDX_STR[]           = "FDX";
+	static const char HDX_STR[]           = "HDX";
+	static const char UNKNOWN_STR[]       = "Unknown";
+	static const char UP_STR[]            = "Up";
+	static const char DOWN_STR[]          = "Down";
+
+	char gbits_str[20];
+	char mbits_str[20];
+	/* preformat complex formating to easily concatinate it further */
+	snprintf(mbits_str, 20, "%u", link->link_speed);
+	snprintf(gbits_str, 20, "%.1f", gbits);
+	/* init str before formating */
+	str[0] = 0;
+	while (*fmt_cur) {
+		/* check str bounds */
+		if (offset > (len - 1)) {
+			str[len - 1] = '\0';
+			return -1;
+		}
+		if (*fmt_cur == '%') {
+			/* set null terminator to current position,
+			 * it's required for strlcat
+			 */
+			*str_cur = '\0';
+			switch (*++fmt_cur) {
+			/* Speed in Mbits/s */
+			case 'M':
+				if (link->link_speed ==
+				    ETH_SPEED_NUM_UNKNOWN)
+					offset = strlcat(str, UNKNOWN_STR,
+							 len);
+				else
+					offset = strlcat(str, mbits_str, len);
+				break;
+			/* Speed in Gbits/s */
+			case 'G':
+				if (link->link_speed ==
+				    ETH_SPEED_NUM_UNKNOWN)
+					offset = strlcat(str, UNKNOWN_STR,
+							 len);
+				else
+					offset = strlcat(str, gbits_str, len);
+				break;
+			/* Link status */
+			case 'S':
+				offset = strlcat(str, link->link_status ?
+					UP_STR : DOWN_STR, len);
+				break;
+			/* Link autoneg */
+			case 'A':
+				offset = strlcat(str, link->link_autoneg ?
+					AUTONEG_STR : FIXED_STR, len);
+				break;
+			/* Link duplex */
+			case 'D':
+				offset = strlcat(str, link->link_duplex ?
+					FDX_STR : HDX_STR, len);
+				break;
+			/* Error cases */
+			default:
+				return -1;
+
+			}
+			if (offset > (len - 1))
+				return -1;
+
+			str_cur = str + offset;
+		} else {
+			*str_cur++ = *fmt_cur;
+			offset++;
+		}
+		fmt_cur++;
+	}
+	*str_cur = '\0';
+	return offset;
+}
+
+int
+rte_eth_link_printf(const char *const fmt,
+		    struct rte_eth_link *link)
+{
+	char text[200];
+	int ret;
+	ret = rte_eth_link_format(text, 200, fmt, link);
+	if (ret > 0)
+		printf("%s", text);
+	return ret;
+}
+
+int
+rte_eth_link_format(char *str, size_t len, const char *const fmt,
+		    struct rte_eth_link *link)
+{
+	size_t offset = 0;
+	double gbits = (double)link->link_speed / 1000.;
+	char gbits_str[20];
+	char mbits_str[20];
+	/* TBD: make it international? */
+	static const char LINK_DOWN_STR[]     = "Link down";
+	static const char LINK_UP_STR[]       = "Link up at ";
+	static const char UNKNOWN_SPEED_STR[] = "Unknown speed ";
+	static const char MBITS_STR[]	      = "Mbit/s";
+	static const char GBITS_STR[]	      = "Gbit/s";
+	static const char AUTONEG_STR[]       = "Autoneg";
+	static const char FIXED_STR[]         = "Fixed";
+	static const char FDX_STR[]           = "FDX ";
+	static const char HDX_STR[]           = "HDX ";
+	if (str == NULL || len == 0)
+		return -1;
+	/* default format string, if no fmt is specified */
+	if (fmt == NULL) {
+		if (link->link_status == ETH_LINK_DOWN) {
+			if (sizeof(LINK_DOWN_STR) > len)
+				return -1;
+			return strlcpy(str, LINK_DOWN_STR, len);
+		}
+
+		/* preformat complex strings to easily concatinate it further */
+		snprintf(mbits_str, 20, "%u %s ", link->link_speed, MBITS_STR);
+		snprintf(gbits_str, 20, "%.1f %s ", gbits, GBITS_STR);
+
+		offset = strlcpy(str, LINK_UP_STR, len);
+		/* reserve one byte to null terminator */
+		if (offset > (len - 1))
+			return -1;
+		/* link speed */
+		if (link->link_speed == ETH_SPEED_NUM_UNKNOWN) {
+			offset = strlcat(str, UNKNOWN_SPEED_STR, len);
+			if (offset > (len - 1))
+				return -1;
+		} else {
+			if (link->link_speed < ETH_SPEED_NUM_1G) {
+				offset = strlcat(str, mbits_str, len);
+				if (offset > (len - 1))
+					return -1;
+			} else {
+				offset = strlcat(str, gbits_str, len);
+				if (offset > (len - 1))
+					return -1;
+			}
+		}
+		/* link duplex */
+		offset = strlcat(str, link->link_duplex ?
+			       FDX_STR : HDX_STR, len);
+		if (offset > (len - 1))
+			return -1;
+		/* link autonegotiation */
+		offset = strlcat(str, link->link_autoneg ?
+			       AUTONEG_STR : FIXED_STR, len);
+		if (offset > (len - 1))
+			return -1;
+	/* Formated status */
+	} else
+		offset = rte_eth_link_format_parser(str, len, fmt, link);
+
+	return offset;
+}
+
 int
 rte_eth_stats_get(uint16_t port_id, struct rte_eth_stats *stats)
 {
diff --git a/lib/librte_ethdev/rte_ethdev.h b/lib/librte_ethdev/rte_ethdev.h
index 2090af501..f444101a6 100644
--- a/lib/librte_ethdev/rte_ethdev.h
+++ b/lib/librte_ethdev/rte_ethdev.h
@@ -2295,6 +2295,60 @@ int rte_eth_link_get(uint16_t port_id, struct rte_eth_link *link);
  */
 int rte_eth_link_get_nowait(uint16_t port_id, struct rte_eth_link *link);
 
+
+/**
+ * print formated link status to stdout. This function threats all
+ * special values like ETH_SPEED_NUM_UNKNOWN, ETH_LINK_DOWN etc. and convert
+ * them to textual representation.
+ *
+ * @param fmt
+ *   Format string which allow to format link status. If NULL is provided
+ *   , default formating will be applied.
+ *   Following specifiers are available:
+ *    - '%M' link speed in Mbits/s
+ *    - '%G' link speed in Gbits/s
+ *    - '%S' link status. e.g. Up or Down
+ *    - '%A' link autonegotiation state
+ *    - '%D' link duplex state
+ * @param link
+ *   Link status provided by rte_eth_link_get function
+ * @return
+ *   - Number of bytes written to stdout. In case of error, -1 is returned.
+ *
+ */
+__rte_experimental
+int rte_eth_link_printf(const char *const fmt,
+			struct rte_eth_link *link);
+
+/**
+ * Format link status to textual representation. This function threats all
+ * special values like ETH_SPEED_NUM_UNKNOWN, ETH_LINK_DOWN etc. and convert
+ * them to textual representation.
+ *
+ * @param str
+ *   A pointer to a string to be filled with textual representation of
+ *   device status.
+ * @param len
+ *   Length of available memory at 'str' string.
+ * @param fmt
+ *   Format string which allow to format link status. If NULL is provided
+ *   , default formating will be applied.
+ *   Following specifiers are available:
+ *    - '%M' link speed in Mbits/s
+ *    - '%G' link speed in Gbits/s
+ *    - '%S' link status. e.g. Up or Down
+ *    - '%A' link autonegotiation state
+ *    - '%D' link duplex state
+ * @param link
+ *   Link status provided by rte_eth_link_get function
+ * @return
+ *   - Number of bytes written to str array. In case of error, -1 is returned.
+ *
+ */
+__rte_experimental
+int rte_eth_link_format(char *str, size_t len, const char *const fmt,
+			struct rte_eth_link *eth_link);
+
 /**
  * Retrieve the general I/O statistics of an Ethernet device.
  *
diff --git a/lib/librte_ethdev/rte_ethdev_version.map b/lib/librte_ethdev/rte_ethdev_version.map
index 715505604..a4c5e7653 100644
--- a/lib/librte_ethdev/rte_ethdev_version.map
+++ b/lib/librte_ethdev/rte_ethdev_version.map
@@ -241,4 +241,8 @@ EXPERIMENTAL {
 	__rte_ethdev_trace_rx_burst;
 	__rte_ethdev_trace_tx_burst;
 	rte_flow_get_aged_flows;
+
+	# added in 20.08
+	rte_eth_link_format;
+	rte_eth_link_printf;
 };
-- 
2.17.1


^ permalink raw reply	[flat|nested] 359+ messages in thread

* [dpdk-dev] [PATCH v4 3/7] app: UNKNOWN link speed print format
       [not found]                             ` <CGME20200702132211eucas1p1e49daea80551730a4fb4736691f3edac@eucas1p1.samsung.com>
@ 2020-07-02 13:21                               ` Ivan Dyukov
  0 siblings, 0 replies; 359+ messages in thread
From: Ivan Dyukov @ 2020-07-02 13:21 UTC (permalink / raw)
  To: dev, i.dyukov, v.kuramshin, thomas, david.marchand, ferruh.yigit,
	arybchenko, wei.zhao1, jia.guo, beilei.xing, qiming.yang,
	wenzhuo.lu, mb, stephen

Add usage of rte_eth_link_format function to example
applications

Signed-off-by: Ivan Dyukov <i.dyukov@samsung.com>
---
 app/proc-info/main.c     |  9 +++------
 app/test-pipeline/init.c | 11 +++++------
 app/test-pmd/config.c    | 19 +++++++++++--------
 app/test-pmd/testpmd.c   |  9 +--------
 app/test/test_pmd_perf.c | 17 +++++++----------
 5 files changed, 27 insertions(+), 38 deletions(-)

diff --git a/app/proc-info/main.c b/app/proc-info/main.c
index abeca4aab..4a4c572c3 100644
--- a/app/proc-info/main.c
+++ b/app/proc-info/main.c
@@ -685,12 +685,9 @@ show_port(void)
 			printf("Link get failed (port %u): %s\n",
 			       i, rte_strerror(-ret));
 		} else {
-			printf("\t  -- link speed %d duplex %d,"
-					" auto neg %d status %d\n",
-					link.link_speed,
-					link.link_duplex,
-					link.link_autoneg,
-					link.link_status);
+			rte_eth_link_printf("\t  -- link speed: %M, duplex: %D,"
+					" auto neg: %A, status: %S\n",
+					&link);
 		}
 		printf("\t  -- promiscuous (%d)\n",
 				rte_eth_promiscuous_get(i));
diff --git a/app/test-pipeline/init.c b/app/test-pipeline/init.c
index 67d54ae05..dfeeec943 100644
--- a/app/test-pipeline/init.c
+++ b/app/test-pipeline/init.c
@@ -155,7 +155,7 @@ static void
 app_ports_check_link(void)
 {
 	uint32_t all_ports_up, i;
-
+	char link_status_text[50];
 	all_ports_up = 1;
 
 	for (i = 0; i < app.n_ports; i++) {
@@ -173,12 +173,11 @@ app_ports_check_link(void)
 			all_ports_up = 0;
 			continue;
 		}
-
-		RTE_LOG(INFO, USER1, "Port %u (%u Gbps) %s\n",
+		rte_eth_link_format(link_status_text, 50, "(%G Gbps) %S",
+				    &link);
+		RTE_LOG(INFO, USER1, "Port %u %s\n",
 			port,
-			link.link_speed / 1000,
-			link.link_status ? "UP" : "DOWN");
-
+			link_status_text);
 		if (link.link_status == ETH_LINK_DOWN)
 			all_ports_up = 0;
 	}
diff --git a/app/test-pmd/config.c b/app/test-pmd/config.c
index 5381207cc..77fa9a0e9 100644
--- a/app/test-pmd/config.c
+++ b/app/test-pmd/config.c
@@ -600,10 +600,9 @@ port_infos_display(portid_t port_id)
 	} else
 		printf("\nmemory allocation on the socket: %u",port->socket_id);
 
-	printf("\nLink status: %s\n", (link.link_status) ? ("up") : ("down"));
-	printf("Link speed: %u Mbps\n", (unsigned) link.link_speed);
-	printf("Link duplex: %s\n", (link.link_duplex == ETH_LINK_FULL_DUPLEX) ?
-	       ("full-duplex") : ("half-duplex"));
+	rte_eth_link_printf("\nLink status: %S\n"
+			    "Link speed: %M Mbps\n"
+			    "Link duplex: %D\n", &link);
 
 	if (!rte_eth_dev_get_mtu(port_id, &mtu))
 		printf("MTU: %u\n", mtu);
@@ -726,6 +725,8 @@ port_summary_display(portid_t port_id)
 	struct rte_eth_link link;
 	struct rte_eth_dev_info dev_info;
 	char name[RTE_ETH_NAME_MAX_LEN];
+	char status_text[6];
+	char speed_text[12];
 	int ret;
 
 	if (port_id_is_invalid(port_id, ENABLED_WARN)) {
@@ -746,12 +747,14 @@ port_summary_display(portid_t port_id)
 	if (ret != 0)
 		return;
 
-	printf("%-4d %02X:%02X:%02X:%02X:%02X:%02X %-12s %-14s %-8s %uMbps\n",
+	rte_eth_link_format(status_text, 6, "%S", &link);
+	rte_eth_link_format(speed_text, 12, "%M", &link);
+	printf("%-4d %02X:%02X:%02X:%02X:%02X:%02X %-12s %-14s %-8s %sMbps\n",
 		port_id, mac_addr.addr_bytes[0], mac_addr.addr_bytes[1],
 		mac_addr.addr_bytes[2], mac_addr.addr_bytes[3],
 		mac_addr.addr_bytes[4], mac_addr.addr_bytes[5], name,
-		dev_info.driver_name, (link.link_status) ? ("up") : ("down"),
-		(unsigned int) link.link_speed);
+		dev_info.driver_name, status_text,
+		speed_text);
 }
 
 void
@@ -3897,7 +3900,7 @@ set_queue_rate_limit(portid_t port_id, uint16_t queue_idx, uint16_t rate)
 	ret = eth_link_get_nowait_print_err(port_id, &link);
 	if (ret < 0)
 		return 1;
-	if (rate > link.link_speed) {
+	if (link.link_speed != UINT32_MAX && rate > link.link_speed) {
 		printf("Invalid rate value:%u bigger than link speed: %u\n",
 			rate, link.link_speed);
 		return 1;
diff --git a/app/test-pmd/testpmd.c b/app/test-pmd/testpmd.c
index 9cbe6e9f6..621a1055c 100644
--- a/app/test-pmd/testpmd.c
+++ b/app/test-pmd/testpmd.c
@@ -3007,14 +3007,7 @@ check_all_ports_link_status(uint32_t port_mask)
 			}
 			/* print link status if flag set */
 			if (print_flag == 1) {
-				if (link.link_status)
-					printf(
-					"Port%d Link Up. speed %u Mbps- %s\n",
-					portid, link.link_speed,
-				(link.link_duplex == ETH_LINK_FULL_DUPLEX) ?
-					("full-duplex") : ("half-duplex"));
-				else
-					printf("Port %d Link Down\n", portid);
+				rte_eth_link_printf(NULL, &link);
 				continue;
 			}
 			/* clear all_ports_up flag if any link down */
diff --git a/app/test/test_pmd_perf.c b/app/test/test_pmd_perf.c
index 352cd4715..8ce464b56 100644
--- a/app/test/test_pmd_perf.c
+++ b/app/test/test_pmd_perf.c
@@ -126,6 +126,7 @@ check_all_ports_link_status(uint16_t port_num, uint32_t port_mask)
 	uint8_t count, all_ports_up, print_flag = 0;
 	struct rte_eth_link link;
 	int ret;
+	char link_status[50];
 
 	printf("Checking link statuses...\n");
 	fflush(stdout);
@@ -146,16 +147,12 @@ check_all_ports_link_status(uint16_t port_num, uint32_t port_mask)
 
 			/* print link status if flag set */
 			if (print_flag == 1) {
-				if (link.link_status) {
-					printf(
-					"Port%d Link Up. Speed %u Mbps - %s\n",
-						portid, link.link_speed,
-				(link.link_duplex == ETH_LINK_FULL_DUPLEX) ?
-					("full-duplex") : ("half-duplex"));
-					if (link_mbps == 0)
-						link_mbps = link.link_speed;
-				} else
-					printf("Port %d Link Down\n", portid);
+				if (link.link_status && link_mbps == 0)
+					link_mbps = link.link_speed;
+
+				rte_eth_link_format(link_status, 50, NULL,
+						    &link);
+				printf("Port %d %s\n", portid, link_status);
 				continue;
 			}
 			/* clear all_ports_up flag if any link down */
-- 
2.17.1


^ permalink raw reply	[flat|nested] 359+ messages in thread

* [dpdk-dev] [PATCH v4 4/7] doc: update sample app with unknown speed
       [not found]                             ` <CGME20200702132213eucas1p2e0d68a0089f372e81e5a5f9bc622f9a0@eucas1p2.samsung.com>
@ 2020-07-02 13:21                               ` Ivan Dyukov
  0 siblings, 0 replies; 359+ messages in thread
From: Ivan Dyukov @ 2020-07-02 13:21 UTC (permalink / raw)
  To: dev, i.dyukov, v.kuramshin, thomas, david.marchand, ferruh.yigit,
	arybchenko, wei.zhao1, jia.guo, beilei.xing, qiming.yang,
	wenzhuo.lu, mb, stephen

Add usage of rte_eth_link_format function to example
applications

Signed-off-by: Ivan Dyukov <i.dyukov@samsung.com>
---
 doc/guides/sample_app_ug/link_status_intr.rst | 10 +++++-----
 1 file changed, 5 insertions(+), 5 deletions(-)

diff --git a/doc/guides/sample_app_ug/link_status_intr.rst b/doc/guides/sample_app_ug/link_status_intr.rst
index 04c40f285..7d7b31798 100644
--- a/doc/guides/sample_app_ug/link_status_intr.rst
+++ b/doc/guides/sample_app_ug/link_status_intr.rst
@@ -158,6 +158,7 @@ An example callback function that has been written as indicated below.
     {
         struct rte_eth_link link;
         int ret;
+        char link_status[200];
 
         RTE_SET_USED(param);
 
@@ -169,11 +170,10 @@ An example callback function that has been written as indicated below.
         if (ret < 0) {
             printf("Failed to get port %d link status: %s\n\n",
                    port_id, rte_strerror(-ret));
-        } else if (link.link_status) {
-            printf("Port %d Link Up - speed %u Mbps - %s\n\n", port_id, (unsigned)link.link_speed,
-                  (link.link_duplex == ETH_LINK_FULL_DUPLEX) ? ("full-duplex") : ("half-duplex"));
-        } else
-            printf("Port %d Link Down\n\n", port_id);
+        } else {
+            rte_eth_link_format(link_status, 200, NULL, &link);
+            printf("Port %d %s\n\n", port_id, link_status);
+        }
     }
 
 This function is called when a link status interrupt is present for the right port.
-- 
2.17.1


^ permalink raw reply	[flat|nested] 359+ messages in thread

* [dpdk-dev] [PATCH v4 5/7] net/ixgbe: return unknown speed in status
       [not found]                             ` <CGME20200702132215eucas1p1f282fb3fd02e2107658bde6adc5d5166@eucas1p1.samsung.com>
@ 2020-07-02 13:21                               ` Ivan Dyukov
  2020-07-02 23:38                                 ` Zhao1, Wei
  0 siblings, 1 reply; 359+ messages in thread
From: Ivan Dyukov @ 2020-07-02 13:21 UTC (permalink / raw)
  To: dev, i.dyukov, v.kuramshin, thomas, david.marchand, ferruh.yigit,
	arybchenko, wei.zhao1, jia.guo, beilei.xing, qiming.yang,
	wenzhuo.lu, mb, stephen

rte_ethdev has declared new NUM_UNKNOWN speed which
could be used in case when no speed information is available

Signed-off-by: Ivan Dyukov <i.dyukov@samsung.com>
Reviewed-by: Wei Zhao <wei.zhao1@intel.com>
---
 drivers/net/ixgbe/ixgbe_ethdev.c | 6 +-----
 1 file changed, 1 insertion(+), 5 deletions(-)

diff --git a/drivers/net/ixgbe/ixgbe_ethdev.c b/drivers/net/ixgbe/ixgbe_ethdev.c
index a4e5c539d..5b9b13058 100644
--- a/drivers/net/ixgbe/ixgbe_ethdev.c
+++ b/drivers/net/ixgbe/ixgbe_ethdev.c
@@ -4311,11 +4311,7 @@ ixgbe_dev_link_update_share(struct rte_eth_dev *dev,
 	switch (link_speed) {
 	default:
 	case IXGBE_LINK_SPEED_UNKNOWN:
-		if (hw->device_id == IXGBE_DEV_ID_X550EM_A_1G_T ||
-			hw->device_id == IXGBE_DEV_ID_X550EM_A_1G_T_L)
-			link.link_speed = ETH_SPEED_NUM_10M;
-		else
-			link.link_speed = ETH_SPEED_NUM_100M;
+		link.link_speed = ETH_SPEED_NUM_UNKNOWN;
 		break;
 
 	case IXGBE_LINK_SPEED_100_FULL:
-- 
2.17.1


^ permalink raw reply	[flat|nested] 359+ messages in thread

* [dpdk-dev] [PATCH v4 6/7] net/i40e: return unknown speed in status
       [not found]                             ` <CGME20200702132217eucas1p1ff03745544095adbdc9f35edb6e9ec6b@eucas1p1.samsung.com>
@ 2020-07-02 13:21                               ` " Ivan Dyukov
  2020-07-03  8:13                                 ` Jeff Guo
  0 siblings, 1 reply; 359+ messages in thread
From: Ivan Dyukov @ 2020-07-02 13:21 UTC (permalink / raw)
  To: dev, i.dyukov, v.kuramshin, thomas, david.marchand, ferruh.yigit,
	arybchenko, wei.zhao1, jia.guo, beilei.xing, qiming.yang,
	wenzhuo.lu, mb, stephen

rte_ethdev has declared new NUM_UNKNOWN speed which
could be used in case when no speed information is available and
link is up. NUM_NONE should be returned, if link is down.

Signed-off-by: Ivan Dyukov <i.dyukov@samsung.com>
---
 drivers/net/i40e/i40e_ethdev.c    |  5 ++++-
 drivers/net/i40e/i40e_ethdev_vf.c | 10 +++++-----
 2 files changed, 9 insertions(+), 6 deletions(-)

diff --git a/drivers/net/i40e/i40e_ethdev.c b/drivers/net/i40e/i40e_ethdev.c
index 749d85f54..d09b77674 100644
--- a/drivers/net/i40e/i40e_ethdev.c
+++ b/drivers/net/i40e/i40e_ethdev.c
@@ -2889,7 +2889,10 @@ update_link_aq(struct i40e_hw *hw, struct rte_eth_link *link,
 		link->link_speed = ETH_SPEED_NUM_40G;
 		break;
 	default:
-		link->link_speed = ETH_SPEED_NUM_NONE;
+		if (link->link_status)
+			link->link_speed = ETH_SPEED_NUM_UNKNOWN;
+		else
+			link->link_speed = ETH_SPEED_NUM_NONE;
 		break;
 	}
 }
diff --git a/drivers/net/i40e/i40e_ethdev_vf.c b/drivers/net/i40e/i40e_ethdev_vf.c
index bb5d28a44..1da185485 100644
--- a/drivers/net/i40e/i40e_ethdev_vf.c
+++ b/drivers/net/i40e/i40e_ethdev_vf.c
@@ -2165,15 +2165,15 @@ i40evf_dev_link_update(struct rte_eth_dev *dev,
 		new_link.link_speed = ETH_SPEED_NUM_40G;
 		break;
 	default:
-		new_link.link_speed = ETH_SPEED_NUM_NONE;
+		if (vf->link_up)
+			new_link.link_speed = ETH_SPEED_NUM_UNKNOWN;
+		else
+			new_link.link_speed = ETH_SPEED_NUM_NONE;
 		break;
 	}
 	/* full duplex only */
 	new_link.link_duplex = ETH_LINK_FULL_DUPLEX;
-	new_link.link_status = vf->link_up &&
-				new_link.link_speed != ETH_SPEED_NUM_NONE
-				? ETH_LINK_UP
-				: ETH_LINK_DOWN;
+	new_link.link_status = vf->link_up ? ETH_LINK_UP : ETH_LINK_DOWN;
 	new_link.link_autoneg =
 		!(dev->data->dev_conf.link_speeds & ETH_LINK_SPEED_FIXED);
 
-- 
2.17.1


^ permalink raw reply	[flat|nested] 359+ messages in thread

* [dpdk-dev] [PATCH v4 7/7] net/ice: return unknown speed in status
       [not found]                             ` <CGME20200702132219eucas1p2a4993ac0ae1dbb983d16dc80729a6dae@eucas1p2.samsung.com>
@ 2020-07-02 13:21                               ` " Ivan Dyukov
  0 siblings, 0 replies; 359+ messages in thread
From: Ivan Dyukov @ 2020-07-02 13:21 UTC (permalink / raw)
  To: dev, i.dyukov, v.kuramshin, thomas, david.marchand, ferruh.yigit,
	arybchenko, wei.zhao1, jia.guo, beilei.xing, qiming.yang,
	wenzhuo.lu, mb, stephen

rte_ethdev has declared new NUM_UNKNOWN speed which
could be used in case when no speed information is available and
link is up. NUM_NONE should be returned, if link is down.

Signed-off-by: Ivan Dyukov <i.dyukov@samsung.com>
Reviewed-by: Ferruh Yigit <ferruh.yigit@intel.com>
---
 drivers/net/ice/ice_ethdev.c | 5 ++++-
 1 file changed, 4 insertions(+), 1 deletion(-)

diff --git a/drivers/net/ice/ice_ethdev.c b/drivers/net/ice/ice_ethdev.c
index d5110c439..1c0c087ea 100644
--- a/drivers/net/ice/ice_ethdev.c
+++ b/drivers/net/ice/ice_ethdev.c
@@ -3112,8 +3112,11 @@ ice_link_update(struct rte_eth_dev *dev, int wait_to_complete)
 		link.link_speed = ETH_SPEED_NUM_100G;
 		break;
 	case ICE_AQ_LINK_SPEED_UNKNOWN:
-	default:
 		PMD_DRV_LOG(ERR, "Unknown link speed");
+		link.link_speed = ETH_SPEED_NUM_UNKNOWN;
+		break;
+	default:
+		PMD_DRV_LOG(ERR, "None link speed");
 		link.link_speed = ETH_SPEED_NUM_NONE;
 		break;
 	}
-- 
2.17.1


^ permalink raw reply	[flat|nested] 359+ messages in thread

* Re: [dpdk-dev] [PATCH v4 5/7] net/ixgbe: return unknown speed in status
  2020-07-02 13:21                               ` [dpdk-dev] [PATCH v4 5/7] net/ixgbe: return unknown speed in status Ivan Dyukov
@ 2020-07-02 23:38                                 ` Zhao1, Wei
  0 siblings, 0 replies; 359+ messages in thread
From: Zhao1, Wei @ 2020-07-02 23:38 UTC (permalink / raw)
  To: i.dyukov, dev, v.kuramshin, thomas, david.marchand, Yigit,
	Ferruh, arybchenko, Guo, Jia, Xing, Beilei, Yang, Qiming, Lu,
	Wenzhuo, mb, stephen


> -----Original Message-----
> From: Ivan Dyukov <i.dyukov@samsung.com>
> Sent: Thursday, July 2, 2020 9:22 PM
> To: dev@dpdk.org; i.dyukov@samsung.com; v.kuramshin@samsung.com;
> thomas@monjalon.net; david.marchand@redhat.com; Yigit, Ferruh
> <ferruh.yigit@intel.com>; arybchenko@solarflare.com; Zhao1, Wei
> <wei.zhao1@intel.com>; Guo, Jia <jia.guo@intel.com>; Xing, Beilei
> <beilei.xing@intel.com>; Yang, Qiming <qiming.yang@intel.com>; Lu,
> Wenzhuo <wenzhuo.lu@intel.com>; mb@smartsharesystems.com;
> stephen@networkplumber.org
> Subject: [PATCH v4 5/7] net/ixgbe: return unknown speed in status
> 
> rte_ethdev has declared new NUM_UNKNOWN speed which could be used in
> case when no speed information is available
> 
> Signed-off-by: Ivan Dyukov <i.dyukov@samsung.com>
> Reviewed-by: Wei Zhao <wei.zhao1@intel.com>
> ---
>  drivers/net/ixgbe/ixgbe_ethdev.c | 6 +-----
>  1 file changed, 1 insertion(+), 5 deletions(-)
> 
> diff --git a/drivers/net/ixgbe/ixgbe_ethdev.c
> b/drivers/net/ixgbe/ixgbe_ethdev.c
> index a4e5c539d..5b9b13058 100644
> --- a/drivers/net/ixgbe/ixgbe_ethdev.c
> +++ b/drivers/net/ixgbe/ixgbe_ethdev.c
> @@ -4311,11 +4311,7 @@ ixgbe_dev_link_update_share(struct rte_eth_dev
> *dev,
>  	switch (link_speed) {
>  	default:
>  	case IXGBE_LINK_SPEED_UNKNOWN:
> -		if (hw->device_id == IXGBE_DEV_ID_X550EM_A_1G_T ||
> -			hw->device_id == IXGBE_DEV_ID_X550EM_A_1G_T_L)
> -			link.link_speed = ETH_SPEED_NUM_10M;
> -		else
> -			link.link_speed = ETH_SPEED_NUM_100M;
> +		link.link_speed = ETH_SPEED_NUM_UNKNOWN;
>  		break;
> 
>  	case IXGBE_LINK_SPEED_100_FULL:
> --
> 2.17.1


Reviewed-by: Wei Zhao <wei.zhao1@intel.com>


^ permalink raw reply	[flat|nested] 359+ messages in thread

* Re: [dpdk-dev] [PATCH v4 6/7] net/i40e: return unknown speed in status
  2020-07-02 13:21                               ` [dpdk-dev] [PATCH v4 6/7] net/i40e: " Ivan Dyukov
@ 2020-07-03  8:13                                 ` Jeff Guo
  0 siblings, 0 replies; 359+ messages in thread
From: Jeff Guo @ 2020-07-03  8:13 UTC (permalink / raw)
  To: i.dyukov, dev, v.kuramshin, thomas, david.marchand, ferruh.yigit,
	arybchenko, wei.zhao1, beilei.xing, qiming.yang, wenzhuo.lu, mb,
	stephen


On 7/2/2020 9:21 PM, Ivan Dyukov wrote:
> rte_ethdev has declared new NUM_UNKNOWN speed which
> could be used in case when no speed information is available and
> link is up. NUM_NONE should be returned, if link is down.
>
> Signed-off-by: Ivan Dyukov <i.dyukov@samsung.com>
> ---
>   drivers/net/i40e/i40e_ethdev.c    |  5 ++++-
>   drivers/net/i40e/i40e_ethdev_vf.c | 10 +++++-----
>   2 files changed, 9 insertions(+), 6 deletions(-)
>
> diff --git a/drivers/net/i40e/i40e_ethdev.c b/drivers/net/i40e/i40e_ethdev.c
> index 749d85f54..d09b77674 100644
> --- a/drivers/net/i40e/i40e_ethdev.c
> +++ b/drivers/net/i40e/i40e_ethdev.c
> @@ -2889,7 +2889,10 @@ update_link_aq(struct i40e_hw *hw, struct rte_eth_link *link,
>   		link->link_speed = ETH_SPEED_NUM_40G;
>   		break;
>   	default:
> -		link->link_speed = ETH_SPEED_NUM_NONE;
> +		if (link->link_status)
> +			link->link_speed = ETH_SPEED_NUM_UNKNOWN;
> +		else
> +			link->link_speed = ETH_SPEED_NUM_NONE;
>   		break;
>   	}
>   }
> diff --git a/drivers/net/i40e/i40e_ethdev_vf.c b/drivers/net/i40e/i40e_ethdev_vf.c
> index bb5d28a44..1da185485 100644
> --- a/drivers/net/i40e/i40e_ethdev_vf.c
> +++ b/drivers/net/i40e/i40e_ethdev_vf.c
> @@ -2165,15 +2165,15 @@ i40evf_dev_link_update(struct rte_eth_dev *dev,
>   		new_link.link_speed = ETH_SPEED_NUM_40G;
>   		break;
>   	default:
> -		new_link.link_speed = ETH_SPEED_NUM_NONE;
> +		if (vf->link_up)
> +			new_link.link_speed = ETH_SPEED_NUM_UNKNOWN;
> +		else
> +			new_link.link_speed = ETH_SPEED_NUM_NONE;
>   		break;
>   	}
>   	/* full duplex only */
>   	new_link.link_duplex = ETH_LINK_FULL_DUPLEX;
> -	new_link.link_status = vf->link_up &&
> -				new_link.link_speed != ETH_SPEED_NUM_NONE
> -				? ETH_LINK_UP
> -				: ETH_LINK_DOWN;
> +	new_link.link_status = vf->link_up ? ETH_LINK_UP : ETH_LINK_DOWN;
>   	new_link.link_autoneg =
>   		!(dev->data->dev_conf.link_speeds & ETH_LINK_SPEED_FIXED);
>   

Acked-by: Jeff Guo <jia.guo@intel.com <mailto:jia.guo@intel.com>>


^ permalink raw reply	[flat|nested] 359+ messages in thread

* [dpdk-dev] [PATCH v5 0/25] ethdev: allow unknown link speed
       [not found]                         ` <CGME20200706202639eucas1p1a311b447521d1128a00483e1ca2f482a@eucas1p1.samsung.com>
@ 2020-07-06 20:25                           ` Ivan Dyukov
       [not found]                             ` <CGME20200706202642eucas1p2929ffa3795a06b1e99d19a6b0e90da76@eucas1p2.samsung.com>
                                               ` (24 more replies)
  0 siblings, 25 replies; 359+ messages in thread
From: Ivan Dyukov @ 2020-07-06 20:25 UTC (permalink / raw)
  To: dev, i.dyukov, v.kuramshin, thomas, david.marchand, ferruh.yigit,
	arybchenko, wei.zhao1, jia.guo, beilei.xing, qiming.yang,
	wenzhuo.lu, mb, stephen, nicolas.chautru, bruce.richardson,
	konstantin.ananyev, cristian.dumitrescu, radu.nicolau,
	akhil.goyal, declan.doherty, skori, pbhagavatula, jerinj,
	kirankumark, david.hunt, anatoly.burakov, xiaoyun.li,
	jingjing.wu, john.mcnamara, jasvinder.singh, byron.marohn,
	yipeng1.wang

MAINTAINERS                                              |   1 +
 app/proc-info/main.c                                     |   9 ++----
 app/test-pipeline/init.c                                 |  11 ++++---
 app/test-pmd/config.c                                    |  20 ++++++++-----
 app/test-pmd/testpmd.c                                   |   9 +-----
 app/test/Makefile                                        |   3 ++
 app/test/meson.build                                     |   2 ++
 app/test/test_ethdev_link.c                              | 278 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 app/test/test_pmd_perf.c                                 |  17 +++++------
 doc/guides/sample_app_ug/link_status_intr.rst            |  10 +++----
 drivers/net/i40e/i40e_ethdev.c                           |   5 +++-
 drivers/net/i40e/i40e_ethdev_vf.c                        |  10 +++----
 drivers/net/ice/ice_ethdev.c                             |   5 +++-
 drivers/net/ixgbe/ixgbe_ethdev.c                         |   6 +---
 examples/bbdev_app/main.c                                |   8 ++---
 examples/ioat/ioatfwd.c                                  |  13 ++++----
 examples/ip_fragmentation/main.c                         |  13 ++++----
 examples/ip_pipeline/cli.c                               |  12 ++++----
 examples/ip_reassembly/main.c                            |  12 +++-----
 examples/ipsec-secgw/ipsec-secgw.c                       |  12 +++-----
 examples/ipv4_multicast/main.c                           |  12 +++-----
 examples/kni/main.c                                      |  26 ++++++----------
 examples/l2fwd-crypto/main.c                             |  12 +++-----
 examples/l2fwd-event/main.c                              |  12 +++-----
 examples/l2fwd-jobstats/main.c                           |  12 +++-----
 examples/l2fwd-keepalive/main.c                          |  12 +++-----
 examples/l2fwd/main.c                                    |  12 +++-----
 examples/l3fwd-acl/main.c                                |  12 +++-----
 examples/l3fwd-graph/main.c                              |  14 +++------
 examples/l3fwd-power/main.c                              |  13 +++-----
 examples/l3fwd/main.c                                    |  12 +++-----
 examples/link_status_interrupt/main.c                    |  30 ++++++++-----------
 examples/multi_process/client_server_mp/mp_server/init.c |  14 ++++-----
 examples/multi_process/symmetric_mp/main.c               |  12 +++-----
 examples/ntb/ntb_fwd.c                                   |  10 +++----
 examples/performance-thread/l3fwd-thread/main.c          |  12 +++-----
 examples/qos_sched/init.c                                |  10 ++-----
 examples/server_node_efd/server/init.c                   |  15 ++++------
 examples/vm_power_manager/main.c                         |  14 ++++-----
 lib/librte_ethdev/rte_ethdev.c                           | 169 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 lib/librte_ethdev/rte_ethdev.h                           |  74 +++++++++++++++++++++++++++++++++++++++-------
 lib/librte_ethdev/rte_ethdev_version.map                 |   4 +++
 42 files changed, 687 insertions(+), 282 deletions(-)

v5 changes:
* rename rte_eth_link_format to rte_eth_link_strf
* add '\n' to default strings
* update remaining examples. patch with subj 'examples: new link status print format' contains examples which have no maintainers.
TBD:
update remaining nic drivers with 'unknown' speed.  It should be provided in separate patchset.

v4 changes:
* refactor rte_eth_link_format using strlcat func instead of snprintf
* added new checks to unit tests
* few minor fixes according review comments
TBD:
update examples in 'example' folder with new status printing mechanism
update remaining nic drivers with 'unknown' speed

v3 changes:
* remove rte_eth_link_prepare_text function
* add rte_eth_link_format and rte_eth_link_printf functions
* added unit tests for rte_eth_link_format function
TBD:
update examples in 'example' folder with new status printing mechanism
update remaining nic drivers with 'unknown' speed

v2 changes:
* add function which format link status to textual representation
* update drivers for Intel nics with 'unknown' speed
TBD:
update examples in 'example' folder with new status printing mechanism
update remaining nic drivers with 'unknown' speed

v1 changes:
This is initial patchset which introduces UNKNOWN speed to dpdk
applications. Also it contains changes related to printf formating.
Patchset contains changes for app/ and doc/ folders.
examples/ folder will be provided later.



^ permalink raw reply	[flat|nested] 359+ messages in thread

* [dpdk-dev] [PATCH v5 01/25] ethdev: allow unknown link speed
       [not found]                             ` <CGME20200706202642eucas1p2929ffa3795a06b1e99d19a6b0e90da76@eucas1p2.samsung.com>
@ 2020-07-06 20:25                               ` " Ivan Dyukov
  0 siblings, 0 replies; 359+ messages in thread
From: Ivan Dyukov @ 2020-07-06 20:25 UTC (permalink / raw)
  To: dev, i.dyukov, v.kuramshin, thomas, david.marchand, ferruh.yigit,
	arybchenko, wei.zhao1, jia.guo, beilei.xing, qiming.yang,
	wenzhuo.lu, mb, stephen, nicolas.chautru, bruce.richardson,
	konstantin.ananyev, cristian.dumitrescu, radu.nicolau,
	akhil.goyal, declan.doherty, skori, pbhagavatula, jerinj,
	kirankumark, david.hunt, anatoly.burakov, xiaoyun.li,
	jingjing.wu, john.mcnamara, jasvinder.singh, byron.marohn,
	yipeng1.wang

From: Thomas Monjalon <thomas@monjalon.net>

When querying the link information, the link status is
a mandatory major information.
Other boolean values are supposed to be accurate:
	- duplex mode (half/full)
	- negotiation (auto/fixed)

This API update is making explicit that the link speed information
is optional.
The value ETH_SPEED_NUM_NONE (0) was already part of the API.
The value ETH_SPEED_NUM_UNKNOWN (infinite) is added to cover
two different cases:
	- speed is not known by the driver
	- device is virtual

Suggested-by: Morten Brørup <mb@smartsharesystems.com>
Suggested-by: Benoit Ganne <bganne@cisco.com>
Signed-off-by: Thomas Monjalon <thomas@monjalon.net>
Reviewed-by: Ferruh Yigit <ferruh.yigit@intel.com>
---
 lib/librte_ethdev/rte_ethdev.h | 20 ++++++++++----------
 1 file changed, 10 insertions(+), 10 deletions(-)

diff --git a/lib/librte_ethdev/rte_ethdev.h b/lib/librte_ethdev/rte_ethdev.h
index a49242bcd..2090af501 100644
--- a/lib/librte_ethdev/rte_ethdev.h
+++ b/lib/librte_ethdev/rte_ethdev.h
@@ -303,6 +303,7 @@ struct rte_eth_stats {
 #define ETH_SPEED_NUM_56G      56000 /**<  56 Gbps */
 #define ETH_SPEED_NUM_100G    100000 /**< 100 Gbps */
 #define ETH_SPEED_NUM_200G    200000 /**< 200 Gbps */
+#define ETH_SPEED_NUM_UNKNOWN UINT32_MAX /**< Unknown */
 
 /**
  * A structure used to retrieve link-level information of an Ethernet port.
@@ -2262,15 +2263,16 @@ int rte_eth_allmulticast_disable(uint16_t port_id);
 int rte_eth_allmulticast_get(uint16_t port_id);
 
 /**
- * Retrieve the status (ON/OFF), the speed (in Mbps) and the mode (HALF-DUPLEX
- * or FULL-DUPLEX) of the physical link of an Ethernet device. It might need
- * to wait up to 9 seconds in it.
+ * Retrieve the link status (up/down), the duplex mode (half/full),
+ * the negotiation (auto/fixed), and if available, the speed (Mbps).
+ *
+ * It might need to wait up to 9 seconds.
+ * @see rte_eth_link_get_nowait.
  *
  * @param port_id
  *   The port identifier of the Ethernet device.
  * @param link
- *   A pointer to an *rte_eth_link* structure to be filled with
- *   the status, the speed and the mode of the Ethernet device link.
+ *   Link information written back.
  * @return
  *   - (0) if successful.
  *   - (-ENOTSUP) if the function is not supported in PMD driver.
@@ -2279,15 +2281,13 @@ int rte_eth_allmulticast_get(uint16_t port_id);
 int rte_eth_link_get(uint16_t port_id, struct rte_eth_link *link);
 
 /**
- * Retrieve the status (ON/OFF), the speed (in Mbps) and the mode (HALF-DUPLEX
- * or FULL-DUPLEX) of the physical link of an Ethernet device. It is a no-wait
- * version of rte_eth_link_get().
+ * Retrieve the link status (up/down), the duplex mode (half/full),
+ * the negotiation (auto/fixed), and if available, the speed (Mbps).
  *
  * @param port_id
  *   The port identifier of the Ethernet device.
  * @param link
- *   A pointer to an *rte_eth_link* structure to be filled with
- *   the status, the speed and the mode of the Ethernet device link.
+ *   Link information written back.
  * @return
  *   - (0) if successful.
  *   - (-ENOTSUP) if the function is not supported in PMD driver.
-- 
2.17.1


^ permalink raw reply	[flat|nested] 359+ messages in thread

* [dpdk-dev] [PATCH v5 02/25] ethdev: add a link status text representation
       [not found]                             ` <CGME20200706202645eucas1p13880f5302149ddf67a2f814290111286@eucas1p1.samsung.com>
@ 2020-07-06 20:25                               ` Ivan Dyukov
  0 siblings, 0 replies; 359+ messages in thread
From: Ivan Dyukov @ 2020-07-06 20:25 UTC (permalink / raw)
  To: dev, i.dyukov, v.kuramshin, thomas, david.marchand, ferruh.yigit,
	arybchenko, wei.zhao1, jia.guo, beilei.xing, qiming.yang,
	wenzhuo.lu, mb, stephen, nicolas.chautru, bruce.richardson,
	konstantin.ananyev, cristian.dumitrescu, radu.nicolau,
	akhil.goyal, declan.doherty, skori, pbhagavatula, jerinj,
	kirankumark, david.hunt, anatoly.burakov, xiaoyun.li,
	jingjing.wu, john.mcnamara, jasvinder.singh, byron.marohn,
	yipeng1.wang

This commit add function which treat link status structure
and format it to text representation.

Signed-off-by: Ivan Dyukov <i.dyukov@samsung.com>
---
 MAINTAINERS                              |   1 +
 app/test/Makefile                        |   3 +
 app/test/meson.build                     |   2 +
 app/test/test_ethdev_link.c              | 278 +++++++++++++++++++++++
 lib/librte_ethdev/rte_ethdev.c           | 169 ++++++++++++++
 lib/librte_ethdev/rte_ethdev.h           |  54 +++++
 lib/librte_ethdev/rte_ethdev_version.map |   4 +
 7 files changed, 511 insertions(+)
 create mode 100644 app/test/test_ethdev_link.c

diff --git a/MAINTAINERS b/MAINTAINERS
index 5e706cd7e..f4fb31ea2 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -393,6 +393,7 @@ T: git://dpdk.org/next/dpdk-next-net
 F: lib/librte_ethdev/
 F: devtools/test-null.sh
 F: doc/guides/prog_guide/switch_representation.rst
+F: app/test/test_ethdev*
 
 Flow API
 M: Ori Kam <orika@mellanox.com>
diff --git a/app/test/Makefile b/app/test/Makefile
index e5440774b..9f43b8c3c 100644
--- a/app/test/Makefile
+++ b/app/test/Makefile
@@ -251,6 +251,9 @@ SRCS-$(CONFIG_RTE_LIBRTE_SECURITY) += test_security.c
 
 SRCS-$(CONFIG_RTE_LIBRTE_IPSEC) += test_ipsec.c test_ipsec_perf.c
 SRCS-$(CONFIG_RTE_LIBRTE_IPSEC) += test_ipsec_sad.c
+
+SRCS-$(CONFIG_RTE_LIBRTE_ETHER) += test_ethdev_link.c
+
 ifeq ($(CONFIG_RTE_LIBRTE_IPSEC),y)
 LDLIBS += -lrte_ipsec
 endif
diff --git a/app/test/meson.build b/app/test/meson.build
index 56591db4e..6df31a4dc 100644
--- a/app/test/meson.build
+++ b/app/test/meson.build
@@ -39,6 +39,7 @@ test_sources = files('commands.c',
 	'test_efd.c',
 	'test_efd_perf.c',
 	'test_errno.c',
+	'test_ethdev_link.c',
 	'test_event_crypto_adapter.c',
 	'test_event_eth_rx_adapter.c',
 	'test_event_ring.c',
@@ -199,6 +200,7 @@ fast_tests = [
         ['eal_flags_misc_autotest', false],
         ['eal_fs_autotest', true],
         ['errno_autotest', true],
+        ['ethdev_link_status' true],
         ['event_ring_autotest', true],
         ['fib_autotest', true],
         ['fib6_autotest', true],
diff --git a/app/test/test_ethdev_link.c b/app/test/test_ethdev_link.c
new file mode 100644
index 000000000..4ece44a5b
--- /dev/null
+++ b/app/test/test_ethdev_link.c
@@ -0,0 +1,278 @@
+/* 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[128];
+	ret = rte_eth_link_strf(text, 128, NULL, &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 Gbit/s FDX Autoneg\n",
+		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_strf(text, 128, NULL, &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 Mbit/s HDX Fixed\n",
+		text, strlen(text), "Invalid default link status "
+		"string with HDX");
+
+	link_status.link_speed = ETH_SPEED_NUM_UNKNOWN,
+	ret = rte_eth_link_strf(text, 128, NULL, &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 speed HDX Fixed\n",
+		text, strlen(text), "Invalid default link status "
+		"string with HDX");
+	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[128];
+	ret = rte_eth_link_strf(text, 128, NULL, &link_status);
+	RTE_TEST_ASSERT(ret > 0, "Failed to format default string\n");
+	TEST_ASSERT_BUFFERS_ARE_EQUAL("Link down\n",
+		text, strlen(text), "Invalid default link status string");
+
+	return TEST_SUCCESS;
+}
+
+static int32_t
+test_link_status_string_overflow(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[128];
+	int i = 0;
+	for (i = 0; i < 128; i++)
+		text[i] = 'Y';
+	text[127] = '\0';
+
+	ret = rte_eth_link_strf(NULL, 2, "status %S, %G Gbits/s",
+		&link_status);
+	RTE_TEST_ASSERT(ret < 0, "Format string should fail, but it's ok\n");
+
+	ret = rte_eth_link_strf(text, 2, "status %S, %G Gbits/s",
+		&link_status);
+	RTE_TEST_ASSERT(ret < 0, "Format string should fail, but it's ok\n");
+	RTE_TEST_ASSERT(text[2] == 'Y', "String1 overflow\n");
+
+	ret = rte_eth_link_strf(text, 8, NULL,
+		&link_status);
+	RTE_TEST_ASSERT(ret < 0, "Default format string should fail,"
+			" but it's ok\n");
+	RTE_TEST_ASSERT(text[8] == 'Y', "String1 overflow\n");
+
+	ret = rte_eth_link_strf(text, 10, NULL,
+		&link_status);
+	RTE_TEST_ASSERT(ret < 0, "Default format string should fail,"
+			" but it's ok\n");
+	RTE_TEST_ASSERT(text[10] == 'Y', "String1 overflow\n");
+
+	text[1] = 'Y';
+	ret = rte_eth_link_strf(text, 1, "%S",
+		&link_status);
+	RTE_TEST_ASSERT(ret < 0, "Status string should fail, but it's ok\n");
+	RTE_TEST_ASSERT(text[1] == 'Y', "String1 overflow\n");
+
+	return TEST_SUCCESS;
+}
+
+static int32_t
+test_link_status_format(void)
+{
+	int ret = 0;
+	struct rte_eth_link link_status = {
+		.link_speed = ETH_SPEED_NUM_40G,
+		.link_status = ETH_LINK_UP,
+		.link_autoneg = ETH_LINK_AUTONEG,
+		.link_duplex = ETH_LINK_FULL_DUPLEX
+	};
+	char text[128];
+	int i = 0;
+	for (i = 0; i < 128; i++)
+		text[i] = 'Y';
+	text[127] = '\0';
+	printf("status format #1: %s\n", text);
+	ret = rte_eth_link_strf(text, 128, "status = %S, duplex = %D\n",
+		&link_status);
+	printf("status format #2: %s\n", text);
+	RTE_TEST_ASSERT(ret > 0, "Failed to format string\n");
+	TEST_ASSERT_BUFFERS_ARE_EQUAL("status = Up, duplex = FDX\n",
+		text, strlen(text), "Invalid status string1.");
+
+	ret = rte_eth_link_strf(text, 128, "%A", &link_status);
+	printf("status format #3: %s\n", text);
+	RTE_TEST_ASSERT(ret > 0, "Failed to format string\n");
+	TEST_ASSERT_BUFFERS_ARE_EQUAL("Autoneg",
+		text, strlen(text), "Invalid status string2.");
+
+	ret = rte_eth_link_strf(text, 128,
+		"%G",
+		&link_status);
+	printf("status format #4: %s\n", text);
+	RTE_TEST_ASSERT(ret > 0, "Failed to format string\n");
+	TEST_ASSERT_BUFFERS_ARE_EQUAL("40.0",
+		text, strlen(text), "Invalid status string3.");
+
+	ret = rte_eth_link_strf(text, 128,
+		"%M",
+		&link_status);
+	printf("status format #5: %s\n", text);
+	RTE_TEST_ASSERT(ret > 0, "Failed to format string\n");
+	TEST_ASSERT_BUFFERS_ARE_EQUAL("40000",
+		text, strlen(text), "Invalid status string4.");
+	return TEST_SUCCESS;
+}
+
+static int32_t
+test_link_status_return_value(void)
+{
+	int ret = 0;
+	struct rte_eth_link link_status = {
+		.link_speed = ETH_SPEED_NUM_40G,
+		.link_status = ETH_LINK_UP,
+		.link_autoneg = ETH_LINK_AUTONEG,
+		.link_duplex = ETH_LINK_FULL_DUPLEX
+	};
+	char text[128];
+	int i = 0;
+	for (i = 0; i < 128; i++)
+		text[i] = 'Y';
+	text[127] = '\0';
+	ret = rte_eth_link_strf(text, 128, "status = %S, ",
+		&link_status);
+	printf("return value #1:ret=%u, text=%s\n", ret, text);
+	ret += rte_eth_link_strf(text + ret, 128 - ret,
+		"%A",
+		&link_status);
+	printf("return value #2:ret=%u, text=%s\n", ret, text);
+	ret += rte_eth_link_strf(text + ret, 128 - ret,
+		", duplex = %D\n",
+		&link_status);
+	printf("return value #3:ret=%u, text=%s\n", ret, text);
+	ret += rte_eth_link_strf(text + ret, 128 - ret,
+		"%M Mbits/s\n",
+		&link_status);
+	printf("return value #4:ret=%u, text=%s\n", ret, text);
+	RTE_TEST_ASSERT(ret > 0, "Failed to format string\n");
+	TEST_ASSERT_BUFFERS_ARE_EQUAL("status = Up, Autoneg, duplex = FDX\n"
+		"40000 Mbits/s\n",
+		text, strlen(text), "Invalid status string");
+
+	return TEST_SUCCESS;
+}
+
+static int32_t
+test_link_status_invalid_fmt(void)
+{
+	int ret = 0;
+	struct rte_eth_link link_status = {
+		.link_speed = ETH_SPEED_NUM_40G,
+		.link_status = ETH_LINK_UP,
+		.link_autoneg = ETH_LINK_AUTONEG,
+		.link_duplex = ETH_LINK_FULL_DUPLEX
+	};
+	char text[128];
+	ret = rte_eth_link_strf(text, 128, "status = %",
+		&link_status);
+	RTE_TEST_ASSERT(ret < 0, "Status string1 should fail, but it's ok\n");
+	ret = rte_eth_link_strf(text, 128,
+		", duplex = %d\n",
+		&link_status);
+	RTE_TEST_ASSERT(ret < 0, "Status string2 should fail, but it's ok\n");
+	ret = rte_eth_link_strf(text, 128,
+		"% Mbits/s\n",
+		&link_status);
+	RTE_TEST_ASSERT(ret < 0, "Status string3 should fail, but it's ok\n");
+
+	return TEST_SUCCESS;
+}
+
+static int32_t
+test_link_status_format_edges(void)
+{
+	int ret = 0;
+	struct rte_eth_link link_status = {
+		.link_speed = ETH_SPEED_NUM_UNKNOWN,
+		.link_status = ETH_LINK_DOWN,
+		.link_autoneg = ETH_LINK_AUTONEG,
+		.link_duplex = ETH_LINK_HALF_DUPLEX
+	};
+	char text[128];
+	ret = rte_eth_link_strf(text, 4, "%S", &link_status);
+	printf("format edges #1: %s\n", text);
+	RTE_TEST_ASSERT(ret < 0, "It should fail. No space for "
+				 "zero terminator\n");
+	ret = rte_eth_link_strf(text, 6, "123%D", &link_status);
+	printf("format edges #2: %s\n", text);
+	RTE_TEST_ASSERT(ret < 0, "It should fail. No space for "
+				 "zero terminator\n");
+	ret = rte_eth_link_strf(text, 7, "%A", &link_status);
+	printf("format edges #3: %s\n", text);
+	RTE_TEST_ASSERT(ret < 0, "It should fail. No space for "
+				 "zero terminator\n");
+	ret = rte_eth_link_strf(text, 8, "%A", &link_status);
+	printf("format edges #4: %s\n", text);
+	RTE_TEST_ASSERT(ret > 0, "It should ok, but it fails\n");
+	return TEST_SUCCESS;
+}
+static struct unit_test_suite link_status_testsuite = {
+	.suite_name = "link status formating",
+	.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_status_string_overflow),
+		TEST_CASE(test_link_status_format),
+		TEST_CASE(test_link_status_format_edges),
+		TEST_CASE(test_link_status_invalid_fmt),
+		TEST_CASE(test_link_status_return_value),
+		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);
diff --git a/lib/librte_ethdev/rte_ethdev.c b/lib/librte_ethdev/rte_ethdev.c
index d06b7f9b1..ef5d6ac8c 100644
--- a/lib/librte_ethdev/rte_ethdev.c
+++ b/lib/librte_ethdev/rte_ethdev.c
@@ -2383,6 +2383,175 @@ rte_eth_link_get_nowait(uint16_t port_id, struct rte_eth_link *eth_link)
 	return 0;
 }
 
+static int
+rte_eth_link_strf_parser(char *str, size_t len, const char *const fmt,
+			   struct rte_eth_link *link)
+{
+	size_t offset = 0;
+	const char *fmt_cur = fmt;
+	char *str_cur = str;
+	double gbits = (double)link->link_speed / 1000.;
+	static const char AUTONEG_STR[]       = "Autoneg";
+	static const char FIXED_STR[]         = "Fixed";
+	static const char FDX_STR[]           = "FDX";
+	static const char HDX_STR[]           = "HDX";
+	static const char UNKNOWN_STR[]       = "Unknown";
+	static const char UP_STR[]            = "Up";
+	static const char DOWN_STR[]          = "Down";
+
+	char gbits_str[20];
+	char mbits_str[20];
+	/* preformat complex formating to easily concatinate it further */
+	snprintf(mbits_str, 20, "%u", link->link_speed);
+	snprintf(gbits_str, 20, "%.1f", gbits);
+	/* init str before formating */
+	str[0] = 0;
+	while (*fmt_cur) {
+		/* check str bounds */
+		if (offset > (len - 1)) {
+			str[len - 1] = '\0';
+			return -1;
+		}
+		if (*fmt_cur == '%') {
+			/* set null terminator to current position,
+			 * it's required for strlcat
+			 */
+			*str_cur = '\0';
+			switch (*++fmt_cur) {
+			/* Speed in Mbits/s */
+			case 'M':
+				if (link->link_speed ==
+				    ETH_SPEED_NUM_UNKNOWN)
+					offset = strlcat(str, UNKNOWN_STR,
+							 len);
+				else
+					offset = strlcat(str, mbits_str, len);
+				break;
+			/* Speed in Gbits/s */
+			case 'G':
+				if (link->link_speed ==
+				    ETH_SPEED_NUM_UNKNOWN)
+					offset = strlcat(str, UNKNOWN_STR,
+							 len);
+				else
+					offset = strlcat(str, gbits_str, len);
+				break;
+			/* Link status */
+			case 'S':
+				offset = strlcat(str, link->link_status ?
+					UP_STR : DOWN_STR, len);
+				break;
+			/* Link autoneg */
+			case 'A':
+				offset = strlcat(str, link->link_autoneg ?
+					AUTONEG_STR : FIXED_STR, len);
+				break;
+			/* Link duplex */
+			case 'D':
+				offset = strlcat(str, link->link_duplex ?
+					FDX_STR : HDX_STR, len);
+				break;
+			/* Error cases */
+			default:
+				return -1;
+
+			}
+			if (offset > (len - 1))
+				return -1;
+
+			str_cur = str + offset;
+		} else {
+			*str_cur++ = *fmt_cur;
+			offset++;
+		}
+		fmt_cur++;
+	}
+	*str_cur = '\0';
+	return offset;
+}
+
+int
+rte_eth_link_printf(const char *const fmt,
+		    struct rte_eth_link *link)
+{
+	char text[200];
+	int ret;
+	ret = rte_eth_link_strf(text, 200, fmt, link);
+	if (ret > 0)
+		printf("%s", text);
+	return ret;
+}
+
+int
+rte_eth_link_strf(char *str, size_t len, const char *const fmt,
+		    struct rte_eth_link *link)
+{
+	size_t offset = 0;
+	double gbits = (double)link->link_speed / 1000.;
+	char gbits_str[20];
+	char mbits_str[20];
+	/* TBD: make it international? */
+	static const char LINK_DOWN_STR[]     = "Link down\n";
+	static const char LINK_UP_STR[]       = "Link up at ";
+	static const char UNKNOWN_SPEED_STR[] = "Unknown speed ";
+	static const char MBITS_STR[]	      = "Mbit/s";
+	static const char GBITS_STR[]	      = "Gbit/s";
+	static const char FDX_STR[]           = "FDX ";
+	static const char HDX_STR[]           = "HDX ";
+	/* autoneg is latest param in default string, so add '\n' */
+	static const char AUTONEG_STR[]       = "Autoneg\n";
+	static const char FIXED_STR[]         = "Fixed\n";
+	if (str == NULL || len == 0)
+		return -1;
+	/* default format string, if no fmt is specified */
+	if (fmt == NULL) {
+		if (link->link_status == ETH_LINK_DOWN) {
+			if (sizeof(LINK_DOWN_STR) > len)
+				return -1;
+			return strlcpy(str, LINK_DOWN_STR, len);
+		}
+
+		/* preformat complex strings to easily concatinate it further */
+		snprintf(mbits_str, 20, "%u %s ", link->link_speed, MBITS_STR);
+		snprintf(gbits_str, 20, "%.1f %s ", gbits, GBITS_STR);
+
+		offset = strlcpy(str, LINK_UP_STR, len);
+		/* reserve one byte to null terminator */
+		if (offset > (len - 1))
+			return -1;
+		/* link speed */
+		if (link->link_speed == ETH_SPEED_NUM_UNKNOWN) {
+			offset = strlcat(str, UNKNOWN_SPEED_STR, len);
+			if (offset > (len - 1))
+				return -1;
+		} else {
+			if (link->link_speed < ETH_SPEED_NUM_1G) {
+				offset = strlcat(str, mbits_str, len);
+				if (offset > (len - 1))
+					return -1;
+			} else {
+				offset = strlcat(str, gbits_str, len);
+				if (offset > (len - 1))
+					return -1;
+			}
+		}
+		/* link duplex */
+		offset = strlcat(str, link->link_duplex ?
+			       FDX_STR : HDX_STR, len);
+		if (offset > (len - 1))
+			return -1;
+		/* link autonegotiation */
+		offset = strlcat(str, link->link_autoneg ?
+			       AUTONEG_STR : FIXED_STR, len);
+		if (offset > (len - 1))
+			return -1;
+	/* Formated status */
+	} else
+		offset = rte_eth_link_strf_parser(str, len, fmt, link);
+
+	return offset;
+}
+
 int
 rte_eth_stats_get(uint16_t port_id, struct rte_eth_stats *stats)
 {
diff --git a/lib/librte_ethdev/rte_ethdev.h b/lib/librte_ethdev/rte_ethdev.h
index 2090af501..580f89382 100644
--- a/lib/librte_ethdev/rte_ethdev.h
+++ b/lib/librte_ethdev/rte_ethdev.h
@@ -2295,6 +2295,60 @@ int rte_eth_link_get(uint16_t port_id, struct rte_eth_link *link);
  */
 int rte_eth_link_get_nowait(uint16_t port_id, struct rte_eth_link *link);
 
+
+/**
+ * print formated link status to stdout. This function threats all
+ * special values like ETH_SPEED_NUM_UNKNOWN, ETH_LINK_DOWN etc. and convert
+ * them to textual representation.
+ *
+ * @param fmt
+ *   Format string which allow to format link status. If NULL is provided
+ *   , default formating will be applied.
+ *   Following specifiers are available:
+ *    - '%M' link speed in Mbits/s
+ *    - '%G' link speed in Gbits/s
+ *    - '%S' link status. e.g. Up or Down
+ *    - '%A' link autonegotiation state
+ *    - '%D' link duplex state
+ * @param link
+ *   Link status provided by rte_eth_link_get function
+ * @return
+ *   - Number of bytes written to stdout. In case of error, -1 is returned.
+ *
+ */
+__rte_experimental
+int rte_eth_link_printf(const char *const fmt,
+			struct rte_eth_link *link);
+
+/**
+ * Format link status to textual representation. This function threats all
+ * special values like ETH_SPEED_NUM_UNKNOWN, ETH_LINK_DOWN etc. and convert
+ * them to textual representation.
+ *
+ * @param str
+ *   A pointer to a string to be filled with textual representation of
+ *   device status.
+ * @param len
+ *   Length of available memory at 'str' string.
+ * @param fmt
+ *   Format string which allow to format link status. If NULL is provided
+ *   , default formating will be applied.
+ *   Following specifiers are available:
+ *    - '%M' link speed in Mbits/s
+ *    - '%G' link speed in Gbits/s
+ *    - '%S' link status. e.g. Up or Down
+ *    - '%A' link autonegotiation state
+ *    - '%D' link duplex state
+ * @param link
+ *   Link status provided by rte_eth_link_get function
+ * @return
+ *   - Number of bytes written to str array. In case of error, -1 is returned.
+ *
+ */
+__rte_experimental
+int rte_eth_link_strf(char *str, size_t len, const char *const fmt,
+			struct rte_eth_link *eth_link);
+
 /**
  * Retrieve the general I/O statistics of an Ethernet device.
  *
diff --git a/lib/librte_ethdev/rte_ethdev_version.map b/lib/librte_ethdev/rte_ethdev_version.map
index 715505604..6c80597d1 100644
--- a/lib/librte_ethdev/rte_ethdev_version.map
+++ b/lib/librte_ethdev/rte_ethdev_version.map
@@ -241,4 +241,8 @@ EXPERIMENTAL {
 	__rte_ethdev_trace_rx_burst;
 	__rte_ethdev_trace_tx_burst;
 	rte_flow_get_aged_flows;
+
+	# added in 20.08
+	rte_eth_link_strf;
+	rte_eth_link_printf;
 };
-- 
2.17.1


^ permalink raw reply	[flat|nested] 359+ messages in thread

* [dpdk-dev] [PATCH v5 03/25] app: UNKNOWN link speed print format
       [not found]                             ` <CGME20200706202648eucas1p17baebff6b2420c5b1c9e53a5dd51998c@eucas1p1.samsung.com>
@ 2020-07-06 20:25                               ` Ivan Dyukov
  0 siblings, 0 replies; 359+ messages in thread
From: Ivan Dyukov @ 2020-07-06 20:25 UTC (permalink / raw)
  To: dev, i.dyukov, v.kuramshin, thomas, david.marchand, ferruh.yigit,
	arybchenko, wei.zhao1, jia.guo, beilei.xing, qiming.yang,
	wenzhuo.lu, mb, stephen, nicolas.chautru, bruce.richardson,
	konstantin.ananyev, cristian.dumitrescu, radu.nicolau,
	akhil.goyal, declan.doherty, skori, pbhagavatula, jerinj,
	kirankumark, david.hunt, anatoly.burakov, xiaoyun.li,
	jingjing.wu, john.mcnamara, jasvinder.singh, byron.marohn,
	yipeng1.wang

Add usage of rte_eth_link_strf function to example
applications

Signed-off-by: Ivan Dyukov <i.dyukov@samsung.com>
---
 app/proc-info/main.c     |  9 +++------
 app/test-pipeline/init.c | 11 +++++------
 app/test-pmd/config.c    | 20 ++++++++++++--------
 app/test-pmd/testpmd.c   |  9 +--------
 app/test/test_pmd_perf.c | 17 +++++++----------
 5 files changed, 28 insertions(+), 38 deletions(-)

diff --git a/app/proc-info/main.c b/app/proc-info/main.c
index abeca4aab..4a4c572c3 100644
--- a/app/proc-info/main.c
+++ b/app/proc-info/main.c
@@ -685,12 +685,9 @@ show_port(void)
 			printf("Link get failed (port %u): %s\n",
 			       i, rte_strerror(-ret));
 		} else {
-			printf("\t  -- link speed %d duplex %d,"
-					" auto neg %d status %d\n",
-					link.link_speed,
-					link.link_duplex,
-					link.link_autoneg,
-					link.link_status);
+			rte_eth_link_printf("\t  -- link speed: %M, duplex: %D,"
+					" auto neg: %A, status: %S\n",
+					&link);
 		}
 		printf("\t  -- promiscuous (%d)\n",
 				rte_eth_promiscuous_get(i));
diff --git a/app/test-pipeline/init.c b/app/test-pipeline/init.c
index 67d54ae05..b59064672 100644
--- a/app/test-pipeline/init.c
+++ b/app/test-pipeline/init.c
@@ -155,7 +155,7 @@ static void
 app_ports_check_link(void)
 {
 	uint32_t all_ports_up, i;
-
+	char link_status_text[50];
 	all_ports_up = 1;
 
 	for (i = 0; i < app.n_ports; i++) {
@@ -173,12 +173,11 @@ app_ports_check_link(void)
 			all_ports_up = 0;
 			continue;
 		}
-
-		RTE_LOG(INFO, USER1, "Port %u (%u Gbps) %s\n",
+		rte_eth_link_strf(link_status_text, 50, "(%G Gbps) %S",
+				  &link);
+		RTE_LOG(INFO, USER1, "Port %u %s\n",
 			port,
-			link.link_speed / 1000,
-			link.link_status ? "UP" : "DOWN");
-
+			link_status_text);
 		if (link.link_status == ETH_LINK_DOWN)
 			all_ports_up = 0;
 	}
diff --git a/app/test-pmd/config.c b/app/test-pmd/config.c
index a7112c998..cb2795a94 100644
--- a/app/test-pmd/config.c
+++ b/app/test-pmd/config.c
@@ -604,10 +604,9 @@ port_infos_display(portid_t port_id)
 	} else
 		printf("\nmemory allocation on the socket: %u",port->socket_id);
 
-	printf("\nLink status: %s\n", (link.link_status) ? ("up") : ("down"));
-	printf("Link speed: %u Mbps\n", (unsigned) link.link_speed);
-	printf("Link duplex: %s\n", (link.link_duplex == ETH_LINK_FULL_DUPLEX) ?
-	       ("full-duplex") : ("half-duplex"));
+	rte_eth_link_printf("\nLink status: %S\n"
+			    "Link speed: %M Mbps\n"
+			    "Link duplex: %D\n", &link);
 
 	if (!rte_eth_dev_get_mtu(port_id, &mtu))
 		printf("MTU: %u\n", mtu);
@@ -730,6 +729,8 @@ port_summary_display(portid_t port_id)
 	struct rte_eth_link link;
 	struct rte_eth_dev_info dev_info;
 	char name[RTE_ETH_NAME_MAX_LEN];
+	char status_text[6];
+	char speed_text[12];
 	int ret;
 
 	if (port_id_is_invalid(port_id, ENABLED_WARN)) {
@@ -750,12 +751,14 @@ port_summary_display(portid_t port_id)
 	if (ret != 0)
 		return;
 
-	printf("%-4d %02X:%02X:%02X:%02X:%02X:%02X %-12s %-14s %-8s %uMbps\n",
+	rte_eth_link_strf(status_text, 6, "%S", &link);
+	rte_eth_link_strf(speed_text, 12, "%M", &link);
+	printf("%-4d %02X:%02X:%02X:%02X:%02X:%02X %-12s %-14s %-8s %sMbps\n",
 		port_id, mac_addr.addr_bytes[0], mac_addr.addr_bytes[1],
 		mac_addr.addr_bytes[2], mac_addr.addr_bytes[3],
 		mac_addr.addr_bytes[4], mac_addr.addr_bytes[5], name,
-		dev_info.driver_name, (link.link_status) ? ("up") : ("down"),
-		(unsigned int) link.link_speed);
+		dev_info.driver_name, status_text,
+		speed_text);
 }
 
 void
@@ -3899,7 +3902,8 @@ set_queue_rate_limit(portid_t port_id, uint16_t queue_idx, uint16_t rate)
 	ret = eth_link_get_nowait_print_err(port_id, &link);
 	if (ret < 0)
 		return 1;
-	if (rate > link.link_speed) {
+	if (link.link_speed != ETH_SPEED_NUM_UNKNOWN &&
+	    rate > link.link_speed) {
 		printf("Invalid rate value:%u bigger than link speed: %u\n",
 			rate, link.link_speed);
 		return 1;
diff --git a/app/test-pmd/testpmd.c b/app/test-pmd/testpmd.c
index 4989d22ca..a1b9c1c1c 100644
--- a/app/test-pmd/testpmd.c
+++ b/app/test-pmd/testpmd.c
@@ -3010,14 +3010,7 @@ check_all_ports_link_status(uint32_t port_mask)
 			}
 			/* print link status if flag set */
 			if (print_flag == 1) {
-				if (link.link_status)
-					printf(
-					"Port%d Link Up. speed %u Mbps- %s\n",
-					portid, link.link_speed,
-				(link.link_duplex == ETH_LINK_FULL_DUPLEX) ?
-					("full-duplex") : ("half-duplex"));
-				else
-					printf("Port %d Link Down\n", portid);
+				rte_eth_link_printf(NULL, &link);
 				continue;
 			}
 			/* clear all_ports_up flag if any link down */
diff --git a/app/test/test_pmd_perf.c b/app/test/test_pmd_perf.c
index 352cd4715..7ebe4efae 100644
--- a/app/test/test_pmd_perf.c
+++ b/app/test/test_pmd_perf.c
@@ -126,6 +126,7 @@ check_all_ports_link_status(uint16_t port_num, uint32_t port_mask)
 	uint8_t count, all_ports_up, print_flag = 0;
 	struct rte_eth_link link;
 	int ret;
+	char link_status[50];
 
 	printf("Checking link statuses...\n");
 	fflush(stdout);
@@ -146,16 +147,12 @@ check_all_ports_link_status(uint16_t port_num, uint32_t port_mask)
 
 			/* print link status if flag set */
 			if (print_flag == 1) {
-				if (link.link_status) {
-					printf(
-					"Port%d Link Up. Speed %u Mbps - %s\n",
-						portid, link.link_speed,
-				(link.link_duplex == ETH_LINK_FULL_DUPLEX) ?
-					("full-duplex") : ("half-duplex"));
-					if (link_mbps == 0)
-						link_mbps = link.link_speed;
-				} else
-					printf("Port %d Link Down\n", portid);
+				if (link.link_status && link_mbps == 0)
+					link_mbps = link.link_speed;
+
+				rte_eth_link_strf(link_status, 50, NULL,
+						  &link);
+				printf("Port %d %s\n", portid, link_status);
 				continue;
 			}
 			/* clear all_ports_up flag if any link down */
-- 
2.17.1


^ permalink raw reply	[flat|nested] 359+ messages in thread

* [dpdk-dev] [PATCH v5 04/25] doc: update sample app with unknown speed
       [not found]                             ` <CGME20200706202650eucas1p129e158e9a86b26d047a592c32d019ab3@eucas1p1.samsung.com>
@ 2020-07-06 20:25                               ` Ivan Dyukov
  0 siblings, 0 replies; 359+ messages in thread
From: Ivan Dyukov @ 2020-07-06 20:25 UTC (permalink / raw)
  To: dev, i.dyukov, v.kuramshin, thomas, david.marchand, ferruh.yigit,
	arybchenko, wei.zhao1, jia.guo, beilei.xing, qiming.yang,
	wenzhuo.lu, mb, stephen, nicolas.chautru, bruce.richardson,
	konstantin.ananyev, cristian.dumitrescu, radu.nicolau,
	akhil.goyal, declan.doherty, skori, pbhagavatula, jerinj,
	kirankumark, david.hunt, anatoly.burakov, xiaoyun.li,
	jingjing.wu, john.mcnamara, jasvinder.singh, byron.marohn,
	yipeng1.wang

Add usage of rte_eth_link_strf function to example
applications

Signed-off-by: Ivan Dyukov <i.dyukov@samsung.com>
---
 doc/guides/sample_app_ug/link_status_intr.rst | 10 +++++-----
 1 file changed, 5 insertions(+), 5 deletions(-)

diff --git a/doc/guides/sample_app_ug/link_status_intr.rst b/doc/guides/sample_app_ug/link_status_intr.rst
index 04c40f285..596782b9d 100644
--- a/doc/guides/sample_app_ug/link_status_intr.rst
+++ b/doc/guides/sample_app_ug/link_status_intr.rst
@@ -158,6 +158,7 @@ An example callback function that has been written as indicated below.
     {
         struct rte_eth_link link;
         int ret;
+        char link_status[200];
 
         RTE_SET_USED(param);
 
@@ -169,11 +170,10 @@ An example callback function that has been written as indicated below.
         if (ret < 0) {
             printf("Failed to get port %d link status: %s\n\n",
                    port_id, rte_strerror(-ret));
-        } else if (link.link_status) {
-            printf("Port %d Link Up - speed %u Mbps - %s\n\n", port_id, (unsigned)link.link_speed,
-                  (link.link_duplex == ETH_LINK_FULL_DUPLEX) ? ("full-duplex") : ("half-duplex"));
-        } else
-            printf("Port %d Link Down\n\n", port_id);
+        } else {
+            rte_eth_link_strf(link_status, 200, NULL, &link);
+            printf("Port %d %s\n\n", port_id, link_status);
+        }
     }
 
 This function is called when a link status interrupt is present for the right port.
-- 
2.17.1


^ permalink raw reply	[flat|nested] 359+ messages in thread

* [dpdk-dev] [PATCH v5 05/25] net/ixgbe: return unknown speed in status
       [not found]                             ` <CGME20200706202653eucas1p2d1714d7aab0ca69d129654ea91a1dae3@eucas1p2.samsung.com>
@ 2020-07-06 20:25                               ` Ivan Dyukov
  0 siblings, 0 replies; 359+ messages in thread
From: Ivan Dyukov @ 2020-07-06 20:25 UTC (permalink / raw)
  To: dev, i.dyukov, v.kuramshin, thomas, david.marchand, ferruh.yigit,
	arybchenko, wei.zhao1, jia.guo, beilei.xing, qiming.yang,
	wenzhuo.lu, mb, stephen, nicolas.chautru, bruce.richardson,
	konstantin.ananyev, cristian.dumitrescu, radu.nicolau,
	akhil.goyal, declan.doherty, skori, pbhagavatula, jerinj,
	kirankumark, david.hunt, anatoly.burakov, xiaoyun.li,
	jingjing.wu, john.mcnamara, jasvinder.singh, byron.marohn,
	yipeng1.wang

rte_ethdev has declared new NUM_UNKNOWN speed which
could be used in case when no speed information is available

Signed-off-by: Ivan Dyukov <i.dyukov@samsung.com>
Reviewed-by: Wei Zhao <wei.zhao1@intel.com>
---
 drivers/net/ixgbe/ixgbe_ethdev.c | 6 +-----
 1 file changed, 1 insertion(+), 5 deletions(-)

diff --git a/drivers/net/ixgbe/ixgbe_ethdev.c b/drivers/net/ixgbe/ixgbe_ethdev.c
index 248f21d14..34a171116 100644
--- a/drivers/net/ixgbe/ixgbe_ethdev.c
+++ b/drivers/net/ixgbe/ixgbe_ethdev.c
@@ -4300,11 +4300,7 @@ ixgbe_dev_link_update_share(struct rte_eth_dev *dev,
 	switch (link_speed) {
 	default:
 	case IXGBE_LINK_SPEED_UNKNOWN:
-		if (hw->device_id == IXGBE_DEV_ID_X550EM_A_1G_T ||
-			hw->device_id == IXGBE_DEV_ID_X550EM_A_1G_T_L)
-			link.link_speed = ETH_SPEED_NUM_10M;
-		else
-			link.link_speed = ETH_SPEED_NUM_100M;
+		link.link_speed = ETH_SPEED_NUM_UNKNOWN;
 		break;
 
 	case IXGBE_LINK_SPEED_100_FULL:
-- 
2.17.1


^ permalink raw reply	[flat|nested] 359+ messages in thread

* [dpdk-dev] [PATCH v5 06/25] net/i40e: return unknown speed in status
       [not found]                             ` <CGME20200706202656eucas1p1acaa7bcd4a93fadfb28164e348986e7a@eucas1p1.samsung.com>
@ 2020-07-06 20:25                               ` " Ivan Dyukov
  0 siblings, 0 replies; 359+ messages in thread
From: Ivan Dyukov @ 2020-07-06 20:25 UTC (permalink / raw)
  To: dev, i.dyukov, v.kuramshin, thomas, david.marchand, ferruh.yigit,
	arybchenko, wei.zhao1, jia.guo, beilei.xing, qiming.yang,
	wenzhuo.lu, mb, stephen, nicolas.chautru, bruce.richardson,
	konstantin.ananyev, cristian.dumitrescu, radu.nicolau,
	akhil.goyal, declan.doherty, skori, pbhagavatula, jerinj,
	kirankumark, david.hunt, anatoly.burakov, xiaoyun.li,
	jingjing.wu, john.mcnamara, jasvinder.singh, byron.marohn,
	yipeng1.wang

rte_ethdev has declared new NUM_UNKNOWN speed which
could be used in case when no speed information is available and
link is up. NUM_NONE should be returned, if link is down.

Signed-off-by: Ivan Dyukov <i.dyukov@samsung.com>
Acked-by: Jeff Guo <jia.guo@intel.com>
---
 drivers/net/i40e/i40e_ethdev.c    |  5 ++++-
 drivers/net/i40e/i40e_ethdev_vf.c | 10 +++++-----
 2 files changed, 9 insertions(+), 6 deletions(-)

diff --git a/drivers/net/i40e/i40e_ethdev.c b/drivers/net/i40e/i40e_ethdev.c
index 472ce2a9e..f718356b5 100644
--- a/drivers/net/i40e/i40e_ethdev.c
+++ b/drivers/net/i40e/i40e_ethdev.c
@@ -2891,7 +2891,10 @@ update_link_aq(struct i40e_hw *hw, struct rte_eth_link *link,
 		link->link_speed = ETH_SPEED_NUM_40G;
 		break;
 	default:
-		link->link_speed = ETH_SPEED_NUM_NONE;
+		if (link->link_status)
+			link->link_speed = ETH_SPEED_NUM_UNKNOWN;
+		else
+			link->link_speed = ETH_SPEED_NUM_NONE;
 		break;
 	}
 }
diff --git a/drivers/net/i40e/i40e_ethdev_vf.c b/drivers/net/i40e/i40e_ethdev_vf.c
index eca716a6a..cf931bf9c 100644
--- a/drivers/net/i40e/i40e_ethdev_vf.c
+++ b/drivers/net/i40e/i40e_ethdev_vf.c
@@ -2163,15 +2163,15 @@ i40evf_dev_link_update(struct rte_eth_dev *dev,
 		new_link.link_speed = ETH_SPEED_NUM_40G;
 		break;
 	default:
-		new_link.link_speed = ETH_SPEED_NUM_NONE;
+		if (vf->link_up)
+			new_link.link_speed = ETH_SPEED_NUM_UNKNOWN;
+		else
+			new_link.link_speed = ETH_SPEED_NUM_NONE;
 		break;
 	}
 	/* full duplex only */
 	new_link.link_duplex = ETH_LINK_FULL_DUPLEX;
-	new_link.link_status = vf->link_up &&
-				new_link.link_speed != ETH_SPEED_NUM_NONE
-				? ETH_LINK_UP
-				: ETH_LINK_DOWN;
+	new_link.link_status = vf->link_up ? ETH_LINK_UP : ETH_LINK_DOWN;
 	new_link.link_autoneg =
 		!(dev->data->dev_conf.link_speeds & ETH_LINK_SPEED_FIXED);
 
-- 
2.17.1


^ permalink raw reply	[flat|nested] 359+ messages in thread

* [dpdk-dev] [PATCH v5 07/25] net/ice: return unknown speed in status
       [not found]                             ` <CGME20200706202658eucas1p16fb0b9d392a4c480915058a034bac1e7@eucas1p1.samsung.com>
@ 2020-07-06 20:25                               ` " Ivan Dyukov
  0 siblings, 0 replies; 359+ messages in thread
From: Ivan Dyukov @ 2020-07-06 20:25 UTC (permalink / raw)
  To: dev, i.dyukov, v.kuramshin, thomas, david.marchand, ferruh.yigit,
	arybchenko, wei.zhao1, jia.guo, beilei.xing, qiming.yang,
	wenzhuo.lu, mb, stephen, nicolas.chautru, bruce.richardson,
	konstantin.ananyev, cristian.dumitrescu, radu.nicolau,
	akhil.goyal, declan.doherty, skori, pbhagavatula, jerinj,
	kirankumark, david.hunt, anatoly.burakov, xiaoyun.li,
	jingjing.wu, john.mcnamara, jasvinder.singh, byron.marohn,
	yipeng1.wang

rte_ethdev has declared new NUM_UNKNOWN speed which
could be used in case when no speed information is available and
link is up. NUM_NONE should be returned, if link is down.

Signed-off-by: Ivan Dyukov <i.dyukov@samsung.com>
Reviewed-by: Ferruh Yigit <ferruh.yigit@intel.com>
---
 drivers/net/ice/ice_ethdev.c | 5 ++++-
 1 file changed, 4 insertions(+), 1 deletion(-)

diff --git a/drivers/net/ice/ice_ethdev.c b/drivers/net/ice/ice_ethdev.c
index b51fa2f17..76f797de0 100644
--- a/drivers/net/ice/ice_ethdev.c
+++ b/drivers/net/ice/ice_ethdev.c
@@ -3135,8 +3135,11 @@ ice_link_update(struct rte_eth_dev *dev, int wait_to_complete)
 		link.link_speed = ETH_SPEED_NUM_100G;
 		break;
 	case ICE_AQ_LINK_SPEED_UNKNOWN:
-	default:
 		PMD_DRV_LOG(ERR, "Unknown link speed");
+		link.link_speed = ETH_SPEED_NUM_UNKNOWN;
+		break;
+	default:
+		PMD_DRV_LOG(ERR, "None link speed");
 		link.link_speed = ETH_SPEED_NUM_NONE;
 		break;
 	}
-- 
2.17.1


^ permalink raw reply	[flat|nested] 359+ messages in thread

* [dpdk-dev] [PATCH v5 08/25] examples: new link status print format
       [not found]                             ` <CGME20200706202701eucas1p2e1edbd116f7bb5b3cf3d9a5432ad6ff9@eucas1p2.samsung.com>
@ 2020-07-06 20:25                               ` Ivan Dyukov
  0 siblings, 0 replies; 359+ messages in thread
From: Ivan Dyukov @ 2020-07-06 20:25 UTC (permalink / raw)
  To: dev, i.dyukov, v.kuramshin, thomas, david.marchand, ferruh.yigit,
	arybchenko, wei.zhao1, jia.guo, beilei.xing, qiming.yang,
	wenzhuo.lu, mb, stephen, nicolas.chautru, bruce.richardson,
	konstantin.ananyev, cristian.dumitrescu, radu.nicolau,
	akhil.goyal, declan.doherty, skori, pbhagavatula, jerinj,
	kirankumark, david.hunt, anatoly.burakov, xiaoyun.li,
	jingjing.wu, john.mcnamara, jasvinder.singh, byron.marohn,
	yipeng1.wang

Add usage of rte_eth_link_strf function to example
applications:
	* ipv4_multicast
	* l2fwd-jobstats
	* l2fwd-keepalive
	* l3fwd
	* link_status_interrupt

Signed-off-by: Ivan Dyukov <i.dyukov@samsung.com>
---
 examples/ipv4_multicast/main.c        | 12 ++++-------
 examples/l2fwd-jobstats/main.c        | 12 ++++-------
 examples/l2fwd-keepalive/main.c       | 12 ++++-------
 examples/l3fwd/main.c                 | 12 ++++-------
 examples/link_status_interrupt/main.c | 30 +++++++++++----------------
 5 files changed, 28 insertions(+), 50 deletions(-)

diff --git a/examples/ipv4_multicast/main.c b/examples/ipv4_multicast/main.c
index 7e255c35a..0d4957658 100644
--- a/examples/ipv4_multicast/main.c
+++ b/examples/ipv4_multicast/main.c
@@ -572,6 +572,7 @@ check_all_ports_link_status(uint32_t port_mask)
 	uint8_t count, all_ports_up, print_flag = 0;
 	struct rte_eth_link link;
 	int ret;
+	char link_status_text[60];
 
 	printf("\nChecking link status");
 	fflush(stdout);
@@ -591,14 +592,9 @@ check_all_ports_link_status(uint32_t port_mask)
 			}
 			/* print link status if flag set */
 			if (print_flag == 1) {
-				if (link.link_status)
-					printf(
-					"Port%d Link Up. Speed %u Mbps - %s\n",
-					portid, link.link_speed,
-				(link.link_duplex == ETH_LINK_FULL_DUPLEX) ?
-					("full-duplex") : ("half-duplex"));
-				else
-					printf("Port %d Link Down\n", portid);
+				rte_eth_link_strf(link_status_text, 60, NULL,
+						  &link);
+				printf("Port %d %s", portid, link_status_text);
 				continue;
 			}
 			/* clear all_ports_up flag if any link down */
diff --git a/examples/l2fwd-jobstats/main.c b/examples/l2fwd-jobstats/main.c
index 47a3b0976..740f1c80f 100644
--- a/examples/l2fwd-jobstats/main.c
+++ b/examples/l2fwd-jobstats/main.c
@@ -689,6 +689,7 @@ check_all_ports_link_status(uint32_t port_mask)
 	uint8_t count, all_ports_up, print_flag = 0;
 	struct rte_eth_link link;
 	int ret;
+	char link_status_text[60];
 
 	printf("\nChecking link status");
 	fflush(stdout);
@@ -708,14 +709,9 @@ check_all_ports_link_status(uint32_t port_mask)
 			}
 			/* print link status if flag set */
 			if (print_flag == 1) {
-				if (link.link_status)
-					printf(
-					"Port%d Link Up. Speed %u Mbps - %s\n",
-						portid, link.link_speed,
-				(link.link_duplex == ETH_LINK_FULL_DUPLEX) ?
-					("full-duplex") : ("half-duplex"));
-				else
-					printf("Port %d Link Down\n", portid);
+				rte_eth_link_strf(link_status_text, 60, NULL,
+						  &link);
+				printf("Port %d %s", portid, link_status_text);
 				continue;
 			}
 			/* clear all_ports_up flag if any link down */
diff --git a/examples/l2fwd-keepalive/main.c b/examples/l2fwd-keepalive/main.c
index b2742633b..d8be0a727 100644
--- a/examples/l2fwd-keepalive/main.c
+++ b/examples/l2fwd-keepalive/main.c
@@ -453,6 +453,7 @@ check_all_ports_link_status(uint32_t port_mask)
 	uint8_t count, all_ports_up, print_flag = 0;
 	struct rte_eth_link link;
 	int ret;
+	char link_status_text[60];
 
 	printf("\nChecking link status");
 	fflush(stdout);
@@ -472,14 +473,9 @@ check_all_ports_link_status(uint32_t port_mask)
 			}
 			/* print link status if flag set */
 			if (print_flag == 1) {
-				if (link.link_status)
-					printf(
-					"Port%d Link Up. Speed %u Mbps - %s\n",
-						portid, link.link_speed,
-				(link.link_duplex == ETH_LINK_FULL_DUPLEX) ?
-					("full-duplex") : ("half-duplex"));
-				else
-					printf("Port %d Link Down\n", portid);
+				rte_eth_link_strf(link_status_text, 60, NULL,
+						  &link);
+				printf("Port %d %s", portid, link_status_text);
 				continue;
 			}
 			/* clear all_ports_up flag if any link down */
diff --git a/examples/l3fwd/main.c b/examples/l3fwd/main.c
index 24ede4290..ef0f19a39 100644
--- a/examples/l3fwd/main.c
+++ b/examples/l3fwd/main.c
@@ -810,6 +810,7 @@ check_all_ports_link_status(uint32_t port_mask)
 	uint8_t count, all_ports_up, print_flag = 0;
 	struct rte_eth_link link;
 	int ret;
+	char link_status_text[60];
 
 	printf("\nChecking link status");
 	fflush(stdout);
@@ -833,14 +834,9 @@ check_all_ports_link_status(uint32_t port_mask)
 			}
 			/* print link status if flag set */
 			if (print_flag == 1) {
-				if (link.link_status)
-					printf(
-					"Port%d Link Up. Speed %u Mbps -%s\n",
-						portid, link.link_speed,
-				(link.link_duplex == ETH_LINK_FULL_DUPLEX) ?
-					("full-duplex") : ("half-duplex"));
-				else
-					printf("Port %d Link Down\n", portid);
+				rte_eth_link_strf(link_status_text, 60, NULL,
+						  &link);
+				printf("Port %d %s", portid, link_status_text);
 				continue;
 			}
 			/* clear all_ports_up flag if any link down */
diff --git a/examples/link_status_interrupt/main.c b/examples/link_status_interrupt/main.c
index 9bbcadfcf..5e286060d 100644
--- a/examples/link_status_interrupt/main.c
+++ b/examples/link_status_interrupt/main.c
@@ -118,6 +118,7 @@ print_stats(void)
 	const char clr[] = { 27, '[', '2', 'J', '\0' };
 	const char topLeft[] = { 27, '[', '1', ';', '1', 'H','\0' };
 	int link_get_err;
+	char link_speed_text[16];
 
 		/* Clear screen and move to top left */
 	printf("%s%s", clr, topLeft);
@@ -131,9 +132,10 @@ print_stats(void)
 
 		memset(&link, 0, sizeof(link));
 		link_get_err = rte_eth_link_get_nowait(portid, &link);
+		rte_eth_link_strf(link_speed_text, 16, "%M", &link);
 		printf("\nStatistics for port %u ------------------------------"
 			   "\nLink status: %25s"
-			   "\nLink speed: %26u"
+			   "\nLink speed: %26s"
 			   "\nLink duplex: %25s"
 			   "\nPackets sent: %24"PRIu64
 			   "\nPackets received: %20"PRIu64
@@ -141,8 +143,7 @@ print_stats(void)
 			   portid,
 			   link_get_err < 0 ? "Link get failed" :
 			   (link.link_status ? "Link up" : "Link down"),
-			   link_get_err < 0 ? 0 :
-					(unsigned int)link.link_speed,
+			   link_get_err < 0 ? "0" : link_speed_text,
 			   link_get_err < 0 ? "Link get failed" :
 			   (link.link_duplex == ETH_LINK_FULL_DUPLEX ? \
 					"full-duplex" : "half-duplex"),
@@ -445,6 +446,7 @@ lsi_event_callback(uint16_t port_id, enum rte_eth_event_type type, void *param,
 {
 	struct rte_eth_link link;
 	int ret;
+	char link_status_text[60];
 
 	RTE_SET_USED(param);
 	RTE_SET_USED(ret_param);
@@ -457,13 +459,8 @@ lsi_event_callback(uint16_t port_id, enum rte_eth_event_type type, void *param,
 		       port_id, rte_strerror(-ret));
 		return ret;
 	}
-	if (link.link_status) {
-		printf("Port %d Link Up - speed %u Mbps - %s\n\n",
-				port_id, (unsigned)link.link_speed,
-			(link.link_duplex == ETH_LINK_FULL_DUPLEX) ?
-				("full-duplex") : ("half-duplex"));
-	} else
-		printf("Port %d Link Down\n\n", port_id);
+	rte_eth_link_strf(link_status_text, 60, NULL, &link);
+	printf("Port %d %s\n", port_id, link_status_text);
 
 	return 0;
 }
@@ -478,6 +475,7 @@ check_all_ports_link_status(uint16_t port_num, uint32_t port_mask)
 	uint16_t portid;
 	struct rte_eth_link link;
 	int ret;
+	char link_status_text[60];
 
 	printf("\nChecking link status");
 	fflush(stdout);
@@ -497,14 +495,10 @@ check_all_ports_link_status(uint16_t port_num, uint32_t port_mask)
 			}
 			/* print link status if flag set */
 			if (print_flag == 1) {
-				if (link.link_status)
-					printf(
-					"Port%d Link Up. Speed %u Mbps - %s\n",
-						portid, link.link_speed,
-				(link.link_duplex == ETH_LINK_FULL_DUPLEX) ?
-					("full-duplex") : ("half-duplex"));
-				else
-					printf("Port %d Link Down\n", portid);
+				rte_eth_link_strf(link_status_text, 60, NULL,
+						    &link);
+				printf("Port %d %s", portid,
+				       link_status_text);
 				continue;
 			}
 			/* clear all_ports_up flag if any link down */
-- 
2.17.1


^ permalink raw reply	[flat|nested] 359+ messages in thread

* [dpdk-dev] [PATCH v5 09/25] examples/bbdev_app: new link status print format
       [not found]                             ` <CGME20200706202704eucas1p2489800126a0327fa6b1696fac1a05b3f@eucas1p2.samsung.com>
@ 2020-07-06 20:25                               ` " Ivan Dyukov
  0 siblings, 0 replies; 359+ messages in thread
From: Ivan Dyukov @ 2020-07-06 20:25 UTC (permalink / raw)
  To: dev, i.dyukov, v.kuramshin, thomas, david.marchand, ferruh.yigit,
	arybchenko, wei.zhao1, jia.guo, beilei.xing, qiming.yang,
	wenzhuo.lu, mb, stephen, nicolas.chautru, bruce.richardson,
	konstantin.ananyev, cristian.dumitrescu, radu.nicolau,
	akhil.goyal, declan.doherty, skori, pbhagavatula, jerinj,
	kirankumark, david.hunt, anatoly.burakov, xiaoyun.li,
	jingjing.wu, john.mcnamara, jasvinder.singh, byron.marohn,
	yipeng1.wang

Add usage of rte_eth_link_strf function to example
applications

Signed-off-by: Ivan Dyukov <i.dyukov@samsung.com>
---
 examples/bbdev_app/main.c | 8 +++-----
 1 file changed, 3 insertions(+), 5 deletions(-)

diff --git a/examples/bbdev_app/main.c b/examples/bbdev_app/main.c
index 68a46050c..44e6952e6 100644
--- a/examples/bbdev_app/main.c
+++ b/examples/bbdev_app/main.c
@@ -313,6 +313,7 @@ check_port_link_status(uint16_t port_id)
 	uint8_t count;
 	struct rte_eth_link link;
 	int link_get_err = -EINVAL;
+	char link_status_text[60];
 
 	printf("\nChecking link status.");
 	fflush(stdout);
@@ -323,11 +324,8 @@ check_port_link_status(uint16_t port_id)
 		link_get_err = rte_eth_link_get_nowait(port_id, &link);
 
 		if (link_get_err >= 0 && link.link_status) {
-			const char *dp = (link.link_duplex ==
-				ETH_LINK_FULL_DUPLEX) ?
-				"full-duplex" : "half-duplex";
-			printf("\nPort %u Link Up - speed %u Mbps - %s\n",
-				port_id, link.link_speed, dp);
+			rte_eth_link_strf(link_status_text, 60, NULL, &link);
+			printf("\nPort %u %s", port_id, link_status_text);
 			return 0;
 		}
 		printf(".");
-- 
2.17.1


^ permalink raw reply	[flat|nested] 359+ messages in thread

* [dpdk-dev] [PATCH v5 10/25] examples/ioat: new link status print format
       [not found]                             ` <CGME20200706202706eucas1p299579aa6492e84e34f0d3912032e51e0@eucas1p2.samsung.com>
@ 2020-07-06 20:26                               ` " Ivan Dyukov
  0 siblings, 0 replies; 359+ messages in thread
From: Ivan Dyukov @ 2020-07-06 20:26 UTC (permalink / raw)
  To: dev, i.dyukov, v.kuramshin, thomas, david.marchand, ferruh.yigit,
	arybchenko, wei.zhao1, jia.guo, beilei.xing, qiming.yang,
	wenzhuo.lu, mb, stephen, nicolas.chautru, bruce.richardson,
	konstantin.ananyev, cristian.dumitrescu, radu.nicolau,
	akhil.goyal, declan.doherty, skori, pbhagavatula, jerinj,
	kirankumark, david.hunt, anatoly.burakov, xiaoyun.li,
	jingjing.wu, john.mcnamara, jasvinder.singh, byron.marohn,
	yipeng1.wang

Add usage of rte_eth_link_strf function to example
applications

Signed-off-by: Ivan Dyukov <i.dyukov@samsung.com>
---
 examples/ioat/ioatfwd.c | 13 +++++--------
 1 file changed, 5 insertions(+), 8 deletions(-)

diff --git a/examples/ioat/ioatfwd.c b/examples/ioat/ioatfwd.c
index b66ee73bc..8bf80c262 100644
--- a/examples/ioat/ioatfwd.c
+++ b/examples/ioat/ioatfwd.c
@@ -700,6 +700,7 @@ check_link_status(uint32_t port_mask)
 	uint16_t portid;
 	struct rte_eth_link link;
 	int ret, link_status = 0;
+	char link_status_text[60];
 
 	printf("\nChecking link status\n");
 	RTE_ETH_FOREACH_DEV(portid) {
@@ -715,15 +716,11 @@ check_link_status(uint32_t port_mask)
 		}
 
 		/* Print link status */
-		if (link.link_status) {
-			printf(
-				"Port %d Link Up. Speed %u Mbps - %s\n",
-				portid, link.link_speed,
-				(link.link_duplex == ETH_LINK_FULL_DUPLEX) ?
-				("full-duplex") : ("half-duplex"));
+		rte_eth_link_strf(link_status_text, 60, NULL, &link);
+		printf("Port %d %s", portid, link_status_text);
+
+		if (link.link_status)
 			link_status = 1;
-		} else
-			printf("Port %d Link Down\n", portid);
 	}
 	return link_status;
 }
-- 
2.17.1


^ permalink raw reply	[flat|nested] 359+ messages in thread

* [dpdk-dev] [PATCH v5 11/25] examples/ip_*: new link status print format
       [not found]                             ` <CGME20200706202709eucas1p2cb2da3247bfdd0b25a3fdfd2fd7b2d99@eucas1p2.samsung.com>
@ 2020-07-06 20:26                               ` " Ivan Dyukov
  0 siblings, 0 replies; 359+ messages in thread
From: Ivan Dyukov @ 2020-07-06 20:26 UTC (permalink / raw)
  To: dev, i.dyukov, v.kuramshin, thomas, david.marchand, ferruh.yigit,
	arybchenko, wei.zhao1, jia.guo, beilei.xing, qiming.yang,
	wenzhuo.lu, mb, stephen, nicolas.chautru, bruce.richardson,
	konstantin.ananyev, cristian.dumitrescu, radu.nicolau,
	akhil.goyal, declan.doherty, skori, pbhagavatula, jerinj,
	kirankumark, david.hunt, anatoly.burakov, xiaoyun.li,
	jingjing.wu, john.mcnamara, jasvinder.singh, byron.marohn,
	yipeng1.wang

Add usage of rte_eth_link_strf function to example
applications:
	* ip_fragmentation
	* ip_reassembly
	* l3fwd-acl

Signed-off-by: Ivan Dyukov <i.dyukov@samsung.com>
---
 examples/ip_fragmentation/main.c | 13 +++++--------
 examples/ip_reassembly/main.c    | 12 ++++--------
 examples/l3fwd-acl/main.c        | 12 ++++--------
 3 files changed, 13 insertions(+), 24 deletions(-)

diff --git a/examples/ip_fragmentation/main.c b/examples/ip_fragmentation/main.c
index 4afb97109..18a6df77e 100644
--- a/examples/ip_fragmentation/main.c
+++ b/examples/ip_fragmentation/main.c
@@ -593,6 +593,7 @@ check_all_ports_link_status(uint32_t port_mask)
 	uint8_t count, all_ports_up, print_flag = 0;
 	struct rte_eth_link link;
 	int ret;
+	char link_status_text[60];
 
 	printf("\nChecking link status");
 	fflush(stdout);
@@ -612,14 +613,10 @@ check_all_ports_link_status(uint32_t port_mask)
 			}
 			/* print link status if flag set */
 			if (print_flag == 1) {
-				if (link.link_status)
-					printf(
-					"Port%d Link Up .Speed %u Mbps - %s\n",
-						portid, link.link_speed,
-				(link.link_duplex == ETH_LINK_FULL_DUPLEX) ?
-					("full-duplex") : ("half-duplex"));
-				else
-					printf("Port %d Link Down\n", portid);
+				rte_eth_link_strf(link_status_text, 60, NULL,
+						    &link);
+				printf("Port %d %s", portid,
+				       link_status_text);
 				continue;
 			}
 			/* clear all_ports_up flag if any link down */
diff --git a/examples/ip_reassembly/main.c b/examples/ip_reassembly/main.c
index 494d7ee77..910c89ae3 100644
--- a/examples/ip_reassembly/main.c
+++ b/examples/ip_reassembly/main.c
@@ -712,6 +712,7 @@ check_all_ports_link_status(uint32_t port_mask)
 	uint8_t count, all_ports_up, print_flag = 0;
 	struct rte_eth_link link;
 	int ret;
+	char link_status_text[60];
 
 	printf("\nChecking link status");
 	fflush(stdout);
@@ -731,14 +732,9 @@ check_all_ports_link_status(uint32_t port_mask)
 			}
 			/* print link status if flag set */
 			if (print_flag == 1) {
-				if (link.link_status)
-					printf(
-					"Port%d Link Up. Speed %u Mbps - %s\n",
-						portid, link.link_speed,
-				(link.link_duplex == ETH_LINK_FULL_DUPLEX) ?
-					("full-duplex") : ("half-duplex"));
-				else
-					printf("Port %d Link Down\n", portid);
+				rte_eth_link_strf(link_status_text, 60, NULL,
+						    &link);
+				printf("Port %d %s", portid, link_status_text);
 				continue;
 			}
 			/* clear all_ports_up flag if any link down */
diff --git a/examples/l3fwd-acl/main.c b/examples/l3fwd-acl/main.c
index f22fca732..ddfec9487 100644
--- a/examples/l3fwd-acl/main.c
+++ b/examples/l3fwd-acl/main.c
@@ -1815,6 +1815,7 @@ check_all_ports_link_status(uint32_t port_mask)
 	uint8_t count, all_ports_up, print_flag = 0;
 	struct rte_eth_link link;
 	int ret;
+	char link_status_text[60];
 
 	printf("\nChecking link status");
 	fflush(stdout);
@@ -1834,14 +1835,9 @@ check_all_ports_link_status(uint32_t port_mask)
 			}
 			/* print link status if flag set */
 			if (print_flag == 1) {
-				if (link.link_status)
-					printf(
-					"Port%d Link Up. Speed %u Mbps %s\n",
-						portid, link.link_speed,
-				(link.link_duplex == ETH_LINK_FULL_DUPLEX) ?
-					("full-duplex") : ("half-duplex"));
-				else
-					printf("Port %d Link Down\n", portid);
+				rte_eth_link_strf(link_status_text, 60, NULL,
+						    &link);
+				printf("Port %d %s", portid, link_status_text);
 				continue;
 			}
 			/* clear all_ports_up flag if any link down */
-- 
2.17.1


^ permalink raw reply	[flat|nested] 359+ messages in thread

* [dpdk-dev] [PATCH v5 12/25] examples/ip_pipeline: new link status print format
       [not found]                             ` <CGME20200706202711eucas1p12fc8d5efc4eb465d9b09c2e7d2d70ad7@eucas1p1.samsung.com>
@ 2020-07-06 20:26                               ` " Ivan Dyukov
  0 siblings, 0 replies; 359+ messages in thread
From: Ivan Dyukov @ 2020-07-06 20:26 UTC (permalink / raw)
  To: dev, i.dyukov, v.kuramshin, thomas, david.marchand, ferruh.yigit,
	arybchenko, wei.zhao1, jia.guo, beilei.xing, qiming.yang,
	wenzhuo.lu, mb, stephen, nicolas.chautru, bruce.richardson,
	konstantin.ananyev, cristian.dumitrescu, radu.nicolau,
	akhil.goyal, declan.doherty, skori, pbhagavatula, jerinj,
	kirankumark, david.hunt, anatoly.burakov, xiaoyun.li,
	jingjing.wu, john.mcnamara, jasvinder.singh, byron.marohn,
	yipeng1.wang

Add usage of rte_eth_link_strf function to example
applications

Signed-off-by: Ivan Dyukov <i.dyukov@samsung.com>
---
 examples/ip_pipeline/cli.c | 12 +++++++-----
 1 file changed, 7 insertions(+), 5 deletions(-)

diff --git a/examples/ip_pipeline/cli.c b/examples/ip_pipeline/cli.c
index d79699e2e..ca461ea0c 100644
--- a/examples/ip_pipeline/cli.c
+++ b/examples/ip_pipeline/cli.c
@@ -249,7 +249,8 @@ print_link_info(struct link *link, char *out, size_t out_size)
 	struct rte_eth_link eth_link;
 	uint16_t mtu;
 	int ret;
-
+	char link_speed_text[16];
+	char link_status_text[10];
 	memset(&stats, 0, sizeof(stats));
 	rte_eth_stats_get(link->port_id, &stats);
 
@@ -268,18 +269,19 @@ print_link_info(struct link *link, char *out, size_t out_size)
 	}
 
 	rte_eth_dev_get_mtu(link->port_id, &mtu);
-
+	rte_eth_link_strf(link_speed_text, 16, "%M", &eth_link);
+	rte_eth_link_strf(link_status_text, 10, "%S", &eth_link);
 	snprintf(out, out_size,
 		"\n"
 		"%s: flags=<%s> mtu %u\n"
 		"\tether %02X:%02X:%02X:%02X:%02X:%02X rxqueues %u txqueues %u\n"
-		"\tport# %u  speed %u Mbps\n"
+		"\tport# %u  speed %s Mbps\n"
 		"\tRX packets %" PRIu64"  bytes %" PRIu64"\n"
 		"\tRX errors %" PRIu64"  missed %" PRIu64"  no-mbuf %" PRIu64"\n"
 		"\tTX packets %" PRIu64"  bytes %" PRIu64"\n"
 		"\tTX errors %" PRIu64"\n",
 		link->name,
-		eth_link.link_status == 0 ? "DOWN" : "UP",
+		link_status_text,
 		mtu,
 		mac_addr.addr_bytes[0], mac_addr.addr_bytes[1],
 		mac_addr.addr_bytes[2], mac_addr.addr_bytes[3],
@@ -287,7 +289,7 @@ print_link_info(struct link *link, char *out, size_t out_size)
 		link->n_rxq,
 		link->n_txq,
 		link->port_id,
-		eth_link.link_speed,
+		link_speed_text,
 		stats.ipackets,
 		stats.ibytes,
 		stats.ierrors,
-- 
2.17.1


^ permalink raw reply	[flat|nested] 359+ messages in thread

* [dpdk-dev] [PATCH v5 13/25] examples/ipsec-secgw: new link status print format
       [not found]                             ` <CGME20200706202714eucas1p1b5817c2d30800b97f6c2acbe891f9aa4@eucas1p1.samsung.com>
@ 2020-07-06 20:26                               ` " Ivan Dyukov
  0 siblings, 0 replies; 359+ messages in thread
From: Ivan Dyukov @ 2020-07-06 20:26 UTC (permalink / raw)
  To: dev, i.dyukov, v.kuramshin, thomas, david.marchand, ferruh.yigit,
	arybchenko, wei.zhao1, jia.guo, beilei.xing, qiming.yang,
	wenzhuo.lu, mb, stephen, nicolas.chautru, bruce.richardson,
	konstantin.ananyev, cristian.dumitrescu, radu.nicolau,
	akhil.goyal, declan.doherty, skori, pbhagavatula, jerinj,
	kirankumark, david.hunt, anatoly.burakov, xiaoyun.li,
	jingjing.wu, john.mcnamara, jasvinder.singh, byron.marohn,
	yipeng1.wang

Add usage of rte_eth_link_strf function to example
applications

Signed-off-by: Ivan Dyukov <i.dyukov@samsung.com>
---
 examples/ipsec-secgw/ipsec-secgw.c | 12 ++++--------
 1 file changed, 4 insertions(+), 8 deletions(-)

diff --git a/examples/ipsec-secgw/ipsec-secgw.c b/examples/ipsec-secgw/ipsec-secgw.c
index f777ce2af..551838229 100644
--- a/examples/ipsec-secgw/ipsec-secgw.c
+++ b/examples/ipsec-secgw/ipsec-secgw.c
@@ -1775,6 +1775,7 @@ check_all_ports_link_status(uint32_t port_mask)
 	uint8_t count, all_ports_up, print_flag = 0;
 	struct rte_eth_link link;
 	int ret;
+	char link_status_text[60];
 
 	printf("\nChecking link status");
 	fflush(stdout);
@@ -1794,14 +1795,9 @@ check_all_ports_link_status(uint32_t port_mask)
 			}
 			/* print link status if flag set */
 			if (print_flag == 1) {
-				if (link.link_status)
-					printf(
-					"Port%d Link Up - speed %u Mbps -%s\n",
-						portid, link.link_speed,
-				(link.link_duplex == ETH_LINK_FULL_DUPLEX) ?
-					("full-duplex") : ("half-duplex"));
-				else
-					printf("Port %d Link Down\n", portid);
+				rte_eth_link_strf(link_status_text, 60, NULL,
+						    &link);
+				printf("Port %d %s", portid, link_status_text);
 				continue;
 			}
 			/* clear all_ports_up flag if any link down */
-- 
2.17.1


^ permalink raw reply	[flat|nested] 359+ messages in thread

* [dpdk-dev] [PATCH v5 14/25] examples/kni: new link status print format
       [not found]                             ` <CGME20200706202717eucas1p2d66b3ffebdd370ac1e2ecd9f398259d8@eucas1p2.samsung.com>
@ 2020-07-06 20:26                               ` " Ivan Dyukov
  0 siblings, 0 replies; 359+ messages in thread
From: Ivan Dyukov @ 2020-07-06 20:26 UTC (permalink / raw)
  To: dev, i.dyukov, v.kuramshin, thomas, david.marchand, ferruh.yigit,
	arybchenko, wei.zhao1, jia.guo, beilei.xing, qiming.yang,
	wenzhuo.lu, mb, stephen, nicolas.chautru, bruce.richardson,
	konstantin.ananyev, cristian.dumitrescu, radu.nicolau,
	akhil.goyal, declan.doherty, skori, pbhagavatula, jerinj,
	kirankumark, david.hunt, anatoly.burakov, xiaoyun.li,
	jingjing.wu, john.mcnamara, jasvinder.singh, byron.marohn,
	yipeng1.wang

Add usage of rte_eth_link_strf function to example
applications

Signed-off-by: Ivan Dyukov <i.dyukov@samsung.com>
---
 examples/kni/main.c | 26 +++++++++-----------------
 1 file changed, 9 insertions(+), 17 deletions(-)

diff --git a/examples/kni/main.c b/examples/kni/main.c
index f5d12a5b8..8ad7fb532 100644
--- a/examples/kni/main.c
+++ b/examples/kni/main.c
@@ -661,6 +661,7 @@ check_all_ports_link_status(uint32_t port_mask)
 	uint8_t count, all_ports_up, print_flag = 0;
 	struct rte_eth_link link;
 	int ret;
+	char link_status_text[60];
 
 	printf("\nChecking link status\n");
 	fflush(stdout);
@@ -680,14 +681,9 @@ check_all_ports_link_status(uint32_t port_mask)
 			}
 			/* print link status if flag set */
 			if (print_flag == 1) {
-				if (link.link_status)
-					printf(
-					"Port%d Link Up - speed %uMbps - %s\n",
-						portid, link.link_speed,
-				(link.link_duplex == ETH_LINK_FULL_DUPLEX) ?
-					("full-duplex") : ("half-duplex"));
-				else
-					printf("Port %d Link Down\n", portid);
+				rte_eth_link_strf(link_status_text, 60, NULL,
+						    &link);
+				printf("Port %d %s", portid, link_status_text);
 				continue;
 			}
 			/* clear all_ports_up flag if any link down */
@@ -717,19 +713,15 @@ check_all_ports_link_status(uint32_t port_mask)
 static void
 log_link_state(struct rte_kni *kni, int prev, struct rte_eth_link *link)
 {
+	char link_status_text[60];
 	if (kni == NULL || link == NULL)
 		return;
 
-	if (prev == ETH_LINK_DOWN && link->link_status == ETH_LINK_UP) {
-		RTE_LOG(INFO, APP, "%s NIC Link is Up %d Mbps %s %s.\n",
+	rte_eth_link_strf(link_status_text, 60, NULL, link);
+	if (prev != link->link_status)
+		RTE_LOG(INFO, APP, "%s NIC %s",
 			rte_kni_get_name(kni),
-			link->link_speed,
-			link->link_autoneg ?  "(AutoNeg)" : "(Fixed)",
-			link->link_duplex ?  "Full Duplex" : "Half Duplex");
-	} else if (prev == ETH_LINK_UP && link->link_status == ETH_LINK_DOWN) {
-		RTE_LOG(INFO, APP, "%s NIC Link is Down.\n",
-			rte_kni_get_name(kni));
-	}
+			link_status_text);
 }
 
 /*
-- 
2.17.1


^ permalink raw reply	[flat|nested] 359+ messages in thread

* [dpdk-dev] [PATCH v5 15/25] examples/l2fwd-crypt: new link status print format
       [not found]                             ` <CGME20200706202719eucas1p1b61bd1297794e070c607c4eb916c7017@eucas1p1.samsung.com>
@ 2020-07-06 20:26                               ` " Ivan Dyukov
  0 siblings, 0 replies; 359+ messages in thread
From: Ivan Dyukov @ 2020-07-06 20:26 UTC (permalink / raw)
  To: dev, i.dyukov, v.kuramshin, thomas, david.marchand, ferruh.yigit,
	arybchenko, wei.zhao1, jia.guo, beilei.xing, qiming.yang,
	wenzhuo.lu, mb, stephen, nicolas.chautru, bruce.richardson,
	konstantin.ananyev, cristian.dumitrescu, radu.nicolau,
	akhil.goyal, declan.doherty, skori, pbhagavatula, jerinj,
	kirankumark, david.hunt, anatoly.burakov, xiaoyun.li,
	jingjing.wu, john.mcnamara, jasvinder.singh, byron.marohn,
	yipeng1.wang

Add usage of rte_eth_link_strf function to example
applications

Signed-off-by: Ivan Dyukov <i.dyukov@samsung.com>
---
 examples/l2fwd-crypto/main.c | 12 ++++--------
 1 file changed, 4 insertions(+), 8 deletions(-)

diff --git a/examples/l2fwd-crypto/main.c b/examples/l2fwd-crypto/main.c
index 827da9b3e..7648ea027 100644
--- a/examples/l2fwd-crypto/main.c
+++ b/examples/l2fwd-crypto/main.c
@@ -1734,6 +1734,7 @@ check_all_ports_link_status(uint32_t port_mask)
 	uint8_t count, all_ports_up, print_flag = 0;
 	struct rte_eth_link link;
 	int ret;
+	char link_status_text[60];
 
 	printf("\nChecking link status");
 	fflush(stdout);
@@ -1753,14 +1754,9 @@ check_all_ports_link_status(uint32_t port_mask)
 			}
 			/* print link status if flag set */
 			if (print_flag == 1) {
-				if (link.link_status)
-					printf(
-					"Port%d Link Up. Speed %u Mbps - %s\n",
-						portid, link.link_speed,
-				(link.link_duplex == ETH_LINK_FULL_DUPLEX) ?
-					("full-duplex") : ("half-duplex"));
-				else
-					printf("Port %d Link Down\n", portid);
+				rte_eth_link_strf(link_status_text, 60, NULL,
+						    &link);
+				printf("Port %d %s", portid, link_status_text);
 				continue;
 			}
 			/* clear all_ports_up flag if any link down */
-- 
2.17.1


^ permalink raw reply	[flat|nested] 359+ messages in thread

* [dpdk-dev] [PATCH v5 16/25] examples/l2fwd-event: new link status print format
       [not found]                             ` <CGME20200706202722eucas1p1a631c58e9805c00286a2a4b469aeb124@eucas1p1.samsung.com>
@ 2020-07-06 20:26                               ` " Ivan Dyukov
  0 siblings, 0 replies; 359+ messages in thread
From: Ivan Dyukov @ 2020-07-06 20:26 UTC (permalink / raw)
  To: dev, i.dyukov, v.kuramshin, thomas, david.marchand, ferruh.yigit,
	arybchenko, wei.zhao1, jia.guo, beilei.xing, qiming.yang,
	wenzhuo.lu, mb, stephen, nicolas.chautru, bruce.richardson,
	konstantin.ananyev, cristian.dumitrescu, radu.nicolau,
	akhil.goyal, declan.doherty, skori, pbhagavatula, jerinj,
	kirankumark, david.hunt, anatoly.burakov, xiaoyun.li,
	jingjing.wu, john.mcnamara, jasvinder.singh, byron.marohn,
	yipeng1.wang

Add usage of rte_eth_link_strf function to example
applications

Signed-off-by: Ivan Dyukov <i.dyukov@samsung.com>
---
 examples/l2fwd-event/main.c | 12 ++++--------
 1 file changed, 4 insertions(+), 8 deletions(-)

diff --git a/examples/l2fwd-event/main.c b/examples/l2fwd-event/main.c
index 4fe500333..3e6d1c311 100644
--- a/examples/l2fwd-event/main.c
+++ b/examples/l2fwd-event/main.c
@@ -366,6 +366,7 @@ check_all_ports_link_status(struct l2fwd_resources *rsrc,
 	uint8_t count, all_ports_up, print_flag = 0;
 	struct rte_eth_link link;
 	int ret;
+	char link_status_text[60];
 
 	printf("\nChecking link status...");
 	fflush(stdout);
@@ -389,14 +390,9 @@ check_all_ports_link_status(struct l2fwd_resources *rsrc,
 			}
 			/* print link status if flag set */
 			if (print_flag == 1) {
-				if (link.link_status)
-					printf(
-					"Port%d Link Up. Speed %u Mbps - %s\n",
-						port_id, link.link_speed,
-				(link.link_duplex == ETH_LINK_FULL_DUPLEX) ?
-					("full-duplex") : ("half-duplex"));
-				else
-					printf("Port %d Link Down\n", port_id);
+				rte_eth_link_strf(link_status_text, 60, NULL,
+						    &link);
+				printf("Port %d %s", port_id, link_status_text);
 				continue;
 			}
 			/* clear all_ports_up flag if any link down */
-- 
2.17.1


^ permalink raw reply	[flat|nested] 359+ messages in thread

* [dpdk-dev] [PATCH v5 17/25] examples/l2fwd: new link status print format
       [not found]                             ` <CGME20200706202724eucas1p196ad6a9590f4b488e13b265fee3b854a@eucas1p1.samsung.com>
@ 2020-07-06 20:26                               ` " Ivan Dyukov
  0 siblings, 0 replies; 359+ messages in thread
From: Ivan Dyukov @ 2020-07-06 20:26 UTC (permalink / raw)
  To: dev, i.dyukov, v.kuramshin, thomas, david.marchand, ferruh.yigit,
	arybchenko, wei.zhao1, jia.guo, beilei.xing, qiming.yang,
	wenzhuo.lu, mb, stephen, nicolas.chautru, bruce.richardson,
	konstantin.ananyev, cristian.dumitrescu, radu.nicolau,
	akhil.goyal, declan.doherty, skori, pbhagavatula, jerinj,
	kirankumark, david.hunt, anatoly.burakov, xiaoyun.li,
	jingjing.wu, john.mcnamara, jasvinder.singh, byron.marohn,
	yipeng1.wang

Add usage of rte_eth_link_strf function to example
applications

Signed-off-by: Ivan Dyukov <i.dyukov@samsung.com>
---
 examples/l2fwd/main.c | 12 ++++--------
 1 file changed, 4 insertions(+), 8 deletions(-)

diff --git a/examples/l2fwd/main.c b/examples/l2fwd/main.c
index e04c601b5..9d5f7307e 100644
--- a/examples/l2fwd/main.c
+++ b/examples/l2fwd/main.c
@@ -571,6 +571,7 @@ check_all_ports_link_status(uint32_t port_mask)
 	uint8_t count, all_ports_up, print_flag = 0;
 	struct rte_eth_link link;
 	int ret;
+	char link_status_text[60];
 
 	printf("\nChecking link status");
 	fflush(stdout);
@@ -594,14 +595,9 @@ check_all_ports_link_status(uint32_t port_mask)
 			}
 			/* print link status if flag set */
 			if (print_flag == 1) {
-				if (link.link_status)
-					printf(
-					"Port%d Link Up. Speed %u Mbps - %s\n",
-						portid, link.link_speed,
-				(link.link_duplex == ETH_LINK_FULL_DUPLEX) ?
-					("full-duplex") : ("half-duplex"));
-				else
-					printf("Port %d Link Down\n", portid);
+				rte_eth_link_strf(link_status_text, 60, NULL,
+						    &link);
+				printf("Port %d %s", portid, link_status_text);
 				continue;
 			}
 			/* clear all_ports_up flag if any link down */
-- 
2.17.1


^ permalink raw reply	[flat|nested] 359+ messages in thread

* [dpdk-dev] [PATCH v5 18/25] examples/l3fwd-graph: new link status print format
       [not found]                             ` <CGME20200706202727eucas1p2b575e02cd42371084aaf970887fad4da@eucas1p2.samsung.com>
@ 2020-07-06 20:26                               ` " Ivan Dyukov
  0 siblings, 0 replies; 359+ messages in thread
From: Ivan Dyukov @ 2020-07-06 20:26 UTC (permalink / raw)
  To: dev, i.dyukov, v.kuramshin, thomas, david.marchand, ferruh.yigit,
	arybchenko, wei.zhao1, jia.guo, beilei.xing, qiming.yang,
	wenzhuo.lu, mb, stephen, nicolas.chautru, bruce.richardson,
	konstantin.ananyev, cristian.dumitrescu, radu.nicolau,
	akhil.goyal, declan.doherty, skori, pbhagavatula, jerinj,
	kirankumark, david.hunt, anatoly.burakov, xiaoyun.li,
	jingjing.wu, john.mcnamara, jasvinder.singh, byron.marohn,
	yipeng1.wang

Add usage of rte_eth_link_strf function to example
applications

Signed-off-by: Ivan Dyukov <i.dyukov@samsung.com>
---
 examples/l3fwd-graph/main.c | 14 ++++----------
 1 file changed, 4 insertions(+), 10 deletions(-)

diff --git a/examples/l3fwd-graph/main.c b/examples/l3fwd-graph/main.c
index c70270c4d..cd8e3aad1 100644
--- a/examples/l3fwd-graph/main.c
+++ b/examples/l3fwd-graph/main.c
@@ -599,6 +599,7 @@ check_all_ports_link_status(uint32_t port_mask)
 	struct rte_eth_link link;
 	uint16_t portid;
 	int ret;
+	char link_status_text[60];
 
 	printf("\nChecking link status");
 	fflush(stdout);
@@ -623,16 +624,9 @@ check_all_ports_link_status(uint32_t port_mask)
 			}
 			/* Print link status if flag set */
 			if (print_flag == 1) {
-				if (link.link_status)
-					printf("Port%d Link Up. Speed %u Mbps "
-					       "-%s\n",
-					       portid, link.link_speed,
-					       (link.link_duplex ==
-						ETH_LINK_FULL_DUPLEX)
-						       ? ("full-duplex")
-						       : ("half-duplex\n"));
-				else
-					printf("Port %d Link Down\n", portid);
+				rte_eth_link_strf(link_status_text, 60, NULL,
+						    &link);
+				printf("Port %d %s", portid, link_status_text);
 				continue;
 			}
 			/* Clear all_ports_up flag if any link down */
-- 
2.17.1


^ permalink raw reply	[flat|nested] 359+ messages in thread

* [dpdk-dev] [PATCH v5 19/25] examples/l3fwd-power: new link status print format
       [not found]                             ` <CGME20200706202730eucas1p1112175f892b58de011b4002fd66b0d36@eucas1p1.samsung.com>
@ 2020-07-06 20:26                               ` " Ivan Dyukov
  0 siblings, 0 replies; 359+ messages in thread
From: Ivan Dyukov @ 2020-07-06 20:26 UTC (permalink / raw)
  To: dev, i.dyukov, v.kuramshin, thomas, david.marchand, ferruh.yigit,
	arybchenko, wei.zhao1, jia.guo, beilei.xing, qiming.yang,
	wenzhuo.lu, mb, stephen, nicolas.chautru, bruce.richardson,
	konstantin.ananyev, cristian.dumitrescu, radu.nicolau,
	akhil.goyal, declan.doherty, skori, pbhagavatula, jerinj,
	kirankumark, david.hunt, anatoly.burakov, xiaoyun.li,
	jingjing.wu, john.mcnamara, jasvinder.singh, byron.marohn,
	yipeng1.wang

Add usage of rte_eth_link_strf function to example
applications

Signed-off-by: Ivan Dyukov <i.dyukov@samsung.com>
---
 examples/l3fwd-power/main.c | 13 ++++---------
 1 file changed, 4 insertions(+), 9 deletions(-)

diff --git a/examples/l3fwd-power/main.c b/examples/l3fwd-power/main.c
index 9db94ce04..ba6bab4a5 100644
--- a/examples/l3fwd-power/main.c
+++ b/examples/l3fwd-power/main.c
@@ -1945,6 +1945,7 @@ check_all_ports_link_status(uint32_t port_mask)
 	uint16_t portid;
 	struct rte_eth_link link;
 	int ret;
+	char link_status_text[60];
 
 	printf("\nChecking link status");
 	fflush(stdout);
@@ -1964,15 +1965,9 @@ check_all_ports_link_status(uint32_t port_mask)
 			}
 			/* print link status if flag set */
 			if (print_flag == 1) {
-				if (link.link_status)
-					printf("Port %d Link Up - speed %u "
-						"Mbps - %s\n", (uint8_t)portid,
-						(unsigned)link.link_speed,
-				(link.link_duplex == ETH_LINK_FULL_DUPLEX) ?
-					("full-duplex") : ("half-duplex"));
-				else
-					printf("Port %d Link Down\n",
-						(uint8_t)portid);
+				rte_eth_link_strf(link_status_text, 60, NULL,
+						    &link);
+				printf("Port %d %s", portid, link_status_text);
 				continue;
 			}
 			/* clear all_ports_up flag if any link down */
-- 
2.17.1


^ permalink raw reply	[flat|nested] 359+ messages in thread

* [dpdk-dev] [PATCH v5 20/25] examples/multi_proc*: new link status print format
       [not found]                             ` <CGME20200706202732eucas1p1f8fd4a2c9fc271e08f8b416dd0af0712@eucas1p1.samsung.com>
@ 2020-07-06 20:26                               ` " Ivan Dyukov
  0 siblings, 0 replies; 359+ messages in thread
From: Ivan Dyukov @ 2020-07-06 20:26 UTC (permalink / raw)
  To: dev, i.dyukov, v.kuramshin, thomas, david.marchand, ferruh.yigit,
	arybchenko, wei.zhao1, jia.guo, beilei.xing, qiming.yang,
	wenzhuo.lu, mb, stephen, nicolas.chautru, bruce.richardson,
	konstantin.ananyev, cristian.dumitrescu, radu.nicolau,
	akhil.goyal, declan.doherty, skori, pbhagavatula, jerinj,
	kirankumark, david.hunt, anatoly.burakov, xiaoyun.li,
	jingjing.wu, john.mcnamara, jasvinder.singh, byron.marohn,
	yipeng1.wang

Add usage of rte_eth_link_strf function to example
applications

Signed-off-by: Ivan Dyukov <i.dyukov@samsung.com>
---
 .../client_server_mp/mp_server/init.c              | 14 +++++---------
 examples/multi_process/symmetric_mp/main.c         | 12 ++++--------
 2 files changed, 9 insertions(+), 17 deletions(-)

diff --git a/examples/multi_process/client_server_mp/mp_server/init.c b/examples/multi_process/client_server_mp/mp_server/init.c
index c2ec07ac6..3ca9bcae3 100644
--- a/examples/multi_process/client_server_mp/mp_server/init.c
+++ b/examples/multi_process/client_server_mp/mp_server/init.c
@@ -185,6 +185,7 @@ check_all_ports_link_status(uint16_t port_num, uint32_t port_mask)
 	uint8_t count, all_ports_up, print_flag = 0;
 	struct rte_eth_link link;
 	int ret;
+	char link_status_text[60];
 
 	printf("\nChecking link status");
 	fflush(stdout);
@@ -204,15 +205,10 @@ check_all_ports_link_status(uint16_t port_num, uint32_t port_mask)
 			}
 			/* print link status if flag set */
 			if (print_flag == 1) {
-				if (link.link_status)
-					printf("Port %d Link Up - speed %u "
-						"Mbps - %s\n", ports->id[portid],
-						(unsigned)link.link_speed,
-				(link.link_duplex == ETH_LINK_FULL_DUPLEX) ?
-					("full-duplex") : ("half-duplex"));
-				else
-					printf("Port %d Link Down\n",
-						(uint8_t)ports->id[portid]);
+				rte_eth_link_strf(link_status_text, 60, NULL,
+						    &link);
+				printf("Port %d %s", (uint8_t)ports->id[portid],
+				       link_status_text);
 				continue;
 			}
 			/* clear all_ports_up flag if any link down */
diff --git a/examples/multi_process/symmetric_mp/main.c b/examples/multi_process/symmetric_mp/main.c
index 9a16e198c..0480874f8 100644
--- a/examples/multi_process/symmetric_mp/main.c
+++ b/examples/multi_process/symmetric_mp/main.c
@@ -365,6 +365,7 @@ check_all_ports_link_status(uint16_t port_num, uint32_t port_mask)
 	uint8_t count, all_ports_up, print_flag = 0;
 	struct rte_eth_link link;
 	int ret;
+	char link_status_text[60];
 
 	printf("\nChecking link status");
 	fflush(stdout);
@@ -384,14 +385,9 @@ check_all_ports_link_status(uint16_t port_num, uint32_t port_mask)
 			}
 			/* print link status if flag set */
 			if (print_flag == 1) {
-				if (link.link_status)
-					printf(
-					"Port%d Link Up. Speed %u Mbps - %s\n",
-						portid, link.link_speed,
-				(link.link_duplex == ETH_LINK_FULL_DUPLEX) ?
-					("full-duplex") : ("half-duplex"));
-				else
-					printf("Port %d Link Down\n", portid);
+				rte_eth_link_strf(link_status_text, 60, NULL,
+						    &link);
+				printf("Port %d %s", portid, link_status_text);
 				continue;
 			}
 			/* clear all_ports_up flag if any link down */
-- 
2.17.1


^ permalink raw reply	[flat|nested] 359+ messages in thread

* [dpdk-dev] [PATCH v5 21/25] examples/ntb: new link status print format
       [not found]                             ` <CGME20200706202735eucas1p29df73c3a0bf8a49a7969e4f18b05348e@eucas1p2.samsung.com>
@ 2020-07-06 20:26                               ` " Ivan Dyukov
  0 siblings, 0 replies; 359+ messages in thread
From: Ivan Dyukov @ 2020-07-06 20:26 UTC (permalink / raw)
  To: dev, i.dyukov, v.kuramshin, thomas, david.marchand, ferruh.yigit,
	arybchenko, wei.zhao1, jia.guo, beilei.xing, qiming.yang,
	wenzhuo.lu, mb, stephen, nicolas.chautru, bruce.richardson,
	konstantin.ananyev, cristian.dumitrescu, radu.nicolau,
	akhil.goyal, declan.doherty, skori, pbhagavatula, jerinj,
	kirankumark, david.hunt, anatoly.burakov, xiaoyun.li,
	jingjing.wu, john.mcnamara, jasvinder.singh, byron.marohn,
	yipeng1.wang

Add usage of rte_eth_link_strf function to example
applications

Signed-off-by: Ivan Dyukov <i.dyukov@samsung.com>
---
 examples/ntb/ntb_fwd.c | 10 +++++-----
 1 file changed, 5 insertions(+), 5 deletions(-)

diff --git a/examples/ntb/ntb_fwd.c b/examples/ntb/ntb_fwd.c
index eba8ebf9f..84fe374c4 100644
--- a/examples/ntb/ntb_fwd.c
+++ b/examples/ntb/ntb_fwd.c
@@ -729,6 +729,7 @@ start_pkt_fwd(void)
 	struct rte_eth_link eth_link;
 	uint32_t lcore_id;
 	int ret, i;
+	char link_status_text[60];
 
 	ret = ntb_fwd_config_setup();
 	if (ret < 0) {
@@ -747,11 +748,10 @@ start_pkt_fwd(void)
 				return;
 			}
 			if (eth_link.link_status) {
-				printf("Eth%u Link Up. Speed %u Mbps - %s\n",
-					eth_port_id, eth_link.link_speed,
-					(eth_link.link_duplex ==
-					 ETH_LINK_FULL_DUPLEX) ?
-					("full-duplex") : ("half-duplex"));
+				rte_eth_link_strf(link_status_text, 60, NULL,
+						    &link);
+				printf("Eth%u %s", eth_port_id,
+				       link_status_text);
 				break;
 			}
 		}
-- 
2.17.1


^ permalink raw reply	[flat|nested] 359+ messages in thread

* [dpdk-dev] [PATCH v5 22/25] example/performance*: new link status print format
       [not found]                             ` <CGME20200706202737eucas1p1314f8a06a538a2181093471bc09ac79d@eucas1p1.samsung.com>
@ 2020-07-06 20:26                               ` " Ivan Dyukov
  0 siblings, 0 replies; 359+ messages in thread
From: Ivan Dyukov @ 2020-07-06 20:26 UTC (permalink / raw)
  To: dev, i.dyukov, v.kuramshin, thomas, david.marchand, ferruh.yigit,
	arybchenko, wei.zhao1, jia.guo, beilei.xing, qiming.yang,
	wenzhuo.lu, mb, stephen, nicolas.chautru, bruce.richardson,
	konstantin.ananyev, cristian.dumitrescu, radu.nicolau,
	akhil.goyal, declan.doherty, skori, pbhagavatula, jerinj,
	kirankumark, david.hunt, anatoly.burakov, xiaoyun.li,
	jingjing.wu, john.mcnamara, jasvinder.singh, byron.marohn,
	yipeng1.wang

Add usage of rte_eth_link_strf function to example
applications

Signed-off-by: Ivan Dyukov <i.dyukov@samsung.com>
---
 examples/performance-thread/l3fwd-thread/main.c | 12 ++++--------
 1 file changed, 4 insertions(+), 8 deletions(-)

diff --git a/examples/performance-thread/l3fwd-thread/main.c b/examples/performance-thread/l3fwd-thread/main.c
index 84c1d7b3a..bd10014a0 100644
--- a/examples/performance-thread/l3fwd-thread/main.c
+++ b/examples/performance-thread/l3fwd-thread/main.c
@@ -3433,6 +3433,7 @@ check_all_ports_link_status(uint32_t port_mask)
 	uint8_t count, all_ports_up, print_flag = 0;
 	struct rte_eth_link link;
 	int ret;
+	char link_status_text[60];
 
 	printf("\nChecking link status");
 	fflush(stdout);
@@ -3452,14 +3453,9 @@ check_all_ports_link_status(uint32_t port_mask)
 			}
 			/* print link status if flag set */
 			if (print_flag == 1) {
-				if (link.link_status)
-					printf(
-					"Port%d Link Up. Speed %u Mbps - %s\n",
-						portid, link.link_speed,
-				(link.link_duplex == ETH_LINK_FULL_DUPLEX) ?
-					("full-duplex") : ("half-duplex"));
-				else
-					printf("Port %d Link Down\n", portid);
+				rte_eth_link_strf(link_status_text, 60, NULL,
+						    &link);
+				printf("Port %d %s", portid, link_status_text);
 				continue;
 			}
 			/* clear all_ports_up flag if any link down */
-- 
2.17.1


^ permalink raw reply	[flat|nested] 359+ messages in thread

* [dpdk-dev] [PATCH v5 23/25] examples/qos_sched: new link status print format
       [not found]                             ` <CGME20200706202741eucas1p2fef03b23c36afc9c8b67b02cf28692a9@eucas1p2.samsung.com>
@ 2020-07-06 20:26                               ` " Ivan Dyukov
  0 siblings, 0 replies; 359+ messages in thread
From: Ivan Dyukov @ 2020-07-06 20:26 UTC (permalink / raw)
  To: dev, i.dyukov, v.kuramshin, thomas, david.marchand, ferruh.yigit,
	arybchenko, wei.zhao1, jia.guo, beilei.xing, qiming.yang,
	wenzhuo.lu, mb, stephen, nicolas.chautru, bruce.richardson,
	konstantin.ananyev, cristian.dumitrescu, radu.nicolau,
	akhil.goyal, declan.doherty, skori, pbhagavatula, jerinj,
	kirankumark, david.hunt, anatoly.burakov, xiaoyun.li,
	jingjing.wu, john.mcnamara, jasvinder.singh, byron.marohn,
	yipeng1.wang

Add usage of rte_eth_link_strf function to example
applications

Signed-off-by: Ivan Dyukov <i.dyukov@samsung.com>
---
 examples/qos_sched/init.c | 10 ++--------
 1 file changed, 2 insertions(+), 8 deletions(-)

diff --git a/examples/qos_sched/init.c b/examples/qos_sched/init.c
index 9626c15b8..4bb975fc9 100644
--- a/examples/qos_sched/init.c
+++ b/examples/qos_sched/init.c
@@ -160,14 +160,8 @@ app_init_port(uint16_t portid, struct rte_mempool *mp)
 			 "rte_eth_link_get: err=%d, port=%u: %s\n",
 			 ret, portid, rte_strerror(-ret));
 
-	if (link.link_status) {
-		printf(" Link Up - speed %u Mbps - %s\n",
-			(uint32_t) link.link_speed,
-			(link.link_duplex == ETH_LINK_FULL_DUPLEX) ?
-			("full-duplex") : ("half-duplex"));
-	} else {
-		printf(" Link Down\n");
-	}
+	rte_eth_link_printf(NULL, &link);
+
 	ret = rte_eth_promiscuous_enable(portid);
 	if (ret != 0)
 		rte_exit(EXIT_FAILURE,
-- 
2.17.1


^ permalink raw reply	[flat|nested] 359+ messages in thread

* [dpdk-dev] [PATCH v5 24/25] examples/server_nod*: new link status print format
       [not found]                             ` <CGME20200706202743eucas1p2a3fdb7441c2c5fc4cbd7c3275376874c@eucas1p2.samsung.com>
@ 2020-07-06 20:26                               ` " Ivan Dyukov
  0 siblings, 0 replies; 359+ messages in thread
From: Ivan Dyukov @ 2020-07-06 20:26 UTC (permalink / raw)
  To: dev, i.dyukov, v.kuramshin, thomas, david.marchand, ferruh.yigit,
	arybchenko, wei.zhao1, jia.guo, beilei.xing, qiming.yang,
	wenzhuo.lu, mb, stephen, nicolas.chautru, bruce.richardson,
	konstantin.ananyev, cristian.dumitrescu, radu.nicolau,
	akhil.goyal, declan.doherty, skori, pbhagavatula, jerinj,
	kirankumark, david.hunt, anatoly.burakov, xiaoyun.li,
	jingjing.wu, john.mcnamara, jasvinder.singh, byron.marohn,
	yipeng1.wang

Add usage of rte_eth_link_strf function to example
applications

Signed-off-by: Ivan Dyukov <i.dyukov@samsung.com>
---
 examples/server_node_efd/server/init.c | 15 +++++----------
 1 file changed, 5 insertions(+), 10 deletions(-)

diff --git a/examples/server_node_efd/server/init.c b/examples/server_node_efd/server/init.c
index 378a74fa5..00224850e 100644
--- a/examples/server_node_efd/server/init.c
+++ b/examples/server_node_efd/server/init.c
@@ -247,6 +247,7 @@ check_all_ports_link_status(uint16_t port_num, uint32_t port_mask)
 	uint16_t portid;
 	struct rte_eth_link link;
 	int ret;
+	char link_status_text[60];
 
 	printf("\nChecking link status");
 	fflush(stdout);
@@ -266,16 +267,10 @@ check_all_ports_link_status(uint16_t port_num, uint32_t port_mask)
 			}
 			/* print link status if flag set */
 			if (print_flag == 1) {
-				if (link.link_status)
-					printf(
-					"Port%d Link Up. Speed %u Mbps - %s\n",
-						info->id[portid],
-						link.link_speed,
-				(link.link_duplex == ETH_LINK_FULL_DUPLEX) ?
-					("full-duplex") : ("half-duplex"));
-				else
-					printf("Port %d Link Down\n",
-						info->id[portid]);
+				rte_eth_link_strf(link_status_text, 60, NULL,
+						    &link);
+				printf("Port %d %s", info->id[portid],
+				       link_status_text);
 				continue;
 			}
 			/* clear all_ports_up flag if any link down */
-- 
2.17.1


^ permalink raw reply	[flat|nested] 359+ messages in thread

* [dpdk-dev] [PATCH v5 25/25] examples/vm_power_*: new link status print format
       [not found]                             ` <CGME20200706202747eucas1p241ac7df0719d3c05dbc5ba55450a1a7b@eucas1p2.samsung.com>
@ 2020-07-06 20:26                               ` " Ivan Dyukov
  0 siblings, 0 replies; 359+ messages in thread
From: Ivan Dyukov @ 2020-07-06 20:26 UTC (permalink / raw)
  To: dev, i.dyukov, v.kuramshin, thomas, david.marchand, ferruh.yigit,
	arybchenko, wei.zhao1, jia.guo, beilei.xing, qiming.yang,
	wenzhuo.lu, mb, stephen, nicolas.chautru, bruce.richardson,
	konstantin.ananyev, cristian.dumitrescu, radu.nicolau,
	akhil.goyal, declan.doherty, skori, pbhagavatula, jerinj,
	kirankumark, david.hunt, anatoly.burakov, xiaoyun.li,
	jingjing.wu, john.mcnamara, jasvinder.singh, byron.marohn,
	yipeng1.wang

Add usage of rte_eth_link_strf function to example
applications

Signed-off-by: Ivan Dyukov <i.dyukov@samsung.com>
---
 examples/vm_power_manager/main.c | 14 +++++---------
 1 file changed, 5 insertions(+), 9 deletions(-)

diff --git a/examples/vm_power_manager/main.c b/examples/vm_power_manager/main.c
index 273bfec29..05aec1aad 100644
--- a/examples/vm_power_manager/main.c
+++ b/examples/vm_power_manager/main.c
@@ -244,6 +244,7 @@ check_all_ports_link_status(uint32_t port_mask)
 	uint16_t portid, count, all_ports_up, print_flag = 0;
 	struct rte_eth_link link;
 	int ret;
+	char link_status_text[60];
 
 	printf("\nChecking link status");
 	fflush(stdout);
@@ -267,15 +268,10 @@ check_all_ports_link_status(uint32_t port_mask)
 			}
 			/* print link status if flag set */
 			if (print_flag == 1) {
-				if (link.link_status)
-					printf("Port %d Link Up - speed %u "
-						"Mbps - %s\n", (uint16_t)portid,
-						(unsigned int)link.link_speed,
-				(link.link_duplex == ETH_LINK_FULL_DUPLEX) ?
-					("full-duplex") : ("half-duplex"));
-				else
-					printf("Port %d Link Down\n",
-						(uint16_t)portid);
+				rte_eth_link_strf(link_status_text, 60, NULL,
+						    &link);
+				printf("Port %d %s", portid,
+				       link_status_text);
 				continue;
 			}
 		       /* clear all_ports_up flag if any link down */
-- 
2.17.1


^ permalink raw reply	[flat|nested] 359+ messages in thread

* [dpdk-dev] [PATCH v6 0/25] ethdev: allow unknown link speed
       [not found]                         ` <CGME20200706203750eucas1p1e35c97b252eb46ba4eb95d79a2fa97b4@eucas1p1.samsung.com>
@ 2020-07-06 20:37                           ` Ivan Dyukov
       [not found]                             ` <CGME20200706203754eucas1p2d933772e36fe6ae9d4ad29d6d1684294@eucas1p2.samsung.com>
                                               ` (24 more replies)
  0 siblings, 25 replies; 359+ messages in thread
From: Ivan Dyukov @ 2020-07-06 20:37 UTC (permalink / raw)
  To: dev, i.dyukov, v.kuramshin, thomas, david.marchand, ferruh.yigit,
	arybchenko, wei.zhao1, jia.guo, beilei.xing, qiming.yang,
	wenzhuo.lu, mb, stephen, nicolas.chautru, bruce.richardson,
	konstantin.ananyev, cristian.dumitrescu, radu.nicolau,
	akhil.goyal, declan.doherty, skori, pbhagavatula, jerinj,
	kirankumark, david.hunt, anatoly.burakov, xiaoyun.li,
	jingjing.wu, john.mcnamara, jasvinder.singh, byron.marohn,
	yipeng1.wang

MAINTAINERS                                              |   1 +
 app/proc-info/main.c                                     |   9 ++----
 app/test-pipeline/init.c                                 |  11 ++++---
 app/test-pmd/config.c                                    |  20 ++++++++-----
 app/test-pmd/testpmd.c                                   |   9 +-----
 app/test/Makefile                                        |   3 ++
 app/test/meson.build                                     |   2 ++
 app/test/test_ethdev_link.c                              | 278 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 app/test/test_pmd_perf.c                                 |  17 +++++------
 doc/guides/sample_app_ug/link_status_intr.rst            |  10 +++----
 drivers/net/i40e/i40e_ethdev.c                           |   5 +++-
 drivers/net/i40e/i40e_ethdev_vf.c                        |  10 +++----
 drivers/net/ice/ice_ethdev.c                             |   5 +++-
 drivers/net/ixgbe/ixgbe_ethdev.c                         |   6 +---
 examples/bbdev_app/main.c                                |   8 ++---
 examples/ioat/ioatfwd.c                                  |  13 ++++----
 examples/ip_fragmentation/main.c                         |  13 ++++----
 examples/ip_pipeline/cli.c                               |  12 ++++----
 examples/ip_reassembly/main.c                            |  12 +++-----
 examples/ipsec-secgw/ipsec-secgw.c                       |  12 +++-----
 examples/ipv4_multicast/main.c                           |  12 +++-----
 examples/kni/main.c                                      |  26 ++++++----------
 examples/l2fwd-crypto/main.c                             |  12 +++-----
 examples/l2fwd-event/main.c                              |  12 +++-----
 examples/l2fwd-jobstats/main.c                           |  12 +++-----
 examples/l2fwd-keepalive/main.c                          |  12 +++-----
 examples/l2fwd/main.c                                    |  12 +++-----
 examples/l3fwd-acl/main.c                                |  12 +++-----
 examples/l3fwd-graph/main.c                              |  14 +++------
 examples/l3fwd-power/main.c                              |  13 +++-----
 examples/l3fwd/main.c                                    |  12 +++-----
 examples/link_status_interrupt/main.c                    |  30 ++++++++-----------
 examples/multi_process/client_server_mp/mp_server/init.c |  14 ++++-----
 examples/multi_process/symmetric_mp/main.c               |  12 +++-----
 examples/ntb/ntb_fwd.c                                   |  10 +++----
 examples/performance-thread/l3fwd-thread/main.c          |  12 +++-----
 examples/qos_sched/init.c                                |  10 ++-----
 examples/server_node_efd/server/init.c                   |  15 ++++------
 examples/vm_power_manager/main.c                         |  14 ++++-----
 lib/librte_ethdev/rte_ethdev.c                           | 169 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 lib/librte_ethdev/rte_ethdev.h                           |  74 +++++++++++++++++++++++++++++++++++++++-------
 lib/librte_ethdev/rte_ethdev_version.map                 |   4 +++
 42 files changed, 687 insertions(+), 282 deletions(-)

v6 changes:
* fix spelling in comments according to checkpatch warning

v5 changes:
* rename rte_eth_link_format to rte_eth_link_strf
* add '\n' to default strings
* update remaining examples. patch with subj 'examples: new link status print format' contains examples which have no maintainers.
TBD:
update remaining nic drivers with 'unknown' speed.  It should be provided in separate patchset.

v4 changes:
* refactor rte_eth_link_format using strlcat func instead of snprintf
* added new checks to unit tests
* few minor fixes according review comments
TBD:
update examples in 'example' folder with new status printing mechanism
update remaining nic drivers with 'unknown' speed

v3 changes:
* remove rte_eth_link_prepare_text function
* add rte_eth_link_format and rte_eth_link_printf functions
* added unit tests for rte_eth_link_format function
TBD:
update examples in 'example' folder with new status printing mechanism
update remaining nic drivers with 'unknown' speed

v2 changes:
* add function which format link status to textual representation
* update drivers for Intel nics with 'unknown' speed
TBD:
update examples in 'example' folder with new status printing mechanism
update remaining nic drivers with 'unknown' speed

v1 changes:
This is initial patchset which introduces UNKNOWN speed to dpdk
applications. Also it contains changes related to printf formating.
Patchset contains changes for app/ and doc/ folders.
examples/ folder will be provided later.


^ permalink raw reply	[flat|nested] 359+ messages in thread

* [dpdk-dev] [PATCH v6 01/25] ethdev: allow unknown link speed
       [not found]                             ` <CGME20200706203754eucas1p2d933772e36fe6ae9d4ad29d6d1684294@eucas1p2.samsung.com>
@ 2020-07-06 20:37                               ` " Ivan Dyukov
  0 siblings, 0 replies; 359+ messages in thread
From: Ivan Dyukov @ 2020-07-06 20:37 UTC (permalink / raw)
  To: dev, i.dyukov, v.kuramshin, thomas, david.marchand, ferruh.yigit,
	arybchenko, wei.zhao1, jia.guo, beilei.xing, qiming.yang,
	wenzhuo.lu, mb, stephen, nicolas.chautru, bruce.richardson,
	konstantin.ananyev, cristian.dumitrescu, radu.nicolau,
	akhil.goyal, declan.doherty, skori, pbhagavatula, jerinj,
	kirankumark, david.hunt, anatoly.burakov, xiaoyun.li,
	jingjing.wu, john.mcnamara, jasvinder.singh, byron.marohn,
	yipeng1.wang

From: Thomas Monjalon <thomas@monjalon.net>

When querying the link information, the link status is
a mandatory major information.
Other boolean values are supposed to be accurate:
	- duplex mode (half/full)
	- negotiation (auto/fixed)

This API update is making explicit that the link speed information
is optional.
The value ETH_SPEED_NUM_NONE (0) was already part of the API.
The value ETH_SPEED_NUM_UNKNOWN (infinite) is added to cover
two different cases:
	- speed is not known by the driver
	- device is virtual

Suggested-by: Morten Brørup <mb@smartsharesystems.com>
Suggested-by: Benoit Ganne <bganne@cisco.com>
Signed-off-by: Thomas Monjalon <thomas@monjalon.net>
Reviewed-by: Ferruh Yigit <ferruh.yigit@intel.com>
---
 lib/librte_ethdev/rte_ethdev.h | 20 ++++++++++----------
 1 file changed, 10 insertions(+), 10 deletions(-)

diff --git a/lib/librte_ethdev/rte_ethdev.h b/lib/librte_ethdev/rte_ethdev.h
index a49242bcd..2090af501 100644
--- a/lib/librte_ethdev/rte_ethdev.h
+++ b/lib/librte_ethdev/rte_ethdev.h
@@ -303,6 +303,7 @@ struct rte_eth_stats {
 #define ETH_SPEED_NUM_56G      56000 /**<  56 Gbps */
 #define ETH_SPEED_NUM_100G    100000 /**< 100 Gbps */
 #define ETH_SPEED_NUM_200G    200000 /**< 200 Gbps */
+#define ETH_SPEED_NUM_UNKNOWN UINT32_MAX /**< Unknown */
 
 /**
  * A structure used to retrieve link-level information of an Ethernet port.
@@ -2262,15 +2263,16 @@ int rte_eth_allmulticast_disable(uint16_t port_id);
 int rte_eth_allmulticast_get(uint16_t port_id);
 
 /**
- * Retrieve the status (ON/OFF), the speed (in Mbps) and the mode (HALF-DUPLEX
- * or FULL-DUPLEX) of the physical link of an Ethernet device. It might need
- * to wait up to 9 seconds in it.
+ * Retrieve the link status (up/down), the duplex mode (half/full),
+ * the negotiation (auto/fixed), and if available, the speed (Mbps).
+ *
+ * It might need to wait up to 9 seconds.
+ * @see rte_eth_link_get_nowait.
  *
  * @param port_id
  *   The port identifier of the Ethernet device.
  * @param link
- *   A pointer to an *rte_eth_link* structure to be filled with
- *   the status, the speed and the mode of the Ethernet device link.
+ *   Link information written back.
  * @return
  *   - (0) if successful.
  *   - (-ENOTSUP) if the function is not supported in PMD driver.
@@ -2279,15 +2281,13 @@ int rte_eth_allmulticast_get(uint16_t port_id);
 int rte_eth_link_get(uint16_t port_id, struct rte_eth_link *link);
 
 /**
- * Retrieve the status (ON/OFF), the speed (in Mbps) and the mode (HALF-DUPLEX
- * or FULL-DUPLEX) of the physical link of an Ethernet device. It is a no-wait
- * version of rte_eth_link_get().
+ * Retrieve the link status (up/down), the duplex mode (half/full),
+ * the negotiation (auto/fixed), and if available, the speed (Mbps).
  *
  * @param port_id
  *   The port identifier of the Ethernet device.
  * @param link
- *   A pointer to an *rte_eth_link* structure to be filled with
- *   the status, the speed and the mode of the Ethernet device link.
+ *   Link information written back.
  * @return
  *   - (0) if successful.
  *   - (-ENOTSUP) if the function is not supported in PMD driver.
-- 
2.17.1


^ permalink raw reply	[flat|nested] 359+ messages in thread

* [dpdk-dev] [PATCH v6 02/25] ethdev: add a link status text representation
       [not found]                             ` <CGME20200706203757eucas1p2f59654f60db48ec7164aad3d29ad6dff@eucas1p2.samsung.com>
@ 2020-07-06 20:37                               ` Ivan Dyukov
  2020-07-06 21:24                                 ` Stephen Hemminger
  2020-07-06 21:30                                 ` Stephen Hemminger
  0 siblings, 2 replies; 359+ messages in thread
From: Ivan Dyukov @ 2020-07-06 20:37 UTC (permalink / raw)
  To: dev, i.dyukov, v.kuramshin, thomas, david.marchand, ferruh.yigit,
	arybchenko, wei.zhao1, jia.guo, beilei.xing, qiming.yang,
	wenzhuo.lu, mb, stephen, nicolas.chautru, bruce.richardson,
	konstantin.ananyev, cristian.dumitrescu, radu.nicolau,
	akhil.goyal, declan.doherty, skori, pbhagavatula, jerinj,
	kirankumark, david.hunt, anatoly.burakov, xiaoyun.li,
	jingjing.wu, john.mcnamara, jasvinder.singh, byron.marohn,
	yipeng1.wang

This commit add function which treat link status structure
and format it to text representation.

Signed-off-by: Ivan Dyukov <i.dyukov@samsung.com>
---
 MAINTAINERS                              |   1 +
 app/test/Makefile                        |   3 +
 app/test/meson.build                     |   2 +
 app/test/test_ethdev_link.c              | 278 +++++++++++++++++++++++
 lib/librte_ethdev/rte_ethdev.c           | 169 ++++++++++++++
 lib/librte_ethdev/rte_ethdev.h           |  54 +++++
 lib/librte_ethdev/rte_ethdev_version.map |   4 +
 7 files changed, 511 insertions(+)
 create mode 100644 app/test/test_ethdev_link.c

diff --git a/MAINTAINERS b/MAINTAINERS
index 5e706cd7e..f4fb31ea2 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -393,6 +393,7 @@ T: git://dpdk.org/next/dpdk-next-net
 F: lib/librte_ethdev/
 F: devtools/test-null.sh
 F: doc/guides/prog_guide/switch_representation.rst
+F: app/test/test_ethdev*
 
 Flow API
 M: Ori Kam <orika@mellanox.com>
diff --git a/app/test/Makefile b/app/test/Makefile
index e5440774b..9f43b8c3c 100644
--- a/app/test/Makefile
+++ b/app/test/Makefile
@@ -251,6 +251,9 @@ SRCS-$(CONFIG_RTE_LIBRTE_SECURITY) += test_security.c
 
 SRCS-$(CONFIG_RTE_LIBRTE_IPSEC) += test_ipsec.c test_ipsec_perf.c
 SRCS-$(CONFIG_RTE_LIBRTE_IPSEC) += test_ipsec_sad.c
+
+SRCS-$(CONFIG_RTE_LIBRTE_ETHER) += test_ethdev_link.c
+
 ifeq ($(CONFIG_RTE_LIBRTE_IPSEC),y)
 LDLIBS += -lrte_ipsec
 endif
diff --git a/app/test/meson.build b/app/test/meson.build
index 56591db4e..6df31a4dc 100644
--- a/app/test/meson.build
+++ b/app/test/meson.build
@@ -39,6 +39,7 @@ test_sources = files('commands.c',
 	'test_efd.c',
 	'test_efd_perf.c',
 	'test_errno.c',
+	'test_ethdev_link.c',
 	'test_event_crypto_adapter.c',
 	'test_event_eth_rx_adapter.c',
 	'test_event_ring.c',
@@ -199,6 +200,7 @@ fast_tests = [
         ['eal_flags_misc_autotest', false],
         ['eal_fs_autotest', true],
         ['errno_autotest', true],
+        ['ethdev_link_status' true],
         ['event_ring_autotest', true],
         ['fib_autotest', true],
         ['fib6_autotest', true],
diff --git a/app/test/test_ethdev_link.c b/app/test/test_ethdev_link.c
new file mode 100644
index 000000000..6709323ef
--- /dev/null
+++ b/app/test/test_ethdev_link.c
@@ -0,0 +1,278 @@
+/* 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[128];
+	ret = rte_eth_link_strf(text, 128, NULL, &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 Gbit/s FDX Autoneg\n",
+		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_strf(text, 128, NULL, &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 Mbit/s HDX Fixed\n",
+		text, strlen(text), "Invalid default link status "
+		"string with HDX");
+
+	link_status.link_speed = ETH_SPEED_NUM_UNKNOWN,
+	ret = rte_eth_link_strf(text, 128, NULL, &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 speed HDX Fixed\n",
+		text, strlen(text), "Invalid default link status "
+		"string with HDX");
+	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[128];
+	ret = rte_eth_link_strf(text, 128, NULL, &link_status);
+	RTE_TEST_ASSERT(ret > 0, "Failed to format default string\n");
+	TEST_ASSERT_BUFFERS_ARE_EQUAL("Link down\n",
+		text, strlen(text), "Invalid default link status string");
+
+	return TEST_SUCCESS;
+}
+
+static int32_t
+test_link_status_string_overflow(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[128];
+	int i = 0;
+	for (i = 0; i < 128; i++)
+		text[i] = 'Y';
+	text[127] = '\0';
+
+	ret = rte_eth_link_strf(NULL, 2, "status %S, %G Gbits/s",
+		&link_status);
+	RTE_TEST_ASSERT(ret < 0, "Format string should fail, but it's ok\n");
+
+	ret = rte_eth_link_strf(text, 2, "status %S, %G Gbits/s",
+		&link_status);
+	RTE_TEST_ASSERT(ret < 0, "Format string should fail, but it's ok\n");
+	RTE_TEST_ASSERT(text[2] == 'Y', "String1 overflow\n");
+
+	ret = rte_eth_link_strf(text, 8, NULL,
+		&link_status);
+	RTE_TEST_ASSERT(ret < 0, "Default format string should fail,"
+			" but it's ok\n");
+	RTE_TEST_ASSERT(text[8] == 'Y', "String1 overflow\n");
+
+	ret = rte_eth_link_strf(text, 10, NULL,
+		&link_status);
+	RTE_TEST_ASSERT(ret < 0, "Default format string should fail,"
+			" but it's ok\n");
+	RTE_TEST_ASSERT(text[10] == 'Y', "String1 overflow\n");
+
+	text[1] = 'Y';
+	ret = rte_eth_link_strf(text, 1, "%S",
+		&link_status);
+	RTE_TEST_ASSERT(ret < 0, "Status string should fail, but it's ok\n");
+	RTE_TEST_ASSERT(text[1] == 'Y', "String1 overflow\n");
+
+	return TEST_SUCCESS;
+}
+
+static int32_t
+test_link_status_format(void)
+{
+	int ret = 0;
+	struct rte_eth_link link_status = {
+		.link_speed = ETH_SPEED_NUM_40G,
+		.link_status = ETH_LINK_UP,
+		.link_autoneg = ETH_LINK_AUTONEG,
+		.link_duplex = ETH_LINK_FULL_DUPLEX
+	};
+	char text[128];
+	int i = 0;
+	for (i = 0; i < 128; i++)
+		text[i] = 'Y';
+	text[127] = '\0';
+	printf("status format #1: %s\n", text);
+	ret = rte_eth_link_strf(text, 128, "status = %S, duplex = %D\n",
+		&link_status);
+	printf("status format #2: %s\n", text);
+	RTE_TEST_ASSERT(ret > 0, "Failed to format string\n");
+	TEST_ASSERT_BUFFERS_ARE_EQUAL("status = Up, duplex = FDX\n",
+		text, strlen(text), "Invalid status string1.");
+
+	ret = rte_eth_link_strf(text, 128, "%A", &link_status);
+	printf("status format #3: %s\n", text);
+	RTE_TEST_ASSERT(ret > 0, "Failed to format string\n");
+	TEST_ASSERT_BUFFERS_ARE_EQUAL("Autoneg",
+		text, strlen(text), "Invalid status string2.");
+
+	ret = rte_eth_link_strf(text, 128,
+		"%G",
+		&link_status);
+	printf("status format #4: %s\n", text);
+	RTE_TEST_ASSERT(ret > 0, "Failed to format string\n");
+	TEST_ASSERT_BUFFERS_ARE_EQUAL("40.0",
+		text, strlen(text), "Invalid status string3.");
+
+	ret = rte_eth_link_strf(text, 128,
+		"%M",
+		&link_status);
+	printf("status format #5: %s\n", text);
+	RTE_TEST_ASSERT(ret > 0, "Failed to format string\n");
+	TEST_ASSERT_BUFFERS_ARE_EQUAL("40000",
+		text, strlen(text), "Invalid status string4.");
+	return TEST_SUCCESS;
+}
+
+static int32_t
+test_link_status_return_value(void)
+{
+	int ret = 0;
+	struct rte_eth_link link_status = {
+		.link_speed = ETH_SPEED_NUM_40G,
+		.link_status = ETH_LINK_UP,
+		.link_autoneg = ETH_LINK_AUTONEG,
+		.link_duplex = ETH_LINK_FULL_DUPLEX
+	};
+	char text[128];
+	int i = 0;
+	for (i = 0; i < 128; i++)
+		text[i] = 'Y';
+	text[127] = '\0';
+	ret = rte_eth_link_strf(text, 128, "status = %S, ",
+		&link_status);
+	printf("return value #1:ret=%u, text=%s\n", ret, text);
+	ret += rte_eth_link_strf(text + ret, 128 - ret,
+		"%A",
+		&link_status);
+	printf("return value #2:ret=%u, text=%s\n", ret, text);
+	ret += rte_eth_link_strf(text + ret, 128 - ret,
+		", duplex = %D\n",
+		&link_status);
+	printf("return value #3:ret=%u, text=%s\n", ret, text);
+	ret += rte_eth_link_strf(text + ret, 128 - ret,
+		"%M Mbits/s\n",
+		&link_status);
+	printf("return value #4:ret=%u, text=%s\n", ret, text);
+	RTE_TEST_ASSERT(ret > 0, "Failed to format string\n");
+	TEST_ASSERT_BUFFERS_ARE_EQUAL("status = Up, Autoneg, duplex = FDX\n"
+		"40000 Mbits/s\n",
+		text, strlen(text), "Invalid status string");
+
+	return TEST_SUCCESS;
+}
+
+static int32_t
+test_link_status_invalid_fmt(void)
+{
+	int ret = 0;
+	struct rte_eth_link link_status = {
+		.link_speed = ETH_SPEED_NUM_40G,
+		.link_status = ETH_LINK_UP,
+		.link_autoneg = ETH_LINK_AUTONEG,
+		.link_duplex = ETH_LINK_FULL_DUPLEX
+	};
+	char text[128];
+	ret = rte_eth_link_strf(text, 128, "status = %",
+		&link_status);
+	RTE_TEST_ASSERT(ret < 0, "Status string1 should fail, but it's ok\n");
+	ret = rte_eth_link_strf(text, 128,
+		", duplex = %d\n",
+		&link_status);
+	RTE_TEST_ASSERT(ret < 0, "Status string2 should fail, but it's ok\n");
+	ret = rte_eth_link_strf(text, 128,
+		"% Mbits/s\n",
+		&link_status);
+	RTE_TEST_ASSERT(ret < 0, "Status string3 should fail, but it's ok\n");
+
+	return TEST_SUCCESS;
+}
+
+static int32_t
+test_link_status_format_edges(void)
+{
+	int ret = 0;
+	struct rte_eth_link link_status = {
+		.link_speed = ETH_SPEED_NUM_UNKNOWN,
+		.link_status = ETH_LINK_DOWN,
+		.link_autoneg = ETH_LINK_AUTONEG,
+		.link_duplex = ETH_LINK_HALF_DUPLEX
+	};
+	char text[128];
+	ret = rte_eth_link_strf(text, 4, "%S", &link_status);
+	printf("format edges #1: %s\n", text);
+	RTE_TEST_ASSERT(ret < 0, "It should fail. No space for "
+				 "zero terminator\n");
+	ret = rte_eth_link_strf(text, 6, "123%D", &link_status);
+	printf("format edges #2: %s\n", text);
+	RTE_TEST_ASSERT(ret < 0, "It should fail. No space for "
+				 "zero terminator\n");
+	ret = rte_eth_link_strf(text, 7, "%A", &link_status);
+	printf("format edges #3: %s\n", text);
+	RTE_TEST_ASSERT(ret < 0, "It should fail. No space for "
+				 "zero terminator\n");
+	ret = rte_eth_link_strf(text, 8, "%A", &link_status);
+	printf("format edges #4: %s\n", text);
+	RTE_TEST_ASSERT(ret > 0, "It should ok, but it fails\n");
+	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_status_string_overflow),
+		TEST_CASE(test_link_status_format),
+		TEST_CASE(test_link_status_format_edges),
+		TEST_CASE(test_link_status_invalid_fmt),
+		TEST_CASE(test_link_status_return_value),
+		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);
diff --git a/lib/librte_ethdev/rte_ethdev.c b/lib/librte_ethdev/rte_ethdev.c
index d06b7f9b1..2234af175 100644
--- a/lib/librte_ethdev/rte_ethdev.c
+++ b/lib/librte_ethdev/rte_ethdev.c
@@ -2383,6 +2383,175 @@ rte_eth_link_get_nowait(uint16_t port_id, struct rte_eth_link *eth_link)
 	return 0;
 }
 
+static int
+rte_eth_link_strf_parser(char *str, size_t len, const char *const fmt,
+			   struct rte_eth_link *link)
+{
+	size_t offset = 0;
+	const char *fmt_cur = fmt;
+	char *str_cur = str;
+	double gbits = (double)link->link_speed / 1000.;
+	static const char AUTONEG_STR[]       = "Autoneg";
+	static const char FIXED_STR[]         = "Fixed";
+	static const char FDX_STR[]           = "FDX";
+	static const char HDX_STR[]           = "HDX";
+	static const char UNKNOWN_STR[]       = "Unknown";
+	static const char UP_STR[]            = "Up";
+	static const char DOWN_STR[]          = "Down";
+
+	char gbits_str[20];
+	char mbits_str[20];
+	/* preformat complex formatting to easily concatinate it further */
+	snprintf(mbits_str, 20, "%u", link->link_speed);
+	snprintf(gbits_str, 20, "%.1f", gbits);
+	/* init str before formatting */
+	str[0] = 0;
+	while (*fmt_cur) {
+		/* check str bounds */
+		if (offset > (len - 1)) {
+			str[len - 1] = '\0';
+			return -1;
+		}
+		if (*fmt_cur == '%') {
+			/* set null terminator to current position,
+			 * it's required for strlcat
+			 */
+			*str_cur = '\0';
+			switch (*++fmt_cur) {
+			/* Speed in Mbits/s */
+			case 'M':
+				if (link->link_speed ==
+				    ETH_SPEED_NUM_UNKNOWN)
+					offset = strlcat(str, UNKNOWN_STR,
+							 len);
+				else
+					offset = strlcat(str, mbits_str, len);
+				break;
+			/* Speed in Gbits/s */
+			case 'G':
+				if (link->link_speed ==
+				    ETH_SPEED_NUM_UNKNOWN)
+					offset = strlcat(str, UNKNOWN_STR,
+							 len);
+				else
+					offset = strlcat(str, gbits_str, len);
+				break;
+			/* Link status */
+			case 'S':
+				offset = strlcat(str, link->link_status ?
+					UP_STR : DOWN_STR, len);
+				break;
+			/* Link autoneg */
+			case 'A':
+				offset = strlcat(str, link->link_autoneg ?
+					AUTONEG_STR : FIXED_STR, len);
+				break;
+			/* Link duplex */
+			case 'D':
+				offset = strlcat(str, link->link_duplex ?
+					FDX_STR : HDX_STR, len);
+				break;
+			/* Error cases */
+			default:
+				return -1;
+
+			}
+			if (offset > (len - 1))
+				return -1;
+
+			str_cur = str + offset;
+		} else {
+			*str_cur++ = *fmt_cur;
+			offset++;
+		}
+		fmt_cur++;
+	}
+	*str_cur = '\0';
+	return offset;
+}
+
+int
+rte_eth_link_printf(const char *const fmt,
+		    struct rte_eth_link *link)
+{
+	char text[200];
+	int ret;
+	ret = rte_eth_link_strf(text, 200, fmt, link);
+	if (ret > 0)
+		printf("%s", text);
+	return ret;
+}
+
+int
+rte_eth_link_strf(char *str, size_t len, const char *const fmt,
+		    struct rte_eth_link *link)
+{
+	size_t offset = 0;
+	double gbits = (double)link->link_speed / 1000.;
+	char gbits_str[20];
+	char mbits_str[20];
+	/* TBD: make it international? */
+	static const char LINK_DOWN_STR[]     = "Link down\n";
+	static const char LINK_UP_STR[]       = "Link up at ";
+	static const char UNKNOWN_SPEED_STR[] = "Unknown speed ";
+	static const char MBITS_STR[]	      = "Mbit/s";
+	static const char GBITS_STR[]	      = "Gbit/s";
+	static const char FDX_STR[]           = "FDX ";
+	static const char HDX_STR[]           = "HDX ";
+	/* autoneg is latest param in default string, so add '\n' */
+	static const char AUTONEG_STR[]       = "Autoneg\n";
+	static const char FIXED_STR[]         = "Fixed\n";
+	if (str == NULL || len == 0)
+		return -1;
+	/* default format string, if no fmt is specified */
+	if (fmt == NULL) {
+		if (link->link_status == ETH_LINK_DOWN) {
+			if (sizeof(LINK_DOWN_STR) > len)
+				return -1;
+			return strlcpy(str, LINK_DOWN_STR, len);
+		}
+
+		/* preformat complex strings to easily concatinate it further */
+		snprintf(mbits_str, 20, "%u %s ", link->link_speed, MBITS_STR);
+		snprintf(gbits_str, 20, "%.1f %s ", gbits, GBITS_STR);
+
+		offset = strlcpy(str, LINK_UP_STR, len);
+		/* reserve one byte to null terminator */
+		if (offset > (len - 1))
+			return -1;
+		/* link speed */
+		if (link->link_speed == ETH_SPEED_NUM_UNKNOWN) {
+			offset = strlcat(str, UNKNOWN_SPEED_STR, len);
+			if (offset > (len - 1))
+				return -1;
+		} else {
+			if (link->link_speed < ETH_SPEED_NUM_1G) {
+				offset = strlcat(str, mbits_str, len);
+				if (offset > (len - 1))
+					return -1;
+			} else {
+				offset = strlcat(str, gbits_str, len);
+				if (offset > (len - 1))
+					return -1;
+			}
+		}
+		/* link duplex */
+		offset = strlcat(str, link->link_duplex ?
+			       FDX_STR : HDX_STR, len);
+		if (offset > (len - 1))
+			return -1;
+		/* link autonegotiation */
+		offset = strlcat(str, link->link_autoneg ?
+			       AUTONEG_STR : FIXED_STR, len);
+		if (offset > (len - 1))
+			return -1;
+	/* Formatted status */
+	} else
+		offset = rte_eth_link_strf_parser(str, len, fmt, link);
+
+	return offset;
+}
+
 int
 rte_eth_stats_get(uint16_t port_id, struct rte_eth_stats *stats)
 {
diff --git a/lib/librte_ethdev/rte_ethdev.h b/lib/librte_ethdev/rte_ethdev.h
index 2090af501..974fee591 100644
--- a/lib/librte_ethdev/rte_ethdev.h
+++ b/lib/librte_ethdev/rte_ethdev.h
@@ -2295,6 +2295,60 @@ int rte_eth_link_get(uint16_t port_id, struct rte_eth_link *link);
  */
 int rte_eth_link_get_nowait(uint16_t port_id, struct rte_eth_link *link);
 
+
+/**
+ * print formatted link status to stdout. This function threats all
+ * special values like ETH_SPEED_NUM_UNKNOWN, ETH_LINK_DOWN etc. and convert
+ * them to textual representation.
+ *
+ * @param fmt
+ *   Format string which allow to format link status. If NULL is provided
+ *   , default formatting will be applied.
+ *   Following specifiers are available:
+ *    - '%M' link speed in Mbits/s
+ *    - '%G' link speed in Gbits/s
+ *    - '%S' link status. e.g. Up or Down
+ *    - '%A' link autonegotiation state
+ *    - '%D' link duplex state
+ * @param link
+ *   Link status provided by rte_eth_link_get function
+ * @return
+ *   - Number of bytes written to stdout. In case of error, -1 is returned.
+ *
+ */
+__rte_experimental
+int rte_eth_link_printf(const char *const fmt,
+			struct rte_eth_link *link);
+
+/**
+ * Format link status to textual representation. This function threats all
+ * special values like ETH_SPEED_NUM_UNKNOWN, ETH_LINK_DOWN etc. and convert
+ * them to textual representation.
+ *
+ * @param str
+ *   A pointer to a string to be filled with textual representation of
+ *   device status.
+ * @param len
+ *   Length of available memory at 'str' string.
+ * @param fmt
+ *   Format string which allow to format link status. If NULL is provided
+ *   , default formatting will be applied.
+ *   Following specifiers are available:
+ *    - '%M' link speed in Mbits/s
+ *    - '%G' link speed in Gbits/s
+ *    - '%S' link status. e.g. Up or Down
+ *    - '%A' link autonegotiation state
+ *    - '%D' link duplex state
+ * @param link
+ *   Link status provided by rte_eth_link_get function
+ * @return
+ *   - Number of bytes written to str array. In case of error, -1 is returned.
+ *
+ */
+__rte_experimental
+int rte_eth_link_strf(char *str, size_t len, const char *const fmt,
+			struct rte_eth_link *eth_link);
+
 /**
  * Retrieve the general I/O statistics of an Ethernet device.
  *
diff --git a/lib/librte_ethdev/rte_ethdev_version.map b/lib/librte_ethdev/rte_ethdev_version.map
index 715505604..6c80597d1 100644
--- a/lib/librte_ethdev/rte_ethdev_version.map
+++ b/lib/librte_ethdev/rte_ethdev_version.map
@@ -241,4 +241,8 @@ EXPERIMENTAL {
 	__rte_ethdev_trace_rx_burst;
 	__rte_ethdev_trace_tx_burst;
 	rte_flow_get_aged_flows;
+
+	# added in 20.08
+	rte_eth_link_strf;
+	rte_eth_link_printf;
 };
-- 
2.17.1


^ permalink raw reply	[flat|nested] 359+ messages in thread

* [dpdk-dev] [PATCH v6 03/25] app: UNKNOWN link speed print format
       [not found]                             ` <CGME20200706203800eucas1p2e1cb90a305258ac2a02fb5de8abc03cb@eucas1p2.samsung.com>
@ 2020-07-06 20:37                               ` Ivan Dyukov
  2020-07-06 21:26                                 ` Stephen Hemminger
  0 siblings, 1 reply; 359+ messages in thread
From: Ivan Dyukov @ 2020-07-06 20:37 UTC (permalink / raw)
  To: dev, i.dyukov, v.kuramshin, thomas, david.marchand, ferruh.yigit,
	arybchenko, wei.zhao1, jia.guo, beilei.xing, qiming.yang,
	wenzhuo.lu, mb, stephen, nicolas.chautru, bruce.richardson,
	konstantin.ananyev, cristian.dumitrescu, radu.nicolau,
	akhil.goyal, declan.doherty, skori, pbhagavatula, jerinj,
	kirankumark, david.hunt, anatoly.burakov, xiaoyun.li,
	jingjing.wu, john.mcnamara, jasvinder.singh, byron.marohn,
	yipeng1.wang

Add usage of rte_eth_link_strf function to example
applications

Signed-off-by: Ivan Dyukov <i.dyukov@samsung.com>
---
 app/proc-info/main.c     |  9 +++------
 app/test-pipeline/init.c | 11 +++++------
 app/test-pmd/config.c    | 20 ++++++++++++--------
 app/test-pmd/testpmd.c   |  9 +--------
 app/test/test_pmd_perf.c | 17 +++++++----------
 5 files changed, 28 insertions(+), 38 deletions(-)

diff --git a/app/proc-info/main.c b/app/proc-info/main.c
index abeca4aab..4a4c572c3 100644
--- a/app/proc-info/main.c
+++ b/app/proc-info/main.c
@@ -685,12 +685,9 @@ show_port(void)
 			printf("Link get failed (port %u): %s\n",
 			       i, rte_strerror(-ret));
 		} else {
-			printf("\t  -- link speed %d duplex %d,"
-					" auto neg %d status %d\n",
-					link.link_speed,
-					link.link_duplex,
-					link.link_autoneg,
-					link.link_status);
+			rte_eth_link_printf("\t  -- link speed: %M, duplex: %D,"
+					" auto neg: %A, status: %S\n",
+					&link);
 		}
 		printf("\t  -- promiscuous (%d)\n",
 				rte_eth_promiscuous_get(i));
diff --git a/app/test-pipeline/init.c b/app/test-pipeline/init.c
index 67d54ae05..b59064672 100644
--- a/app/test-pipeline/init.c
+++ b/app/test-pipeline/init.c
@@ -155,7 +155,7 @@ static void
 app_ports_check_link(void)
 {
 	uint32_t all_ports_up, i;
-
+	char link_status_text[50];
 	all_ports_up = 1;
 
 	for (i = 0; i < app.n_ports; i++) {
@@ -173,12 +173,11 @@ app_ports_check_link(void)
 			all_ports_up = 0;
 			continue;
 		}
-
-		RTE_LOG(INFO, USER1, "Port %u (%u Gbps) %s\n",
+		rte_eth_link_strf(link_status_text, 50, "(%G Gbps) %S",
+				  &link);
+		RTE_LOG(INFO, USER1, "Port %u %s\n",
 			port,
-			link.link_speed / 1000,
-			link.link_status ? "UP" : "DOWN");
-
+			link_status_text);
 		if (link.link_status == ETH_LINK_DOWN)
 			all_ports_up = 0;
 	}
diff --git a/app/test-pmd/config.c b/app/test-pmd/config.c
index a7112c998..cb2795a94 100644
--- a/app/test-pmd/config.c
+++ b/app/test-pmd/config.c
@@ -604,10 +604,9 @@ port_infos_display(portid_t port_id)
 	} else
 		printf("\nmemory allocation on the socket: %u",port->socket_id);
 
-	printf("\nLink status: %s\n", (link.link_status) ? ("up") : ("down"));
-	printf("Link speed: %u Mbps\n", (unsigned) link.link_speed);
-	printf("Link duplex: %s\n", (link.link_duplex == ETH_LINK_FULL_DUPLEX) ?
-	       ("full-duplex") : ("half-duplex"));
+	rte_eth_link_printf("\nLink status: %S\n"
+			    "Link speed: %M Mbps\n"
+			    "Link duplex: %D\n", &link);
 
 	if (!rte_eth_dev_get_mtu(port_id, &mtu))
 		printf("MTU: %u\n", mtu);
@@ -730,6 +729,8 @@ port_summary_display(portid_t port_id)
 	struct rte_eth_link link;
 	struct rte_eth_dev_info dev_info;
 	char name[RTE_ETH_NAME_MAX_LEN];
+	char status_text[6];
+	char speed_text[12];
 	int ret;
 
 	if (port_id_is_invalid(port_id, ENABLED_WARN)) {
@@ -750,12 +751,14 @@ port_summary_display(portid_t port_id)
 	if (ret != 0)
 		return;
 
-	printf("%-4d %02X:%02X:%02X:%02X:%02X:%02X %-12s %-14s %-8s %uMbps\n",
+	rte_eth_link_strf(status_text, 6, "%S", &link);
+	rte_eth_link_strf(speed_text, 12, "%M", &link);
+	printf("%-4d %02X:%02X:%02X:%02X:%02X:%02X %-12s %-14s %-8s %sMbps\n",
 		port_id, mac_addr.addr_bytes[0], mac_addr.addr_bytes[1],
 		mac_addr.addr_bytes[2], mac_addr.addr_bytes[3],
 		mac_addr.addr_bytes[4], mac_addr.addr_bytes[5], name,
-		dev_info.driver_name, (link.link_status) ? ("up") : ("down"),
-		(unsigned int) link.link_speed);
+		dev_info.driver_name, status_text,
+		speed_text);
 }
 
 void
@@ -3899,7 +3902,8 @@ set_queue_rate_limit(portid_t port_id, uint16_t queue_idx, uint16_t rate)
 	ret = eth_link_get_nowait_print_err(port_id, &link);
 	if (ret < 0)
 		return 1;
-	if (rate > link.link_speed) {
+	if (link.link_speed != ETH_SPEED_NUM_UNKNOWN &&
+	    rate > link.link_speed) {
 		printf("Invalid rate value:%u bigger than link speed: %u\n",
 			rate, link.link_speed);
 		return 1;
diff --git a/app/test-pmd/testpmd.c b/app/test-pmd/testpmd.c
index 4989d22ca..a1b9c1c1c 100644
--- a/app/test-pmd/testpmd.c
+++ b/app/test-pmd/testpmd.c
@@ -3010,14 +3010,7 @@ check_all_ports_link_status(uint32_t port_mask)
 			}
 			/* print link status if flag set */
 			if (print_flag == 1) {
-				if (link.link_status)
-					printf(
-					"Port%d Link Up. speed %u Mbps- %s\n",
-					portid, link.link_speed,
-				(link.link_duplex == ETH_LINK_FULL_DUPLEX) ?
-					("full-duplex") : ("half-duplex"));
-				else
-					printf("Port %d Link Down\n", portid);
+				rte_eth_link_printf(NULL, &link);
 				continue;
 			}
 			/* clear all_ports_up flag if any link down */
diff --git a/app/test/test_pmd_perf.c b/app/test/test_pmd_perf.c
index 352cd4715..7ebe4efae 100644
--- a/app/test/test_pmd_perf.c
+++ b/app/test/test_pmd_perf.c
@@ -126,6 +126,7 @@ check_all_ports_link_status(uint16_t port_num, uint32_t port_mask)
 	uint8_t count, all_ports_up, print_flag = 0;
 	struct rte_eth_link link;
 	int ret;
+	char link_status[50];
 
 	printf("Checking link statuses...\n");
 	fflush(stdout);
@@ -146,16 +147,12 @@ check_all_ports_link_status(uint16_t port_num, uint32_t port_mask)
 
 			/* print link status if flag set */
 			if (print_flag == 1) {
-				if (link.link_status) {
-					printf(
-					"Port%d Link Up. Speed %u Mbps - %s\n",
-						portid, link.link_speed,
-				(link.link_duplex == ETH_LINK_FULL_DUPLEX) ?
-					("full-duplex") : ("half-duplex"));
-					if (link_mbps == 0)
-						link_mbps = link.link_speed;
-				} else
-					printf("Port %d Link Down\n", portid);
+				if (link.link_status && link_mbps == 0)
+					link_mbps = link.link_speed;
+
+				rte_eth_link_strf(link_status, 50, NULL,
+						  &link);
+				printf("Port %d %s\n", portid, link_status);
 				continue;
 			}
 			/* clear all_ports_up flag if any link down */
-- 
2.17.1


^ permalink raw reply	[flat|nested] 359+ messages in thread

* [dpdk-dev] [PATCH v6 04/25] doc: update sample app with unknown speed
       [not found]                             ` <CGME20200706203803eucas1p26fa02f91c1c5f94b8ce724a75b341f31@eucas1p2.samsung.com>
@ 2020-07-06 20:37                               ` Ivan Dyukov
  0 siblings, 0 replies; 359+ messages in thread
From: Ivan Dyukov @ 2020-07-06 20:37 UTC (permalink / raw)
  To: dev, i.dyukov, v.kuramshin, thomas, david.marchand, ferruh.yigit,
	arybchenko, wei.zhao1, jia.guo, beilei.xing, qiming.yang,
	wenzhuo.lu, mb, stephen, nicolas.chautru, bruce.richardson,
	konstantin.ananyev, cristian.dumitrescu, radu.nicolau,
	akhil.goyal, declan.doherty, skori, pbhagavatula, jerinj,
	kirankumark, david.hunt, anatoly.burakov, xiaoyun.li,
	jingjing.wu, john.mcnamara, jasvinder.singh, byron.marohn,
	yipeng1.wang

Add usage of rte_eth_link_strf function to example
applications

Signed-off-by: Ivan Dyukov <i.dyukov@samsung.com>
---
 doc/guides/sample_app_ug/link_status_intr.rst | 10 +++++-----
 1 file changed, 5 insertions(+), 5 deletions(-)

diff --git a/doc/guides/sample_app_ug/link_status_intr.rst b/doc/guides/sample_app_ug/link_status_intr.rst
index 04c40f285..596782b9d 100644
--- a/doc/guides/sample_app_ug/link_status_intr.rst
+++ b/doc/guides/sample_app_ug/link_status_intr.rst
@@ -158,6 +158,7 @@ An example callback function that has been written as indicated below.
     {
         struct rte_eth_link link;
         int ret;
+        char link_status[200];
 
         RTE_SET_USED(param);
 
@@ -169,11 +170,10 @@ An example callback function that has been written as indicated below.
         if (ret < 0) {
             printf("Failed to get port %d link status: %s\n\n",
                    port_id, rte_strerror(-ret));
-        } else if (link.link_status) {
-            printf("Port %d Link Up - speed %u Mbps - %s\n\n", port_id, (unsigned)link.link_speed,
-                  (link.link_duplex == ETH_LINK_FULL_DUPLEX) ? ("full-duplex") : ("half-duplex"));
-        } else
-            printf("Port %d Link Down\n\n", port_id);
+        } else {
+            rte_eth_link_strf(link_status, 200, NULL, &link);
+            printf("Port %d %s\n\n", port_id, link_status);
+        }
     }
 
 This function is called when a link status interrupt is present for the right port.
-- 
2.17.1


^ permalink raw reply	[flat|nested] 359+ messages in thread

* [dpdk-dev] [PATCH v6 05/25] net/ixgbe: return unknown speed in status
       [not found]                             ` <CGME20200706203805eucas1p2b8c92ded7d87356c788dec9e936edf43@eucas1p2.samsung.com>
@ 2020-07-06 20:37                               ` Ivan Dyukov
  0 siblings, 0 replies; 359+ messages in thread
From: Ivan Dyukov @ 2020-07-06 20:37 UTC (permalink / raw)
  To: dev, i.dyukov, v.kuramshin, thomas, david.marchand, ferruh.yigit,
	arybchenko, wei.zhao1, jia.guo, beilei.xing, qiming.yang,
	wenzhuo.lu, mb, stephen, nicolas.chautru, bruce.richardson,
	konstantin.ananyev, cristian.dumitrescu, radu.nicolau,
	akhil.goyal, declan.doherty, skori, pbhagavatula, jerinj,
	kirankumark, david.hunt, anatoly.burakov, xiaoyun.li,
	jingjing.wu, john.mcnamara, jasvinder.singh, byron.marohn,
	yipeng1.wang

rte_ethdev has declared new NUM_UNKNOWN speed which
could be used in case when no speed information is available

Signed-off-by: Ivan Dyukov <i.dyukov@samsung.com>
Reviewed-by: Wei Zhao <wei.zhao1@intel.com>
---
 drivers/net/ixgbe/ixgbe_ethdev.c | 6 +-----
 1 file changed, 1 insertion(+), 5 deletions(-)

diff --git a/drivers/net/ixgbe/ixgbe_ethdev.c b/drivers/net/ixgbe/ixgbe_ethdev.c
index 248f21d14..34a171116 100644
--- a/drivers/net/ixgbe/ixgbe_ethdev.c
+++ b/drivers/net/ixgbe/ixgbe_ethdev.c
@@ -4300,11 +4300,7 @@ ixgbe_dev_link_update_share(struct rte_eth_dev *dev,
 	switch (link_speed) {
 	default:
 	case IXGBE_LINK_SPEED_UNKNOWN:
-		if (hw->device_id == IXGBE_DEV_ID_X550EM_A_1G_T ||
-			hw->device_id == IXGBE_DEV_ID_X550EM_A_1G_T_L)
-			link.link_speed = ETH_SPEED_NUM_10M;
-		else
-			link.link_speed = ETH_SPEED_NUM_100M;
+		link.link_speed = ETH_SPEED_NUM_UNKNOWN;
 		break;
 
 	case IXGBE_LINK_SPEED_100_FULL:
-- 
2.17.1


^ permalink raw reply	[flat|nested] 359+ messages in thread

* [dpdk-dev] [PATCH v6 06/25] net/i40e: return unknown speed in status
       [not found]                             ` <CGME20200706203808eucas1p149298d8c1de1cea35fe9dd22e5a81ea4@eucas1p1.samsung.com>
@ 2020-07-06 20:37                               ` " Ivan Dyukov
  0 siblings, 0 replies; 359+ messages in thread
From: Ivan Dyukov @ 2020-07-06 20:37 UTC (permalink / raw)
  To: dev, i.dyukov, v.kuramshin, thomas, david.marchand, ferruh.yigit,
	arybchenko, wei.zhao1, jia.guo, beilei.xing, qiming.yang,
	wenzhuo.lu, mb, stephen, nicolas.chautru, bruce.richardson,
	konstantin.ananyev, cristian.dumitrescu, radu.nicolau,
	akhil.goyal, declan.doherty, skori, pbhagavatula, jerinj,
	kirankumark, david.hunt, anatoly.burakov, xiaoyun.li,
	jingjing.wu, john.mcnamara, jasvinder.singh, byron.marohn,
	yipeng1.wang

rte_ethdev has declared new NUM_UNKNOWN speed which
could be used in case when no speed information is available and
link is up. NUM_NONE should be returned, if link is down.

Signed-off-by: Ivan Dyukov <i.dyukov@samsung.com>
Acked-by: Jeff Guo <jia.guo@intel.com>
---
 drivers/net/i40e/i40e_ethdev.c    |  5 ++++-
 drivers/net/i40e/i40e_ethdev_vf.c | 10 +++++-----
 2 files changed, 9 insertions(+), 6 deletions(-)

diff --git a/drivers/net/i40e/i40e_ethdev.c b/drivers/net/i40e/i40e_ethdev.c
index 472ce2a9e..f718356b5 100644
--- a/drivers/net/i40e/i40e_ethdev.c
+++ b/drivers/net/i40e/i40e_ethdev.c
@@ -2891,7 +2891,10 @@ update_link_aq(struct i40e_hw *hw, struct rte_eth_link *link,
 		link->link_speed = ETH_SPEED_NUM_40G;
 		break;
 	default:
-		link->link_speed = ETH_SPEED_NUM_NONE;
+		if (link->link_status)
+			link->link_speed = ETH_SPEED_NUM_UNKNOWN;
+		else
+			link->link_speed = ETH_SPEED_NUM_NONE;
 		break;
 	}
 }
diff --git a/drivers/net/i40e/i40e_ethdev_vf.c b/drivers/net/i40e/i40e_ethdev_vf.c
index eca716a6a..cf931bf9c 100644
--- a/drivers/net/i40e/i40e_ethdev_vf.c
+++ b/drivers/net/i40e/i40e_ethdev_vf.c
@@ -2163,15 +2163,15 @@ i40evf_dev_link_update(struct rte_eth_dev *dev,
 		new_link.link_speed = ETH_SPEED_NUM_40G;
 		break;
 	default:
-		new_link.link_speed = ETH_SPEED_NUM_NONE;
+		if (vf->link_up)
+			new_link.link_speed = ETH_SPEED_NUM_UNKNOWN;
+		else
+			new_link.link_speed = ETH_SPEED_NUM_NONE;
 		break;
 	}
 	/* full duplex only */
 	new_link.link_duplex = ETH_LINK_FULL_DUPLEX;
-	new_link.link_status = vf->link_up &&
-				new_link.link_speed != ETH_SPEED_NUM_NONE
-				? ETH_LINK_UP
-				: ETH_LINK_DOWN;
+	new_link.link_status = vf->link_up ? ETH_LINK_UP : ETH_LINK_DOWN;
 	new_link.link_autoneg =
 		!(dev->data->dev_conf.link_speeds & ETH_LINK_SPEED_FIXED);
 
-- 
2.17.1


^ permalink raw reply	[flat|nested] 359+ messages in thread

* [dpdk-dev] [PATCH v6 07/25] net/ice: return unknown speed in status
       [not found]                             ` <CGME20200706203810eucas1p2d010ecaa97bf03484e61c4629909e76a@eucas1p2.samsung.com>
@ 2020-07-06 20:37                               ` " Ivan Dyukov
  0 siblings, 0 replies; 359+ messages in thread
From: Ivan Dyukov @ 2020-07-06 20:37 UTC (permalink / raw)
  To: dev, i.dyukov, v.kuramshin, thomas, david.marchand, ferruh.yigit,
	arybchenko, wei.zhao1, jia.guo, beilei.xing, qiming.yang,
	wenzhuo.lu, mb, stephen, nicolas.chautru, bruce.richardson,
	konstantin.ananyev, cristian.dumitrescu, radu.nicolau,
	akhil.goyal, declan.doherty, skori, pbhagavatula, jerinj,
	kirankumark, david.hunt, anatoly.burakov, xiaoyun.li,
	jingjing.wu, john.mcnamara, jasvinder.singh, byron.marohn,
	yipeng1.wang

rte_ethdev has declared new NUM_UNKNOWN speed which
could be used in case when no speed information is available and
link is up. NUM_NONE should be returned, if link is down.

Signed-off-by: Ivan Dyukov <i.dyukov@samsung.com>
Reviewed-by: Ferruh Yigit <ferruh.yigit@intel.com>
---
 drivers/net/ice/ice_ethdev.c | 5 ++++-
 1 file changed, 4 insertions(+), 1 deletion(-)

diff --git a/drivers/net/ice/ice_ethdev.c b/drivers/net/ice/ice_ethdev.c
index b51fa2f17..76f797de0 100644
--- a/drivers/net/ice/ice_ethdev.c
+++ b/drivers/net/ice/ice_ethdev.c
@@ -3135,8 +3135,11 @@ ice_link_update(struct rte_eth_dev *dev, int wait_to_complete)
 		link.link_speed = ETH_SPEED_NUM_100G;
 		break;
 	case ICE_AQ_LINK_SPEED_UNKNOWN:
-	default:
 		PMD_DRV_LOG(ERR, "Unknown link speed");
+		link.link_speed = ETH_SPEED_NUM_UNKNOWN;
+		break;
+	default:
+		PMD_DRV_LOG(ERR, "None link speed");
 		link.link_speed = ETH_SPEED_NUM_NONE;
 		break;
 	}
-- 
2.17.1


^ permalink raw reply	[flat|nested] 359+ messages in thread

* [dpdk-dev] [PATCH v6 08/25] examples: new link status print format
       [not found]                             ` <CGME20200706203813eucas1p1fd1cf5ef5ae7ac290dcc2e4de11c6224@eucas1p1.samsung.com>
@ 2020-07-06 20:37                               ` Ivan Dyukov
  0 siblings, 0 replies; 359+ messages in thread
From: Ivan Dyukov @ 2020-07-06 20:37 UTC (permalink / raw)
  To: dev, i.dyukov, v.kuramshin, thomas, david.marchand, ferruh.yigit,
	arybchenko, wei.zhao1, jia.guo, beilei.xing, qiming.yang,
	wenzhuo.lu, mb, stephen, nicolas.chautru, bruce.richardson,
	konstantin.ananyev, cristian.dumitrescu, radu.nicolau,
	akhil.goyal, declan.doherty, skori, pbhagavatula, jerinj,
	kirankumark, david.hunt, anatoly.burakov, xiaoyun.li,
	jingjing.wu, john.mcnamara, jasvinder.singh, byron.marohn,
	yipeng1.wang

Add usage of rte_eth_link_strf function to example
applications:
	* ipv4_multicast
	* l2fwd-jobstats
	* l2fwd-keepalive
	* l3fwd
	* link_status_interrupt

Signed-off-by: Ivan Dyukov <i.dyukov@samsung.com>
---
 examples/ipv4_multicast/main.c        | 12 ++++-------
 examples/l2fwd-jobstats/main.c        | 12 ++++-------
 examples/l2fwd-keepalive/main.c       | 12 ++++-------
 examples/l3fwd/main.c                 | 12 ++++-------
 examples/link_status_interrupt/main.c | 30 +++++++++++----------------
 5 files changed, 28 insertions(+), 50 deletions(-)

diff --git a/examples/ipv4_multicast/main.c b/examples/ipv4_multicast/main.c
index 7e255c35a..0d4957658 100644
--- a/examples/ipv4_multicast/main.c
+++ b/examples/ipv4_multicast/main.c
@@ -572,6 +572,7 @@ check_all_ports_link_status(uint32_t port_mask)
 	uint8_t count, all_ports_up, print_flag = 0;
 	struct rte_eth_link link;
 	int ret;
+	char link_status_text[60];
 
 	printf("\nChecking link status");
 	fflush(stdout);
@@ -591,14 +592,9 @@ check_all_ports_link_status(uint32_t port_mask)
 			}
 			/* print link status if flag set */
 			if (print_flag == 1) {
-				if (link.link_status)
-					printf(
-					"Port%d Link Up. Speed %u Mbps - %s\n",
-					portid, link.link_speed,
-				(link.link_duplex == ETH_LINK_FULL_DUPLEX) ?
-					("full-duplex") : ("half-duplex"));
-				else
-					printf("Port %d Link Down\n", portid);
+				rte_eth_link_strf(link_status_text, 60, NULL,
+						  &link);
+				printf("Port %d %s", portid, link_status_text);
 				continue;
 			}
 			/* clear all_ports_up flag if any link down */
diff --git a/examples/l2fwd-jobstats/main.c b/examples/l2fwd-jobstats/main.c
index 47a3b0976..740f1c80f 100644
--- a/examples/l2fwd-jobstats/main.c
+++ b/examples/l2fwd-jobstats/main.c
@@ -689,6 +689,7 @@ check_all_ports_link_status(uint32_t port_mask)
 	uint8_t count, all_ports_up, print_flag = 0;
 	struct rte_eth_link link;
 	int ret;
+	char link_status_text[60];
 
 	printf("\nChecking link status");
 	fflush(stdout);
@@ -708,14 +709,9 @@ check_all_ports_link_status(uint32_t port_mask)
 			}
 			/* print link status if flag set */
 			if (print_flag == 1) {
-				if (link.link_status)
-					printf(
-					"Port%d Link Up. Speed %u Mbps - %s\n",
-						portid, link.link_speed,
-				(link.link_duplex == ETH_LINK_FULL_DUPLEX) ?
-					("full-duplex") : ("half-duplex"));
-				else
-					printf("Port %d Link Down\n", portid);
+				rte_eth_link_strf(link_status_text, 60, NULL,
+						  &link);
+				printf("Port %d %s", portid, link_status_text);
 				continue;
 			}
 			/* clear all_ports_up flag if any link down */
diff --git a/examples/l2fwd-keepalive/main.c b/examples/l2fwd-keepalive/main.c
index b2742633b..d8be0a727 100644
--- a/examples/l2fwd-keepalive/main.c
+++ b/examples/l2fwd-keepalive/main.c
@@ -453,6 +453,7 @@ check_all_ports_link_status(uint32_t port_mask)
 	uint8_t count, all_ports_up, print_flag = 0;
 	struct rte_eth_link link;
 	int ret;
+	char link_status_text[60];
 
 	printf("\nChecking link status");
 	fflush(stdout);
@@ -472,14 +473,9 @@ check_all_ports_link_status(uint32_t port_mask)
 			}
 			/* print link status if flag set */
 			if (print_flag == 1) {
-				if (link.link_status)
-					printf(
-					"Port%d Link Up. Speed %u Mbps - %s\n",
-						portid, link.link_speed,
-				(link.link_duplex == ETH_LINK_FULL_DUPLEX) ?
-					("full-duplex") : ("half-duplex"));
-				else
-					printf("Port %d Link Down\n", portid);
+				rte_eth_link_strf(link_status_text, 60, NULL,
+						  &link);
+				printf("Port %d %s", portid, link_status_text);
 				continue;
 			}
 			/* clear all_ports_up flag if any link down */
diff --git a/examples/l3fwd/main.c b/examples/l3fwd/main.c
index 24ede4290..ef0f19a39 100644
--- a/examples/l3fwd/main.c
+++ b/examples/l3fwd/main.c
@@ -810,6 +810,7 @@ check_all_ports_link_status(uint32_t port_mask)
 	uint8_t count, all_ports_up, print_flag = 0;
 	struct rte_eth_link link;
 	int ret;
+	char link_status_text[60];
 
 	printf("\nChecking link status");
 	fflush(stdout);
@@ -833,14 +834,9 @@ check_all_ports_link_status(uint32_t port_mask)
 			}
 			/* print link status if flag set */
 			if (print_flag == 1) {
-				if (link.link_status)
-					printf(
-					"Port%d Link Up. Speed %u Mbps -%s\n",
-						portid, link.link_speed,
-				(link.link_duplex == ETH_LINK_FULL_DUPLEX) ?
-					("full-duplex") : ("half-duplex"));
-				else
-					printf("Port %d Link Down\n", portid);
+				rte_eth_link_strf(link_status_text, 60, NULL,
+						  &link);
+				printf("Port %d %s", portid, link_status_text);
 				continue;
 			}
 			/* clear all_ports_up flag if any link down */
diff --git a/examples/link_status_interrupt/main.c b/examples/link_status_interrupt/main.c
index 9bbcadfcf..5e286060d 100644
--- a/examples/link_status_interrupt/main.c
+++ b/examples/link_status_interrupt/main.c
@@ -118,6 +118,7 @@ print_stats(void)
 	const char clr[] = { 27, '[', '2', 'J', '\0' };
 	const char topLeft[] = { 27, '[', '1', ';', '1', 'H','\0' };
 	int link_get_err;
+	char link_speed_text[16];
 
 		/* Clear screen and move to top left */
 	printf("%s%s", clr, topLeft);
@@ -131,9 +132,10 @@ print_stats(void)
 
 		memset(&link, 0, sizeof(link));
 		link_get_err = rte_eth_link_get_nowait(portid, &link);
+		rte_eth_link_strf(link_speed_text, 16, "%M", &link);
 		printf("\nStatistics for port %u ------------------------------"
 			   "\nLink status: %25s"
-			   "\nLink speed: %26u"
+			   "\nLink speed: %26s"
 			   "\nLink duplex: %25s"
 			   "\nPackets sent: %24"PRIu64
 			   "\nPackets received: %20"PRIu64
@@ -141,8 +143,7 @@ print_stats(void)
 			   portid,
 			   link_get_err < 0 ? "Link get failed" :
 			   (link.link_status ? "Link up" : "Link down"),
-			   link_get_err < 0 ? 0 :
-					(unsigned int)link.link_speed,
+			   link_get_err < 0 ? "0" : link_speed_text,
 			   link_get_err < 0 ? "Link get failed" :
 			   (link.link_duplex == ETH_LINK_FULL_DUPLEX ? \
 					"full-duplex" : "half-duplex"),
@@ -445,6 +446,7 @@ lsi_event_callback(uint16_t port_id, enum rte_eth_event_type type, void *param,
 {
 	struct rte_eth_link link;
 	int ret;
+	char link_status_text[60];
 
 	RTE_SET_USED(param);
 	RTE_SET_USED(ret_param);
@@ -457,13 +459,8 @@ lsi_event_callback(uint16_t port_id, enum rte_eth_event_type type, void *param,
 		       port_id, rte_strerror(-ret));
 		return ret;
 	}
-	if (link.link_status) {
-		printf("Port %d Link Up - speed %u Mbps - %s\n\n",
-				port_id, (unsigned)link.link_speed,
-			(link.link_duplex == ETH_LINK_FULL_DUPLEX) ?
-				("full-duplex") : ("half-duplex"));
-	} else
-		printf("Port %d Link Down\n\n", port_id);
+	rte_eth_link_strf(link_status_text, 60, NULL, &link);
+	printf("Port %d %s\n", port_id, link_status_text);
 
 	return 0;
 }
@@ -478,6 +475,7 @@ check_all_ports_link_status(uint16_t port_num, uint32_t port_mask)
 	uint16_t portid;
 	struct rte_eth_link link;
 	int ret;
+	char link_status_text[60];
 
 	printf("\nChecking link status");
 	fflush(stdout);
@@ -497,14 +495,10 @@ check_all_ports_link_status(uint16_t port_num, uint32_t port_mask)
 			}
 			/* print link status if flag set */
 			if (print_flag == 1) {
-				if (link.link_status)
-					printf(
-					"Port%d Link Up. Speed %u Mbps - %s\n",
-						portid, link.link_speed,
-				(link.link_duplex == ETH_LINK_FULL_DUPLEX) ?
-					("full-duplex") : ("half-duplex"));
-				else
-					printf("Port %d Link Down\n", portid);
+				rte_eth_link_strf(link_status_text, 60, NULL,
+						    &link);
+				printf("Port %d %s", portid,
+				       link_status_text);
 				continue;
 			}
 			/* clear all_ports_up flag if any link down */
-- 
2.17.1


^ permalink raw reply	[flat|nested] 359+ messages in thread

* [dpdk-dev] [PATCH v6 09/25] examples/bbdev_app: new link status print format
       [not found]                             ` <CGME20200706203816eucas1p1e8b84a0dfdd156d6f9a87c2dc96b8bf7@eucas1p1.samsung.com>
@ 2020-07-06 20:37                               ` " Ivan Dyukov
  0 siblings, 0 replies; 359+ messages in thread
From: Ivan Dyukov @ 2020-07-06 20:37 UTC (permalink / raw)
  To: dev, i.dyukov, v.kuramshin, thomas, david.marchand, ferruh.yigit,
	arybchenko, wei.zhao1, jia.guo, beilei.xing, qiming.yang,
	wenzhuo.lu, mb, stephen, nicolas.chautru, bruce.richardson,
	konstantin.ananyev, cristian.dumitrescu, radu.nicolau,
	akhil.goyal, declan.doherty, skori, pbhagavatula, jerinj,
	kirankumark, david.hunt, anatoly.burakov, xiaoyun.li,
	jingjing.wu, john.mcnamara, jasvinder.singh, byron.marohn,
	yipeng1.wang

Add usage of rte_eth_link_strf function to example
applications

Signed-off-by: Ivan Dyukov <i.dyukov@samsung.com>
---
 examples/bbdev_app/main.c | 8 +++-----
 1 file changed, 3 insertions(+), 5 deletions(-)

diff --git a/examples/bbdev_app/main.c b/examples/bbdev_app/main.c
index 68a46050c..44e6952e6 100644
--- a/examples/bbdev_app/main.c
+++ b/examples/bbdev_app/main.c
@@ -313,6 +313,7 @@ check_port_link_status(uint16_t port_id)
 	uint8_t count;
 	struct rte_eth_link link;
 	int link_get_err = -EINVAL;
+	char link_status_text[60];
 
 	printf("\nChecking link status.");
 	fflush(stdout);
@@ -323,11 +324,8 @@ check_port_link_status(uint16_t port_id)
 		link_get_err = rte_eth_link_get_nowait(port_id, &link);
 
 		if (link_get_err >= 0 && link.link_status) {
-			const char *dp = (link.link_duplex ==
-				ETH_LINK_FULL_DUPLEX) ?
-				"full-duplex" : "half-duplex";
-			printf("\nPort %u Link Up - speed %u Mbps - %s\n",
-				port_id, link.link_speed, dp);
+			rte_eth_link_strf(link_status_text, 60, NULL, &link);
+			printf("\nPort %u %s", port_id, link_status_text);
 			return 0;
 		}
 		printf(".");
-- 
2.17.1


^ permalink raw reply	[flat|nested] 359+ messages in thread

* [dpdk-dev] [PATCH v6 10/25] examples/ioat: new link status print format
       [not found]                             ` <CGME20200706203819eucas1p194ba5cda089597317d68ba5338d12f12@eucas1p1.samsung.com>
@ 2020-07-06 20:37                               ` " Ivan Dyukov
  0 siblings, 0 replies; 359+ messages in thread
From: Ivan Dyukov @ 2020-07-06 20:37 UTC (permalink / raw)
  To: dev, i.dyukov, v.kuramshin, thomas, david.marchand, ferruh.yigit,
	arybchenko, wei.zhao1, jia.guo, beilei.xing, qiming.yang,
	wenzhuo.lu, mb, stephen, nicolas.chautru, bruce.richardson,
	konstantin.ananyev, cristian.dumitrescu, radu.nicolau,
	akhil.goyal, declan.doherty, skori, pbhagavatula, jerinj,
	kirankumark, david.hunt, anatoly.burakov, xiaoyun.li,
	jingjing.wu, john.mcnamara, jasvinder.singh, byron.marohn,
	yipeng1.wang

Add usage of rte_eth_link_strf function to example
applications

Signed-off-by: Ivan Dyukov <i.dyukov@samsung.com>
---
 examples/ioat/ioatfwd.c | 13 +++++--------
 1 file changed, 5 insertions(+), 8 deletions(-)

diff --git a/examples/ioat/ioatfwd.c b/examples/ioat/ioatfwd.c
index b66ee73bc..8bf80c262 100644
--- a/examples/ioat/ioatfwd.c
+++ b/examples/ioat/ioatfwd.c
@@ -700,6 +700,7 @@ check_link_status(uint32_t port_mask)
 	uint16_t portid;
 	struct rte_eth_link link;
 	int ret, link_status = 0;
+	char link_status_text[60];
 
 	printf("\nChecking link status\n");
 	RTE_ETH_FOREACH_DEV(portid) {
@@ -715,15 +716,11 @@ check_link_status(uint32_t port_mask)
 		}
 
 		/* Print link status */
-		if (link.link_status) {
-			printf(
-				"Port %d Link Up. Speed %u Mbps - %s\n",
-				portid, link.link_speed,
-				(link.link_duplex == ETH_LINK_FULL_DUPLEX) ?
-				("full-duplex") : ("half-duplex"));
+		rte_eth_link_strf(link_status_text, 60, NULL, &link);
+		printf("Port %d %s", portid, link_status_text);
+
+		if (link.link_status)
 			link_status = 1;
-		} else
-			printf("Port %d Link Down\n", portid);
 	}
 	return link_status;
 }
-- 
2.17.1


^ permalink raw reply	[flat|nested] 359+ messages in thread

* [dpdk-dev] [PATCH v6 11/25] examples/ip_*: new link status print format
       [not found]                             ` <CGME20200706203821eucas1p185226841e82d0270cb03a488cf69e04f@eucas1p1.samsung.com>
@ 2020-07-06 20:37                               ` " Ivan Dyukov
  0 siblings, 0 replies; 359+ messages in thread
From: Ivan Dyukov @ 2020-07-06 20:37 UTC (permalink / raw)
  To: dev, i.dyukov, v.kuramshin, thomas, david.marchand, ferruh.yigit,
	arybchenko, wei.zhao1, jia.guo, beilei.xing, qiming.yang,
	wenzhuo.lu, mb, stephen, nicolas.chautru, bruce.richardson,
	konstantin.ananyev, cristian.dumitrescu, radu.nicolau,
	akhil.goyal, declan.doherty, skori, pbhagavatula, jerinj,
	kirankumark, david.hunt, anatoly.burakov, xiaoyun.li,
	jingjing.wu, john.mcnamara, jasvinder.singh, byron.marohn,
	yipeng1.wang

Add usage of rte_eth_link_strf function to example
applications:
	* ip_fragmentation
	* ip_reassembly
	* l3fwd-acl

Signed-off-by: Ivan Dyukov <i.dyukov@samsung.com>
---
 examples/ip_fragmentation/main.c | 13 +++++--------
 examples/ip_reassembly/main.c    | 12 ++++--------
 examples/l3fwd-acl/main.c        | 12 ++++--------
 3 files changed, 13 insertions(+), 24 deletions(-)

diff --git a/examples/ip_fragmentation/main.c b/examples/ip_fragmentation/main.c
index 4afb97109..18a6df77e 100644
--- a/examples/ip_fragmentation/main.c
+++ b/examples/ip_fragmentation/main.c
@@ -593,6 +593,7 @@ check_all_ports_link_status(uint32_t port_mask)
 	uint8_t count, all_ports_up, print_flag = 0;
 	struct rte_eth_link link;
 	int ret;
+	char link_status_text[60];
 
 	printf("\nChecking link status");
 	fflush(stdout);
@@ -612,14 +613,10 @@ check_all_ports_link_status(uint32_t port_mask)
 			}
 			/* print link status if flag set */
 			if (print_flag == 1) {
-				if (link.link_status)
-					printf(
-					"Port%d Link Up .Speed %u Mbps - %s\n",
-						portid, link.link_speed,
-				(link.link_duplex == ETH_LINK_FULL_DUPLEX) ?
-					("full-duplex") : ("half-duplex"));
-				else
-					printf("Port %d Link Down\n", portid);
+				rte_eth_link_strf(link_status_text, 60, NULL,
+						    &link);
+				printf("Port %d %s", portid,
+				       link_status_text);
 				continue;
 			}
 			/* clear all_ports_up flag if any link down */
diff --git a/examples/ip_reassembly/main.c b/examples/ip_reassembly/main.c
index 494d7ee77..910c89ae3 100644
--- a/examples/ip_reassembly/main.c
+++ b/examples/ip_reassembly/main.c
@@ -712,6 +712,7 @@ check_all_ports_link_status(uint32_t port_mask)
 	uint8_t count, all_ports_up, print_flag = 0;
 	struct rte_eth_link link;
 	int ret;
+	char link_status_text[60];
 
 	printf("\nChecking link status");
 	fflush(stdout);
@@ -731,14 +732,9 @@ check_all_ports_link_status(uint32_t port_mask)
 			}
 			/* print link status if flag set */
 			if (print_flag == 1) {
-				if (link.link_status)
-					printf(
-					"Port%d Link Up. Speed %u Mbps - %s\n",
-						portid, link.link_speed,
-				(link.link_duplex == ETH_LINK_FULL_DUPLEX) ?
-					("full-duplex") : ("half-duplex"));
-				else
-					printf("Port %d Link Down\n", portid);
+				rte_eth_link_strf(link_status_text, 60, NULL,
+						    &link);
+				printf("Port %d %s", portid, link_status_text);
 				continue;
 			}
 			/* clear all_ports_up flag if any link down */
diff --git a/examples/l3fwd-acl/main.c b/examples/l3fwd-acl/main.c
index f22fca732..ddfec9487 100644
--- a/examples/l3fwd-acl/main.c
+++ b/examples/l3fwd-acl/main.c
@@ -1815,6 +1815,7 @@ check_all_ports_link_status(uint32_t port_mask)
 	uint8_t count, all_ports_up, print_flag = 0;
 	struct rte_eth_link link;
 	int ret;
+	char link_status_text[60];
 
 	printf("\nChecking link status");
 	fflush(stdout);
@@ -1834,14 +1835,9 @@ check_all_ports_link_status(uint32_t port_mask)
 			}
 			/* print link status if flag set */
 			if (print_flag == 1) {
-				if (link.link_status)
-					printf(
-					"Port%d Link Up. Speed %u Mbps %s\n",
-						portid, link.link_speed,
-				(link.link_duplex == ETH_LINK_FULL_DUPLEX) ?
-					("full-duplex") : ("half-duplex"));
-				else
-					printf("Port %d Link Down\n", portid);
+				rte_eth_link_strf(link_status_text, 60, NULL,
+						    &link);
+				printf("Port %d %s", portid, link_status_text);
 				continue;
 			}
 			/* clear all_ports_up flag if any link down */
-- 
2.17.1


^ permalink raw reply	[flat|nested] 359+ messages in thread

* [dpdk-dev] [PATCH v6 12/25] examples/ip_pipeline: new link status print format
       [not found]                             ` <CGME20200706203824eucas1p1de6a23263f1d5289d0844cd01b699054@eucas1p1.samsung.com>
@ 2020-07-06 20:37                               ` " Ivan Dyukov
  0 siblings, 0 replies; 359+ messages in thread
From: Ivan Dyukov @ 2020-07-06 20:37 UTC (permalink / raw)
  To: dev, i.dyukov, v.kuramshin, thomas, david.marchand, ferruh.yigit,
	arybchenko, wei.zhao1, jia.guo, beilei.xing, qiming.yang,
	wenzhuo.lu, mb, stephen, nicolas.chautru, bruce.richardson,
	konstantin.ananyev, cristian.dumitrescu, radu.nicolau,
	akhil.goyal, declan.doherty, skori, pbhagavatula, jerinj,
	kirankumark, david.hunt, anatoly.burakov, xiaoyun.li,
	jingjing.wu, john.mcnamara, jasvinder.singh, byron.marohn,
	yipeng1.wang

Add usage of rte_eth_link_strf function to example
applications

Signed-off-by: Ivan Dyukov <i.dyukov@samsung.com>
---
 examples/ip_pipeline/cli.c | 12 +++++++-----
 1 file changed, 7 insertions(+), 5 deletions(-)

diff --git a/examples/ip_pipeline/cli.c b/examples/ip_pipeline/cli.c
index d79699e2e..ca461ea0c 100644
--- a/examples/ip_pipeline/cli.c
+++ b/examples/ip_pipeline/cli.c
@@ -249,7 +249,8 @@ print_link_info(struct link *link, char *out, size_t out_size)
 	struct rte_eth_link eth_link;
 	uint16_t mtu;
 	int ret;
-
+	char link_speed_text[16];
+	char link_status_text[10];
 	memset(&stats, 0, sizeof(stats));
 	rte_eth_stats_get(link->port_id, &stats);
 
@@ -268,18 +269,19 @@ print_link_info(struct link *link, char *out, size_t out_size)
 	}
 
 	rte_eth_dev_get_mtu(link->port_id, &mtu);
-
+	rte_eth_link_strf(link_speed_text, 16, "%M", &eth_link);
+	rte_eth_link_strf(link_status_text, 10, "%S", &eth_link);
 	snprintf(out, out_size,
 		"\n"
 		"%s: flags=<%s> mtu %u\n"
 		"\tether %02X:%02X:%02X:%02X:%02X:%02X rxqueues %u txqueues %u\n"
-		"\tport# %u  speed %u Mbps\n"
+		"\tport# %u  speed %s Mbps\n"
 		"\tRX packets %" PRIu64"  bytes %" PRIu64"\n"
 		"\tRX errors %" PRIu64"  missed %" PRIu64"  no-mbuf %" PRIu64"\n"
 		"\tTX packets %" PRIu64"  bytes %" PRIu64"\n"
 		"\tTX errors %" PRIu64"\n",
 		link->name,
-		eth_link.link_status == 0 ? "DOWN" : "UP",
+		link_status_text,
 		mtu,
 		mac_addr.addr_bytes[0], mac_addr.addr_bytes[1],
 		mac_addr.addr_bytes[2], mac_addr.addr_bytes[3],
@@ -287,7 +289,7 @@ print_link_info(struct link *link, char *out, size_t out_size)
 		link->n_rxq,
 		link->n_txq,
 		link->port_id,
-		eth_link.link_speed,
+		link_speed_text,
 		stats.ipackets,
 		stats.ibytes,
 		stats.ierrors,
-- 
2.17.1


^ permalink raw reply	[flat|nested] 359+ messages in thread

* [dpdk-dev] [PATCH v6 13/25] examples/ipsec-secgw: new link status print format
       [not found]                             ` <CGME20200706203826eucas1p2cdffffa65bd89e363797b2cfb376abff@eucas1p2.samsung.com>
@ 2020-07-06 20:37                               ` " Ivan Dyukov
  0 siblings, 0 replies; 359+ messages in thread
From: Ivan Dyukov @ 2020-07-06 20:37 UTC (permalink / raw)
  To: dev, i.dyukov, v.kuramshin, thomas, david.marchand, ferruh.yigit,
	arybchenko, wei.zhao1, jia.guo, beilei.xing, qiming.yang,
	wenzhuo.lu, mb, stephen, nicolas.chautru, bruce.richardson,
	konstantin.ananyev, cristian.dumitrescu, radu.nicolau,
	akhil.goyal, declan.doherty, skori, pbhagavatula, jerinj,
	kirankumark, david.hunt, anatoly.burakov, xiaoyun.li,
	jingjing.wu, john.mcnamara, jasvinder.singh, byron.marohn,
	yipeng1.wang

Add usage of rte_eth_link_strf function to example
applications

Signed-off-by: Ivan Dyukov <i.dyukov@samsung.com>
---
 examples/ipsec-secgw/ipsec-secgw.c | 12 ++++--------
 1 file changed, 4 insertions(+), 8 deletions(-)

diff --git a/examples/ipsec-secgw/ipsec-secgw.c b/examples/ipsec-secgw/ipsec-secgw.c
index f777ce2af..551838229 100644
--- a/examples/ipsec-secgw/ipsec-secgw.c
+++ b/examples/ipsec-secgw/ipsec-secgw.c
@@ -1775,6 +1775,7 @@ check_all_ports_link_status(uint32_t port_mask)
 	uint8_t count, all_ports_up, print_flag = 0;
 	struct rte_eth_link link;
 	int ret;
+	char link_status_text[60];
 
 	printf("\nChecking link status");
 	fflush(stdout);
@@ -1794,14 +1795,9 @@ check_all_ports_link_status(uint32_t port_mask)
 			}
 			/* print link status if flag set */
 			if (print_flag == 1) {
-				if (link.link_status)
-					printf(
-					"Port%d Link Up - speed %u Mbps -%s\n",
-						portid, link.link_speed,
-				(link.link_duplex == ETH_LINK_FULL_DUPLEX) ?
-					("full-duplex") : ("half-duplex"));
-				else
-					printf("Port %d Link Down\n", portid);
+				rte_eth_link_strf(link_status_text, 60, NULL,
+						    &link);
+				printf("Port %d %s", portid, link_status_text);
 				continue;
 			}
 			/* clear all_ports_up flag if any link down */
-- 
2.17.1


^ permalink raw reply	[flat|nested] 359+ messages in thread

* [dpdk-dev] [PATCH v6 14/25] examples/kni: new link status print format
       [not found]                             ` <CGME20200706203829eucas1p287744dd5ed850265d94669971a98abab@eucas1p2.samsung.com>
@ 2020-07-06 20:37                               ` " Ivan Dyukov
  0 siblings, 0 replies; 359+ messages in thread
From: Ivan Dyukov @ 2020-07-06 20:37 UTC (permalink / raw)
  To: dev, i.dyukov, v.kuramshin, thomas, david.marchand, ferruh.yigit,
	arybchenko, wei.zhao1, jia.guo, beilei.xing, qiming.yang,
	wenzhuo.lu, mb, stephen, nicolas.chautru, bruce.richardson,
	konstantin.ananyev, cristian.dumitrescu, radu.nicolau,
	akhil.goyal, declan.doherty, skori, pbhagavatula, jerinj,
	kirankumark, david.hunt, anatoly.burakov, xiaoyun.li,
	jingjing.wu, john.mcnamara, jasvinder.singh, byron.marohn,
	yipeng1.wang

Add usage of rte_eth_link_strf function to example
applications

Signed-off-by: Ivan Dyukov <i.dyukov@samsung.com>
---
 examples/kni/main.c | 26 +++++++++-----------------
 1 file changed, 9 insertions(+), 17 deletions(-)

diff --git a/examples/kni/main.c b/examples/kni/main.c
index f5d12a5b8..8ad7fb532 100644
--- a/examples/kni/main.c
+++ b/examples/kni/main.c
@@ -661,6 +661,7 @@ check_all_ports_link_status(uint32_t port_mask)
 	uint8_t count, all_ports_up, print_flag = 0;
 	struct rte_eth_link link;
 	int ret;
+	char link_status_text[60];
 
 	printf("\nChecking link status\n");
 	fflush(stdout);
@@ -680,14 +681,9 @@ check_all_ports_link_status(uint32_t port_mask)
 			}
 			/* print link status if flag set */
 			if (print_flag == 1) {
-				if (link.link_status)
-					printf(
-					"Port%d Link Up - speed %uMbps - %s\n",
-						portid, link.link_speed,
-				(link.link_duplex == ETH_LINK_FULL_DUPLEX) ?
-					("full-duplex") : ("half-duplex"));
-				else
-					printf("Port %d Link Down\n", portid);
+				rte_eth_link_strf(link_status_text, 60, NULL,
+						    &link);
+				printf("Port %d %s", portid, link_status_text);
 				continue;
 			}
 			/* clear all_ports_up flag if any link down */
@@ -717,19 +713,15 @@ check_all_ports_link_status(uint32_t port_mask)
 static void
 log_link_state(struct rte_kni *kni, int prev, struct rte_eth_link *link)
 {
+	char link_status_text[60];
 	if (kni == NULL || link == NULL)
 		return;
 
-	if (prev == ETH_LINK_DOWN && link->link_status == ETH_LINK_UP) {
-		RTE_LOG(INFO, APP, "%s NIC Link is Up %d Mbps %s %s.\n",
+	rte_eth_link_strf(link_status_text, 60, NULL, link);
+	if (prev != link->link_status)
+		RTE_LOG(INFO, APP, "%s NIC %s",
 			rte_kni_get_name(kni),
-			link->link_speed,
-			link->link_autoneg ?  "(AutoNeg)" : "(Fixed)",
-			link->link_duplex ?  "Full Duplex" : "Half Duplex");
-	} else if (prev == ETH_LINK_UP && link->link_status == ETH_LINK_DOWN) {
-		RTE_LOG(INFO, APP, "%s NIC Link is Down.\n",
-			rte_kni_get_name(kni));
-	}
+			link_status_text);
 }
 
 /*
-- 
2.17.1


^ permalink raw reply	[flat|nested] 359+ messages in thread

* [dpdk-dev] [PATCH v6 15/25] examples/l2fwd-crypt: new link status print format
       [not found]                             ` <CGME20200706203832eucas1p2e73d9cadd71c3c3bf564b80e75ea8e75@eucas1p2.samsung.com>
@ 2020-07-06 20:37                               ` " Ivan Dyukov
  0 siblings, 0 replies; 359+ messages in thread
From: Ivan Dyukov @ 2020-07-06 20:37 UTC (permalink / raw)
  To: dev, i.dyukov, v.kuramshin, thomas, david.marchand, ferruh.yigit,
	arybchenko, wei.zhao1, jia.guo, beilei.xing, qiming.yang,
	wenzhuo.lu, mb, stephen, nicolas.chautru, bruce.richardson,
	konstantin.ananyev, cristian.dumitrescu, radu.nicolau,
	akhil.goyal, declan.doherty, skori, pbhagavatula, jerinj,
	kirankumark, david.hunt, anatoly.burakov, xiaoyun.li,
	jingjing.wu, john.mcnamara, jasvinder.singh, byron.marohn,
	yipeng1.wang

Add usage of rte_eth_link_strf function to example
applications

Signed-off-by: Ivan Dyukov <i.dyukov@samsung.com>
---
 examples/l2fwd-crypto/main.c | 12 ++++--------
 1 file changed, 4 insertions(+), 8 deletions(-)

diff --git a/examples/l2fwd-crypto/main.c b/examples/l2fwd-crypto/main.c
index 827da9b3e..7648ea027 100644
--- a/examples/l2fwd-crypto/main.c
+++ b/examples/l2fwd-crypto/main.c
@@ -1734,6 +1734,7 @@ check_all_ports_link_status(uint32_t port_mask)
 	uint8_t count, all_ports_up, print_flag = 0;
 	struct rte_eth_link link;
 	int ret;
+	char link_status_text[60];
 
 	printf("\nChecking link status");
 	fflush(stdout);
@@ -1753,14 +1754,9 @@ check_all_ports_link_status(uint32_t port_mask)
 			}
 			/* print link status if flag set */
 			if (print_flag == 1) {
-				if (link.link_status)
-					printf(
-					"Port%d Link Up. Speed %u Mbps - %s\n",
-						portid, link.link_speed,
-				(link.link_duplex == ETH_LINK_FULL_DUPLEX) ?
-					("full-duplex") : ("half-duplex"));
-				else
-					printf("Port %d Link Down\n", portid);
+				rte_eth_link_strf(link_status_text, 60, NULL,
+						    &link);
+				printf("Port %d %s", portid, link_status_text);
 				continue;
 			}
 			/* clear all_ports_up flag if any link down */
-- 
2.17.1


^ permalink raw reply	[flat|nested] 359+ messages in thread

* [dpdk-dev] [PATCH v6 16/25] examples/l2fwd-event: new link status print format
       [not found]                             ` <CGME20200706203835eucas1p1ec5020cd607b45703a3b41144182d52c@eucas1p1.samsung.com>
@ 2020-07-06 20:37                               ` " Ivan Dyukov
  0 siblings, 0 replies; 359+ messages in thread
From: Ivan Dyukov @ 2020-07-06 20:37 UTC (permalink / raw)
  To: dev, i.dyukov, v.kuramshin, thomas, david.marchand, ferruh.yigit,
	arybchenko, wei.zhao1, jia.guo, beilei.xing, qiming.yang,
	wenzhuo.lu, mb, stephen, nicolas.chautru, bruce.richardson,
	konstantin.ananyev, cristian.dumitrescu, radu.nicolau,
	akhil.goyal, declan.doherty, skori, pbhagavatula, jerinj,
	kirankumark, david.hunt, anatoly.burakov, xiaoyun.li,
	jingjing.wu, john.mcnamara, jasvinder.singh, byron.marohn,
	yipeng1.wang

Add usage of rte_eth_link_strf function to example
applications

Signed-off-by: Ivan Dyukov <i.dyukov@samsung.com>
---
 examples/l2fwd-event/main.c | 12 ++++--------
 1 file changed, 4 insertions(+), 8 deletions(-)

diff --git a/examples/l2fwd-event/main.c b/examples/l2fwd-event/main.c
index 4fe500333..3e6d1c311 100644
--- a/examples/l2fwd-event/main.c
+++ b/examples/l2fwd-event/main.c
@@ -366,6 +366,7 @@ check_all_ports_link_status(struct l2fwd_resources *rsrc,
 	uint8_t count, all_ports_up, print_flag = 0;
 	struct rte_eth_link link;
 	int ret;
+	char link_status_text[60];
 
 	printf("\nChecking link status...");
 	fflush(stdout);
@@ -389,14 +390,9 @@ check_all_ports_link_status(struct l2fwd_resources *rsrc,
 			}
 			/* print link status if flag set */
 			if (print_flag == 1) {
-				if (link.link_status)
-					printf(
-					"Port%d Link Up. Speed %u Mbps - %s\n",
-						port_id, link.link_speed,
-				(link.link_duplex == ETH_LINK_FULL_DUPLEX) ?
-					("full-duplex") : ("half-duplex"));
-				else
-					printf("Port %d Link Down\n", port_id);
+				rte_eth_link_strf(link_status_text, 60, NULL,
+						    &link);
+				printf("Port %d %s", port_id, link_status_text);
 				continue;
 			}
 			/* clear all_ports_up flag if any link down */
-- 
2.17.1


^ permalink raw reply	[flat|nested] 359+ messages in thread

* [dpdk-dev] [PATCH v6 17/25] examples/l2fwd: new link status print format
       [not found]                             ` <CGME20200706203838eucas1p25a3b38dc4c1a04f7c15f76f190dff8a2@eucas1p2.samsung.com>
@ 2020-07-06 20:37                               ` " Ivan Dyukov
  0 siblings, 0 replies; 359+ messages in thread
From: Ivan Dyukov @ 2020-07-06 20:37 UTC (permalink / raw)
  To: dev, i.dyukov, v.kuramshin, thomas, david.marchand, ferruh.yigit,
	arybchenko, wei.zhao1, jia.guo, beilei.xing, qiming.yang,
	wenzhuo.lu, mb, stephen, nicolas.chautru, bruce.richardson,
	konstantin.ananyev, cristian.dumitrescu, radu.nicolau,
	akhil.goyal, declan.doherty, skori, pbhagavatula, jerinj,
	kirankumark, david.hunt, anatoly.burakov, xiaoyun.li,
	jingjing.wu, john.mcnamara, jasvinder.singh, byron.marohn,
	yipeng1.wang

Add usage of rte_eth_link_strf function to example
applications

Signed-off-by: Ivan Dyukov <i.dyukov@samsung.com>
---
 examples/l2fwd/main.c | 12 ++++--------
 1 file changed, 4 insertions(+), 8 deletions(-)

diff --git a/examples/l2fwd/main.c b/examples/l2fwd/main.c
index e04c601b5..9d5f7307e 100644
--- a/examples/l2fwd/main.c
+++ b/examples/l2fwd/main.c
@@ -571,6 +571,7 @@ check_all_ports_link_status(uint32_t port_mask)
 	uint8_t count, all_ports_up, print_flag = 0;
 	struct rte_eth_link link;
 	int ret;
+	char link_status_text[60];
 
 	printf("\nChecking link status");
 	fflush(stdout);
@@ -594,14 +595,9 @@ check_all_ports_link_status(uint32_t port_mask)
 			}
 			/* print link status if flag set */
 			if (print_flag == 1) {
-				if (link.link_status)
-					printf(
-					"Port%d Link Up. Speed %u Mbps - %s\n",
-						portid, link.link_speed,
-				(link.link_duplex == ETH_LINK_FULL_DUPLEX) ?
-					("full-duplex") : ("half-duplex"));
-				else
-					printf("Port %d Link Down\n", portid);
+				rte_eth_link_strf(link_status_text, 60, NULL,
+						    &link);
+				printf("Port %d %s", portid, link_status_text);
 				continue;
 			}
 			/* clear all_ports_up flag if any link down */
-- 
2.17.1


^ permalink raw reply	[flat|nested] 359+ messages in thread

* [dpdk-dev] [PATCH v6 18/25] examples/l3fwd-graph: new link status print format
       [not found]                             ` <CGME20200706203840eucas1p2366ef5cffa8f367969343fe9240cd919@eucas1p2.samsung.com>
@ 2020-07-06 20:37                               ` " Ivan Dyukov
  0 siblings, 0 replies; 359+ messages in thread
From: Ivan Dyukov @ 2020-07-06 20:37 UTC (permalink / raw)
  To: dev, i.dyukov, v.kuramshin, thomas, david.marchand, ferruh.yigit,
	arybchenko, wei.zhao1, jia.guo, beilei.xing, qiming.yang,
	wenzhuo.lu, mb, stephen, nicolas.chautru, bruce.richardson,
	konstantin.ananyev, cristian.dumitrescu, radu.nicolau,
	akhil.goyal, declan.doherty, skori, pbhagavatula, jerinj,
	kirankumark, david.hunt, anatoly.burakov, xiaoyun.li,
	jingjing.wu, john.mcnamara, jasvinder.singh, byron.marohn,
	yipeng1.wang

Add usage of rte_eth_link_strf function to example
applications

Signed-off-by: Ivan Dyukov <i.dyukov@samsung.com>
---
 examples/l3fwd-graph/main.c | 14 ++++----------
 1 file changed, 4 insertions(+), 10 deletions(-)

diff --git a/examples/l3fwd-graph/main.c b/examples/l3fwd-graph/main.c
index c70270c4d..cd8e3aad1 100644
--- a/examples/l3fwd-graph/main.c
+++ b/examples/l3fwd-graph/main.c
@@ -599,6 +599,7 @@ check_all_ports_link_status(uint32_t port_mask)
 	struct rte_eth_link link;
 	uint16_t portid;
 	int ret;
+	char link_status_text[60];
 
 	printf("\nChecking link status");
 	fflush(stdout);
@@ -623,16 +624,9 @@ check_all_ports_link_status(uint32_t port_mask)
 			}
 			/* Print link status if flag set */
 			if (print_flag == 1) {
-				if (link.link_status)
-					printf("Port%d Link Up. Speed %u Mbps "
-					       "-%s\n",
-					       portid, link.link_speed,
-					       (link.link_duplex ==
-						ETH_LINK_FULL_DUPLEX)
-						       ? ("full-duplex")
-						       : ("half-duplex\n"));
-				else
-					printf("Port %d Link Down\n", portid);
+				rte_eth_link_strf(link_status_text, 60, NULL,
+						    &link);
+				printf("Port %d %s", portid, link_status_text);
 				continue;
 			}
 			/* Clear all_ports_up flag if any link down */
-- 
2.17.1


^ permalink raw reply	[flat|nested] 359+ messages in thread

* [dpdk-dev] [PATCH v6 19/25] examples/l3fwd-power: new link status print format
       [not found]                             ` <CGME20200706203843eucas1p2207dc76350211e49c4b81af097499c8a@eucas1p2.samsung.com>
@ 2020-07-06 20:37                               ` " Ivan Dyukov
  0 siblings, 0 replies; 359+ messages in thread
From: Ivan Dyukov @ 2020-07-06 20:37 UTC (permalink / raw)
  To: dev, i.dyukov, v.kuramshin, thomas, david.marchand, ferruh.yigit,
	arybchenko, wei.zhao1, jia.guo, beilei.xing, qiming.yang,
	wenzhuo.lu, mb, stephen, nicolas.chautru, bruce.richardson,
	konstantin.ananyev, cristian.dumitrescu, radu.nicolau,
	akhil.goyal, declan.doherty, skori, pbhagavatula, jerinj,
	kirankumark, david.hunt, anatoly.burakov, xiaoyun.li,
	jingjing.wu, john.mcnamara, jasvinder.singh, byron.marohn,
	yipeng1.wang

Add usage of rte_eth_link_strf function to example
applications

Signed-off-by: Ivan Dyukov <i.dyukov@samsung.com>
---
 examples/l3fwd-power/main.c | 13 ++++---------
 1 file changed, 4 insertions(+), 9 deletions(-)

diff --git a/examples/l3fwd-power/main.c b/examples/l3fwd-power/main.c
index 9db94ce04..ba6bab4a5 100644
--- a/examples/l3fwd-power/main.c
+++ b/examples/l3fwd-power/main.c
@@ -1945,6 +1945,7 @@ check_all_ports_link_status(uint32_t port_mask)
 	uint16_t portid;
 	struct rte_eth_link link;
 	int ret;
+	char link_status_text[60];
 
 	printf("\nChecking link status");
 	fflush(stdout);
@@ -1964,15 +1965,9 @@ check_all_ports_link_status(uint32_t port_mask)
 			}
 			/* print link status if flag set */
 			if (print_flag == 1) {
-				if (link.link_status)
-					printf("Port %d Link Up - speed %u "
-						"Mbps - %s\n", (uint8_t)portid,
-						(unsigned)link.link_speed,
-				(link.link_duplex == ETH_LINK_FULL_DUPLEX) ?
-					("full-duplex") : ("half-duplex"));
-				else
-					printf("Port %d Link Down\n",
-						(uint8_t)portid);
+				rte_eth_link_strf(link_status_text, 60, NULL,
+						    &link);
+				printf("Port %d %s", portid, link_status_text);
 				continue;
 			}
 			/* clear all_ports_up flag if any link down */
-- 
2.17.1


^ permalink raw reply	[flat|nested] 359+ messages in thread

* [dpdk-dev] [PATCH v6 20/25] examples/multi_proc*: new link status print format
       [not found]                             ` <CGME20200706203846eucas1p21bbcbf41b435e8fcb0ef75aa0d0c2b82@eucas1p2.samsung.com>
@ 2020-07-06 20:37                               ` " Ivan Dyukov
  0 siblings, 0 replies; 359+ messages in thread
From: Ivan Dyukov @ 2020-07-06 20:37 UTC (permalink / raw)
  To: dev, i.dyukov, v.kuramshin, thomas, david.marchand, ferruh.yigit,
	arybchenko, wei.zhao1, jia.guo, beilei.xing, qiming.yang,
	wenzhuo.lu, mb, stephen, nicolas.chautru, bruce.richardson,
	konstantin.ananyev, cristian.dumitrescu, radu.nicolau,
	akhil.goyal, declan.doherty, skori, pbhagavatula, jerinj,
	kirankumark, david.hunt, anatoly.burakov, xiaoyun.li,
	jingjing.wu, john.mcnamara, jasvinder.singh, byron.marohn,
	yipeng1.wang

Add usage of rte_eth_link_strf function to example
applications

Signed-off-by: Ivan Dyukov <i.dyukov@samsung.com>
---
 .../client_server_mp/mp_server/init.c              | 14 +++++---------
 examples/multi_process/symmetric_mp/main.c         | 12 ++++--------
 2 files changed, 9 insertions(+), 17 deletions(-)

diff --git a/examples/multi_process/client_server_mp/mp_server/init.c b/examples/multi_process/client_server_mp/mp_server/init.c
index c2ec07ac6..3ca9bcae3 100644
--- a/examples/multi_process/client_server_mp/mp_server/init.c
+++ b/examples/multi_process/client_server_mp/mp_server/init.c
@@ -185,6 +185,7 @@ check_all_ports_link_status(uint16_t port_num, uint32_t port_mask)
 	uint8_t count, all_ports_up, print_flag = 0;
 	struct rte_eth_link link;
 	int ret;
+	char link_status_text[60];
 
 	printf("\nChecking link status");
 	fflush(stdout);
@@ -204,15 +205,10 @@ check_all_ports_link_status(uint16_t port_num, uint32_t port_mask)
 			}
 			/* print link status if flag set */
 			if (print_flag == 1) {
-				if (link.link_status)
-					printf("Port %d Link Up - speed %u "
-						"Mbps - %s\n", ports->id[portid],
-						(unsigned)link.link_speed,
-				(link.link_duplex == ETH_LINK_FULL_DUPLEX) ?
-					("full-duplex") : ("half-duplex"));
-				else
-					printf("Port %d Link Down\n",
-						(uint8_t)ports->id[portid]);
+				rte_eth_link_strf(link_status_text, 60, NULL,
+						    &link);
+				printf("Port %d %s", (uint8_t)ports->id[portid],
+				       link_status_text);
 				continue;
 			}
 			/* clear all_ports_up flag if any link down */
diff --git a/examples/multi_process/symmetric_mp/main.c b/examples/multi_process/symmetric_mp/main.c
index 9a16e198c..0480874f8 100644
--- a/examples/multi_process/symmetric_mp/main.c
+++ b/examples/multi_process/symmetric_mp/main.c
@@ -365,6 +365,7 @@ check_all_ports_link_status(uint16_t port_num, uint32_t port_mask)
 	uint8_t count, all_ports_up, print_flag = 0;
 	struct rte_eth_link link;
 	int ret;
+	char link_status_text[60];
 
 	printf("\nChecking link status");
 	fflush(stdout);
@@ -384,14 +385,9 @@ check_all_ports_link_status(uint16_t port_num, uint32_t port_mask)
 			}
 			/* print link status if flag set */
 			if (print_flag == 1) {
-				if (link.link_status)
-					printf(
-					"Port%d Link Up. Speed %u Mbps - %s\n",
-						portid, link.link_speed,
-				(link.link_duplex == ETH_LINK_FULL_DUPLEX) ?
-					("full-duplex") : ("half-duplex"));
-				else
-					printf("Port %d Link Down\n", portid);
+				rte_eth_link_strf(link_status_text, 60, NULL,
+						    &link);
+				printf("Port %d %s", portid, link_status_text);
 				continue;
 			}
 			/* clear all_ports_up flag if any link down */
-- 
2.17.1


^ permalink raw reply	[flat|nested] 359+ messages in thread

* [dpdk-dev] [PATCH v6 21/25] examples/ntb: new link status print format
       [not found]                             ` <CGME20200706203849eucas1p2b573ab867439ead5c864cc7638649079@eucas1p2.samsung.com>
@ 2020-07-06 20:37                               ` " Ivan Dyukov
  0 siblings, 0 replies; 359+ messages in thread
From: Ivan Dyukov @ 2020-07-06 20:37 UTC (permalink / raw)
  To: dev, i.dyukov, v.kuramshin, thomas, david.marchand, ferruh.yigit,
	arybchenko, wei.zhao1, jia.guo, beilei.xing, qiming.yang,
	wenzhuo.lu, mb, stephen, nicolas.chautru, bruce.richardson,
	konstantin.ananyev, cristian.dumitrescu, radu.nicolau,
	akhil.goyal, declan.doherty, skori, pbhagavatula, jerinj,
	kirankumark, david.hunt, anatoly.burakov, xiaoyun.li,
	jingjing.wu, john.mcnamara, jasvinder.singh, byron.marohn,
	yipeng1.wang

Add usage of rte_eth_link_strf function to example
applications

Signed-off-by: Ivan Dyukov <i.dyukov@samsung.com>
---
 examples/ntb/ntb_fwd.c | 10 +++++-----
 1 file changed, 5 insertions(+), 5 deletions(-)

diff --git a/examples/ntb/ntb_fwd.c b/examples/ntb/ntb_fwd.c
index eba8ebf9f..84fe374c4 100644
--- a/examples/ntb/ntb_fwd.c
+++ b/examples/ntb/ntb_fwd.c
@@ -729,6 +729,7 @@ start_pkt_fwd(void)
 	struct rte_eth_link eth_link;
 	uint32_t lcore_id;
 	int ret, i;
+	char link_status_text[60];
 
 	ret = ntb_fwd_config_setup();
 	if (ret < 0) {
@@ -747,11 +748,10 @@ start_pkt_fwd(void)
 				return;
 			}
 			if (eth_link.link_status) {
-				printf("Eth%u Link Up. Speed %u Mbps - %s\n",
-					eth_port_id, eth_link.link_speed,
-					(eth_link.link_duplex ==
-					 ETH_LINK_FULL_DUPLEX) ?
-					("full-duplex") : ("half-duplex"));
+				rte_eth_link_strf(link_status_text, 60, NULL,
+						    &link);
+				printf("Eth%u %s", eth_port_id,
+				       link_status_text);
 				break;
 			}
 		}
-- 
2.17.1


^ permalink raw reply	[flat|nested] 359+ messages in thread

* [dpdk-dev] [PATCH v6 22/25] example/performance*: new link status print format
       [not found]                             ` <CGME20200706203851eucas1p1aeb631663772fc95d1fa11bb1873dbe7@eucas1p1.samsung.com>
@ 2020-07-06 20:37                               ` " Ivan Dyukov
  0 siblings, 0 replies; 359+ messages in thread
From: Ivan Dyukov @ 2020-07-06 20:37 UTC (permalink / raw)
  To: dev, i.dyukov, v.kuramshin, thomas, david.marchand, ferruh.yigit,
	arybchenko, wei.zhao1, jia.guo, beilei.xing, qiming.yang,
	wenzhuo.lu, mb, stephen, nicolas.chautru, bruce.richardson,
	konstantin.ananyev, cristian.dumitrescu, radu.nicolau,
	akhil.goyal, declan.doherty, skori, pbhagavatula, jerinj,
	kirankumark, david.hunt, anatoly.burakov, xiaoyun.li,
	jingjing.wu, john.mcnamara, jasvinder.singh, byron.marohn,
	yipeng1.wang

Add usage of rte_eth_link_strf function to example
applications

Signed-off-by: Ivan Dyukov <i.dyukov@samsung.com>
---
 examples/performance-thread/l3fwd-thread/main.c | 12 ++++--------
 1 file changed, 4 insertions(+), 8 deletions(-)

diff --git a/examples/performance-thread/l3fwd-thread/main.c b/examples/performance-thread/l3fwd-thread/main.c
index 84c1d7b3a..bd10014a0 100644
--- a/examples/performance-thread/l3fwd-thread/main.c
+++ b/examples/performance-thread/l3fwd-thread/main.c
@@ -3433,6 +3433,7 @@ check_all_ports_link_status(uint32_t port_mask)
 	uint8_t count, all_ports_up, print_flag = 0;
 	struct rte_eth_link link;
 	int ret;
+	char link_status_text[60];
 
 	printf("\nChecking link status");
 	fflush(stdout);
@@ -3452,14 +3453,9 @@ check_all_ports_link_status(uint32_t port_mask)
 			}
 			/* print link status if flag set */
 			if (print_flag == 1) {
-				if (link.link_status)
-					printf(
-					"Port%d Link Up. Speed %u Mbps - %s\n",
-						portid, link.link_speed,
-				(link.link_duplex == ETH_LINK_FULL_DUPLEX) ?
-					("full-duplex") : ("half-duplex"));
-				else
-					printf("Port %d Link Down\n", portid);
+				rte_eth_link_strf(link_status_text, 60, NULL,
+						    &link);
+				printf("Port %d %s", portid, link_status_text);
 				continue;
 			}
 			/* clear all_ports_up flag if any link down */
-- 
2.17.1


^ permalink raw reply	[flat|nested] 359+ messages in thread

* [dpdk-dev] [PATCH v6 23/25] examples/qos_sched: new link status print format
       [not found]                             ` <CGME20200706203854eucas1p190bd0852cecbbede8423d6efa7bf554a@eucas1p1.samsung.com>
@ 2020-07-06 20:37                               ` " Ivan Dyukov
  0 siblings, 0 replies; 359+ messages in thread
From: Ivan Dyukov @ 2020-07-06 20:37 UTC (permalink / raw)
  To: dev, i.dyukov, v.kuramshin, thomas, david.marchand, ferruh.yigit,
	arybchenko, wei.zhao1, jia.guo, beilei.xing, qiming.yang,
	wenzhuo.lu, mb, stephen, nicolas.chautru, bruce.richardson,
	konstantin.ananyev, cristian.dumitrescu, radu.nicolau,
	akhil.goyal, declan.doherty, skori, pbhagavatula, jerinj,
	kirankumark, david.hunt, anatoly.burakov, xiaoyun.li,
	jingjing.wu, john.mcnamara, jasvinder.singh, byron.marohn,
	yipeng1.wang

Add usage of rte_eth_link_strf function to example
applications

Signed-off-by: Ivan Dyukov <i.dyukov@samsung.com>
---
 examples/qos_sched/init.c | 10 ++--------
 1 file changed, 2 insertions(+), 8 deletions(-)

diff --git a/examples/qos_sched/init.c b/examples/qos_sched/init.c
index 9626c15b8..4bb975fc9 100644
--- a/examples/qos_sched/init.c
+++ b/examples/qos_sched/init.c
@@ -160,14 +160,8 @@ app_init_port(uint16_t portid, struct rte_mempool *mp)
 			 "rte_eth_link_get: err=%d, port=%u: %s\n",
 			 ret, portid, rte_strerror(-ret));
 
-	if (link.link_status) {
-		printf(" Link Up - speed %u Mbps - %s\n",
-			(uint32_t) link.link_speed,
-			(link.link_duplex == ETH_LINK_FULL_DUPLEX) ?
-			("full-duplex") : ("half-duplex"));
-	} else {
-		printf(" Link Down\n");
-	}
+	rte_eth_link_printf(NULL, &link);
+
 	ret = rte_eth_promiscuous_enable(portid);
 	if (ret != 0)
 		rte_exit(EXIT_FAILURE,
-- 
2.17.1


^ permalink raw reply	[flat|nested] 359+ messages in thread

* [dpdk-dev] [PATCH v6 24/25] examples/server_nod*: new link status print format
       [not found]                             ` <CGME20200706203857eucas1p1b97d37ca61cda22ff7e93e08e1e01fbe@eucas1p1.samsung.com>
@ 2020-07-06 20:37                               ` " Ivan Dyukov
  0 siblings, 0 replies; 359+ messages in thread
From: Ivan Dyukov @ 2020-07-06 20:37 UTC (permalink / raw)
  To: dev, i.dyukov, v.kuramshin, thomas, david.marchand, ferruh.yigit,
	arybchenko, wei.zhao1, jia.guo, beilei.xing, qiming.yang,
	wenzhuo.lu, mb, stephen, nicolas.chautru, bruce.richardson,
	konstantin.ananyev, cristian.dumitrescu, radu.nicolau,
	akhil.goyal, declan.doherty, skori, pbhagavatula, jerinj,
	kirankumark, david.hunt, anatoly.burakov, xiaoyun.li,
	jingjing.wu, john.mcnamara, jasvinder.singh, byron.marohn,
	yipeng1.wang

Add usage of rte_eth_link_strf function to example
applications

Signed-off-by: Ivan Dyukov <i.dyukov@samsung.com>
---
 examples/server_node_efd/server/init.c | 15 +++++----------
 1 file changed, 5 insertions(+), 10 deletions(-)

diff --git a/examples/server_node_efd/server/init.c b/examples/server_node_efd/server/init.c
index 378a74fa5..00224850e 100644
--- a/examples/server_node_efd/server/init.c
+++ b/examples/server_node_efd/server/init.c
@@ -247,6 +247,7 @@ check_all_ports_link_status(uint16_t port_num, uint32_t port_mask)
 	uint16_t portid;
 	struct rte_eth_link link;
 	int ret;
+	char link_status_text[60];
 
 	printf("\nChecking link status");
 	fflush(stdout);
@@ -266,16 +267,10 @@ check_all_ports_link_status(uint16_t port_num, uint32_t port_mask)
 			}
 			/* print link status if flag set */
 			if (print_flag == 1) {
-				if (link.link_status)
-					printf(
-					"Port%d Link Up. Speed %u Mbps - %s\n",
-						info->id[portid],
-						link.link_speed,
-				(link.link_duplex == ETH_LINK_FULL_DUPLEX) ?
-					("full-duplex") : ("half-duplex"));
-				else
-					printf("Port %d Link Down\n",
-						info->id[portid]);
+				rte_eth_link_strf(link_status_text, 60, NULL,
+						    &link);
+				printf("Port %d %s", info->id[portid],
+				       link_status_text);
 				continue;
 			}
 			/* clear all_ports_up flag if any link down */
-- 
2.17.1


^ permalink raw reply	[flat|nested] 359+ messages in thread

* [dpdk-dev] [PATCH v6 25/25] examples/vm_power_*: new link status print format
       [not found]                             ` <CGME20200706203900eucas1p1da635a7b8512d7c087ea0def6de3223d@eucas1p1.samsung.com>
@ 2020-07-06 20:37                               ` " Ivan Dyukov
  0 siblings, 0 replies; 359+ messages in thread
From: Ivan Dyukov @ 2020-07-06 20:37 UTC (permalink / raw)
  To: dev, i.dyukov, v.kuramshin, thomas, david.marchand, ferruh.yigit,
	arybchenko, wei.zhao1, jia.guo, beilei.xing, qiming.yang,
	wenzhuo.lu, mb, stephen, nicolas.chautru, bruce.richardson,
	konstantin.ananyev, cristian.dumitrescu, radu.nicolau,
	akhil.goyal, declan.doherty, skori, pbhagavatula, jerinj,
	kirankumark, david.hunt, anatoly.burakov, xiaoyun.li,
	jingjing.wu, john.mcnamara, jasvinder.singh, byron.marohn,
	yipeng1.wang

Add usage of rte_eth_link_strf function to example
applications

Signed-off-by: Ivan Dyukov <i.dyukov@samsung.com>
---
 examples/vm_power_manager/main.c | 14 +++++---------
 1 file changed, 5 insertions(+), 9 deletions(-)

diff --git a/examples/vm_power_manager/main.c b/examples/vm_power_manager/main.c
index 273bfec29..05aec1aad 100644
--- a/examples/vm_power_manager/main.c
+++ b/examples/vm_power_manager/main.c
@@ -244,6 +244,7 @@ check_all_ports_link_status(uint32_t port_mask)
 	uint16_t portid, count, all_ports_up, print_flag = 0;
 	struct rte_eth_link link;
 	int ret;
+	char link_status_text[60];
 
 	printf("\nChecking link status");
 	fflush(stdout);
@@ -267,15 +268,10 @@ check_all_ports_link_status(uint32_t port_mask)
 			}
 			/* print link status if flag set */
 			if (print_flag == 1) {
-				if (link.link_status)
-					printf("Port %d Link Up - speed %u "
-						"Mbps - %s\n", (uint16_t)portid,
-						(unsigned int)link.link_speed,
-				(link.link_duplex == ETH_LINK_FULL_DUPLEX) ?
-					("full-duplex") : ("half-duplex"));
-				else
-					printf("Port %d Link Down\n",
-						(uint16_t)portid);
+				rte_eth_link_strf(link_status_text, 60, NULL,
+						    &link);
+				printf("Port %d %s", portid,
+				       link_status_text);
 				continue;
 			}
 		       /* clear all_ports_up flag if any link down */
-- 
2.17.1


^ permalink raw reply	[flat|nested] 359+ messages in thread

* Re: [dpdk-dev] [PATCH v6 02/25] ethdev: add a link status text representation
  2020-07-06 20:37                               ` [dpdk-dev] [PATCH v6 02/25] ethdev: add a link status text representation Ivan Dyukov
@ 2020-07-06 21:24                                 ` Stephen Hemminger
  2020-07-06 21:30                                 ` Stephen Hemminger
  1 sibling, 0 replies; 359+ messages in thread
From: Stephen Hemminger @ 2020-07-06 21:24 UTC (permalink / raw)
  To: Ivan Dyukov
  Cc: dev, v.kuramshin, thomas, david.marchand, ferruh.yigit,
	arybchenko, wei.zhao1, jia.guo, beilei.xing, qiming.yang,
	wenzhuo.lu, mb, nicolas.chautru, bruce.richardson,
	konstantin.ananyev, cristian.dumitrescu, radu.nicolau,
	akhil.goyal, declan.doherty, skori, pbhagavatula, jerinj,
	kirankumark, david.hunt, anatoly.burakov, xiaoyun.li,
	jingjing.wu, john.mcnamara, jasvinder.singh, byron.marohn,
	yipeng1.wang

On Mon,  6 Jul 2020 23:37:16 +0300
Ivan Dyukov <i.dyukov@samsung.com> wrote:

> static int
> +rte_eth_link_strf_parser(char *str, size_t len, const char *const fmt,
> +			   struct rte_eth_link *link)

The link arg should be const.

> +{
> +	size_t offset = 0;
> +	const char *fmt_cur = fmt;
> +	char *str_cur = str;
> +	double gbits = (double)link->link_speed / 1000.;
> +	static const char AUTONEG_STR[]       = "Autoneg";
> +	static const char FIXED_STR[]         = "Fixed";
> +	static const char FDX_STR[]           = "FDX";
> +	static const char HDX_STR[]           = "HDX";
> +	static const char UNKNOWN_STR[]       = "Unknown";
> +	static const char UP_STR[]            = "Up";
> +	static const char DOWN_STR[]          = "Down";

Why are these UPPER_CASE_CONSTANTS? That does not match DPDK style.
> +
> +	char gbits_str[20];
> +	char mbits_str[20];
> +	/* preformat complex formatting to easily concatinate it further */

Blank line between declaration and code.
> +	snprintf(mbits_str, 20, "%u", link->link_speed);
> +	snprintf(gbits_str, 20, "%.1f", gbits);

Use sizeof(mbits_str) which is safer and matches what youare doing.
> +	/* init str before formatting */
> +	str[0] = 0;
> +	while (*fmt_cur) {
> +		/* check str bounds */
> +		if (offset > (len - 1)) {
> +			str[len - 1] = '\0';
> +			return -1;
> +		}
> +		if (*fmt_cur == '%') {
> +			/* set null terminator to current position,
> +			 * it's required for strlcat
> +			 */
> +			*str_cur = '\0';
> +			switch (*++fmt_cur) {
> +			/* Speed in Mbits/s */
> +			case 'M':
> +				if (link->link_speed ==
> +				    ETH_SPEED_NUM_UNKNOWN)
> +					offset = strlcat(str, UNKNOWN_STR,
> +							 len);
> +				else
> +					offset = strlcat(str, mbits_str, len);
> +				break;
> +			/* Speed in Gbits/s */
> +			case 'G':
> +				if (link->link_speed ==
> +				    ETH_SPEED_NUM_UNKNOWN)
> +					offset = strlcat(str, UNKNOWN_STR,
> +							 len);
> +				else
> +					offset = strlcat(str, gbits_str, len);
> +				break;
> +			/* Link status */
> +			case 'S':
> +				offset = strlcat(str, link->link_status ?
> +					UP_STR : DOWN_STR, len);
> +				break;
> +			/* Link autoneg */
> +			case 'A':
> +				offset = strlcat(str, link->link_autoneg ?
> +					AUTONEG_STR : FIXED_STR, len);
> +				break;
> +			/* Link duplex */
> +			case 'D':
> +				offset = strlcat(str, link->link_duplex ?
> +					FDX_STR : HDX_STR, len);
> +				break;
> +			/* Error cases */
> +			default:
> +				return -1;
> +
> +			}
> +			if (offset > (len - 1))
> +				return -1;
> +
> +			str_cur = str + offset;
> +		} else {
> +			*str_cur++ = *fmt_cur;
> +			offset++;
> +		}
> +		fmt_cur++;
> +	}
> +	*str_cur = '\0';
> +	return offset;
> +}
> +
> +int
> +rte_eth_link_printf(const char *const fmt,
> +		    struct rte_eth_link *link)
> +{
> +	char text[200];
> +	int ret;
> +	ret = rte_eth_link_strf(text, 200, fmt, link);

Blank line tween declaration and code.
> +	if (ret > 0)
> +		printf("%s", text);
> +	return ret;
> +}

^ permalink raw reply	[flat|nested] 359+ messages in thread

* Re: [dpdk-dev] [PATCH v6 03/25] app: UNKNOWN link speed print format
  2020-07-06 20:37                               ` [dpdk-dev] [PATCH v6 03/25] app: UNKNOWN link speed print format Ivan Dyukov
@ 2020-07-06 21:26                                 ` Stephen Hemminger
  0 siblings, 0 replies; 359+ messages in thread
From: Stephen Hemminger @ 2020-07-06 21:26 UTC (permalink / raw)
  To: Ivan Dyukov
  Cc: dev, v.kuramshin, thomas, david.marchand, ferruh.yigit,
	arybchenko, wei.zhao1, jia.guo, beilei.xing, qiming.yang,
	wenzhuo.lu, mb, nicolas.chautru, bruce.richardson,
	konstantin.ananyev, cristian.dumitrescu, radu.nicolau,
	akhil.goyal, declan.doherty, skori, pbhagavatula, jerinj,
	kirankumark, david.hunt, anatoly.burakov, xiaoyun.li,
	jingjing.wu, john.mcnamara, jasvinder.singh, byron.marohn,
	yipeng1.wang

On Mon,  6 Jul 2020 23:37:17 +0300
Ivan Dyukov <i.dyukov@samsung.com> wrote:

> +			rte_eth_link_printf("\t  -- link speed: %M, duplex: %D,"
> +					" auto neg: %A, status: %S\n",

Don't break lines in middle of strings. It makes it hard for users
who are doing grep to look for error messages.

^ permalink raw reply	[flat|nested] 359+ messages in thread

* Re: [dpdk-dev] [PATCH v6 02/25] ethdev: add a link status text representation
  2020-07-06 20:37                               ` [dpdk-dev] [PATCH v6 02/25] ethdev: add a link status text representation Ivan Dyukov
  2020-07-06 21:24                                 ` Stephen Hemminger
@ 2020-07-06 21:30                                 ` Stephen Hemminger
  1 sibling, 0 replies; 359+ messages in thread
From: Stephen Hemminger @ 2020-07-06 21:30 UTC (permalink / raw)
  To: Ivan Dyukov
  Cc: dev, v.kuramshin, thomas, david.marchand, ferruh.yigit,
	arybchenko, wei.zhao1, jia.guo, beilei.xing, qiming.yang,
	wenzhuo.lu, mb, nicolas.chautru, bruce.richardson,
	konstantin.ananyev, cristian.dumitrescu, radu.nicolau,
	akhil.goyal, declan.doherty, skori, pbhagavatula, jerinj,
	kirankumark, david.hunt, anatoly.burakov, xiaoyun.li,
	jingjing.wu, john.mcnamara, jasvinder.singh, byron.marohn,
	yipeng1.wang

On Mon,  6 Jul 2020 23:37:16 +0300
Ivan Dyukov <i.dyukov@samsung.com> wrote:

> +			/* Error cases */
> +			default:
> +				return -1;
> +

Since very little of the code is checking for errors, why return on
bad format. Why not do what printf() does and ignore what is not specified.

Example:

	r = printf("Wierd %W format\n", x);
	printf("returned %d\n", r);

Wierd %W format
returned 16

^ permalink raw reply	[flat|nested] 359+ messages in thread

* [dpdk-dev] [PATCH v7 0/25] ethdev: allow unknown link speed
       [not found]                         ` <CGME20200710070235eucas1p12961d36cdc8abf56f2ab2987fef8276b@eucas1p1.samsung.com>
@ 2020-07-10  7:01                           ` Ivan Dyukov
       [not found]                             ` <CGME20200710070239eucas1p1585ae0ea8e64d3f00e58870d9e133fa1@eucas1p1.samsung.com>
                                               ` (25 more replies)
  0 siblings, 26 replies; 359+ messages in thread
From: Ivan Dyukov @ 2020-07-10  7:01 UTC (permalink / raw)
  To: dev, i.dyukov, v.kuramshin, thomas, david.marchand, ferruh.yigit,
	arybchenko, wei.zhao1, jia.guo, beilei.xing, qiming.yang,
	wenzhuo.lu, mb, stephen, nicolas.chautru, bruce.richardson,
	konstantin.ananyev, cristian.dumitrescu, radu.nicolau,
	akhil.goyal, declan.doherty, skori, pbhagavatula, jerinj,
	kirankumark, david.hunt, anatoly.burakov, xiaoyun.li,
	jingjing.wu, john.mcnamara, jasvinder.singh, byron.marohn,
	yipeng1.wang

MAINTAINERS                                              |   1 +
 app/proc-info/main.c                                     |   9 ++----
 app/test-pipeline/init.c                                 |  11 ++++---
 app/test-pmd/config.c                                    |  20 ++++++++-----
 app/test-pmd/testpmd.c                                   |   9 +-----
 app/test/Makefile                                        |   3 ++
 app/test/meson.build                                     |   2 ++
 app/test/test_ethdev_link.c                              | 278 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 app/test/test_pmd_perf.c                                 |  17 +++++------
 doc/guides/sample_app_ug/link_status_intr.rst            |  10 +++----
 drivers/net/i40e/i40e_ethdev.c                           |   5 +++-
 drivers/net/i40e/i40e_ethdev_vf.c                        |  10 +++----
 drivers/net/ice/ice_ethdev.c                             |   5 +++-
 drivers/net/ixgbe/ixgbe_ethdev.c                         |   6 +---
 examples/bbdev_app/main.c                                |   8 ++---
 examples/ioat/ioatfwd.c                                  |  13 ++++----
 examples/ip_fragmentation/main.c                         |  13 ++++----
 examples/ip_pipeline/cli.c                               |  12 ++++----
 examples/ip_reassembly/main.c                            |  12 +++-----
 examples/ipsec-secgw/ipsec-secgw.c                       |  12 +++-----
 examples/ipv4_multicast/main.c                           |  12 +++-----
 examples/kni/main.c                                      |  26 ++++++----------
 examples/l2fwd-crypto/main.c                             |  12 +++-----
 examples/l2fwd-event/main.c                              |  12 +++-----
 examples/l2fwd-jobstats/main.c                           |  12 +++-----
 examples/l2fwd-keepalive/main.c                          |  12 +++-----
 examples/l2fwd/main.c                                    |  12 +++-----
 examples/l3fwd-acl/main.c                                |  12 +++-----
 examples/l3fwd-graph/main.c                              |  14 +++------
 examples/l3fwd-power/main.c                              |  13 +++-----
 examples/l3fwd/main.c                                    |  12 +++-----
 examples/link_status_interrupt/main.c                    |  30 ++++++++-----------
 examples/multi_process/client_server_mp/mp_server/init.c |  14 ++++-----
 examples/multi_process/symmetric_mp/main.c               |  12 +++-----
 examples/ntb/ntb_fwd.c                                   |  10 +++----
 examples/performance-thread/l3fwd-thread/main.c          |  12 +++-----
 examples/qos_sched/init.c                                |  10 ++-----
 examples/server_node_efd/server/init.c                   |  15 ++++------
 examples/vm_power_manager/main.c                         |  14 ++++-----
 lib/librte_ethdev/rte_ethdev.c                           | 169 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 lib/librte_ethdev/rte_ethdev.h                           |  74 +++++++++++++++++++++++++++++++++++++++-------
 lib/librte_ethdev/rte_ethdev_version.map                 |   4 +++
 42 files changed, 687 insertions(+), 282 deletions(-)

v7 changes:
* fix meson build
* change _strf function. now it does not fails in case of unknown specifiers like %d. it just copy it to target string.
* remove invalid_fmt unit test.
* add unknown specifier test.
* fix codestyle

v6 changes:
* fix spelling in comments according to checkpatch warning

v5 changes:
* rename rte_eth_link_format to rte_eth_link_strf
* add '\n' to default strings
* update remaining examples. patch with subj 'examples: new link status print format' contains examples which have no maintainers.
TBD:
update remaining nic drivers with 'unknown' speed.  It should be provided in separate patchset.

v4 changes:
* refactor rte_eth_link_format using strlcat func instead of snprintf
* added new checks to unit tests
* few minor fixes according review comments
TBD:
update examples in 'example' folder with new status printing mechanism
update remaining nic drivers with 'unknown' speed

v3 changes:
* remove rte_eth_link_prepare_text function
* add rte_eth_link_format and rte_eth_link_printf functions
* added unit tests for rte_eth_link_format function
TBD:
update examples in 'example' folder with new status printing mechanism
update remaining nic drivers with 'unknown' speed

v2 changes:
* add function which format link status to textual representation
* update drivers for Intel nics with 'unknown' speed
TBD:
update examples in 'example' folder with new status printing mechanism
update remaining nic drivers with 'unknown' speed

v1 changes:
This is initial patchset which introduces UNKNOWN speed to dpdk
applications. Also it contains changes related to printf formating.
Patchset contains changes for app/ and doc/ folders.
examples/ folder will be provided later.





^ permalink raw reply	[flat|nested] 359+ messages in thread

* [dpdk-dev] [PATCH v7 01/25] ethdev: allow unknown link speed
       [not found]                             ` <CGME20200710070239eucas1p1585ae0ea8e64d3f00e58870d9e133fa1@eucas1p1.samsung.com>
@ 2020-07-10  7:01                               ` " Ivan Dyukov
  0 siblings, 0 replies; 359+ messages in thread
From: Ivan Dyukov @ 2020-07-10  7:01 UTC (permalink / raw)
  To: dev, i.dyukov, v.kuramshin, thomas, david.marchand, ferruh.yigit,
	arybchenko, wei.zhao1, jia.guo, beilei.xing, qiming.yang,
	wenzhuo.lu, mb, stephen, nicolas.chautru, bruce.richardson,
	konstantin.ananyev, cristian.dumitrescu, radu.nicolau,
	akhil.goyal, declan.doherty, skori, pbhagavatula, jerinj,
	kirankumark, david.hunt, anatoly.burakov, xiaoyun.li,
	jingjing.wu, john.mcnamara, jasvinder.singh, byron.marohn,
	yipeng1.wang

From: Thomas Monjalon <thomas@monjalon.net>

When querying the link information, the link status is
a mandatory major information.
Other boolean values are supposed to be accurate:
	- duplex mode (half/full)
	- negotiation (auto/fixed)

This API update is making explicit that the link speed information
is optional.
The value ETH_SPEED_NUM_NONE (0) was already part of the API.
The value ETH_SPEED_NUM_UNKNOWN (infinite) is added to cover
two different cases:
	- speed is not known by the driver
	- device is virtual

Suggested-by: Morten Brørup <mb@smartsharesystems.com>
Suggested-by: Benoit Ganne <bganne@cisco.com>
Signed-off-by: Thomas Monjalon <thomas@monjalon.net>
Reviewed-by: Ferruh Yigit <ferruh.yigit@intel.com>
---
 lib/librte_ethdev/rte_ethdev.h | 20 ++++++++++----------
 1 file changed, 10 insertions(+), 10 deletions(-)

diff --git a/lib/librte_ethdev/rte_ethdev.h b/lib/librte_ethdev/rte_ethdev.h
index a49242bcd..2090af501 100644
--- a/lib/librte_ethdev/rte_ethdev.h
+++ b/lib/librte_ethdev/rte_ethdev.h
@@ -303,6 +303,7 @@ struct rte_eth_stats {
 #define ETH_SPEED_NUM_56G      56000 /**<  56 Gbps */
 #define ETH_SPEED_NUM_100G    100000 /**< 100 Gbps */
 #define ETH_SPEED_NUM_200G    200000 /**< 200 Gbps */
+#define ETH_SPEED_NUM_UNKNOWN UINT32_MAX /**< Unknown */
 
 /**
  * A structure used to retrieve link-level information of an Ethernet port.
@@ -2262,15 +2263,16 @@ int rte_eth_allmulticast_disable(uint16_t port_id);
 int rte_eth_allmulticast_get(uint16_t port_id);
 
 /**
- * Retrieve the status (ON/OFF), the speed (in Mbps) and the mode (HALF-DUPLEX
- * or FULL-DUPLEX) of the physical link of an Ethernet device. It might need
- * to wait up to 9 seconds in it.
+ * Retrieve the link status (up/down), the duplex mode (half/full),
+ * the negotiation (auto/fixed), and if available, the speed (Mbps).
+ *
+ * It might need to wait up to 9 seconds.
+ * @see rte_eth_link_get_nowait.
  *
  * @param port_id
  *   The port identifier of the Ethernet device.
  * @param link
- *   A pointer to an *rte_eth_link* structure to be filled with
- *   the status, the speed and the mode of the Ethernet device link.
+ *   Link information written back.
  * @return
  *   - (0) if successful.
  *   - (-ENOTSUP) if the function is not supported in PMD driver.
@@ -2279,15 +2281,13 @@ int rte_eth_allmulticast_get(uint16_t port_id);
 int rte_eth_link_get(uint16_t port_id, struct rte_eth_link *link);
 
 /**
- * Retrieve the status (ON/OFF), the speed (in Mbps) and the mode (HALF-DUPLEX
- * or FULL-DUPLEX) of the physical link of an Ethernet device. It is a no-wait
- * version of rte_eth_link_get().
+ * Retrieve the link status (up/down), the duplex mode (half/full),
+ * the negotiation (auto/fixed), and if available, the speed (Mbps).
  *
  * @param port_id
  *   The port identifier of the Ethernet device.
  * @param link
- *   A pointer to an *rte_eth_link* structure to be filled with
- *   the status, the speed and the mode of the Ethernet device link.
+ *   Link information written back.
  * @return
  *   - (0) if successful.
  *   - (-ENOTSUP) if the function is not supported in PMD driver.
-- 
2.17.1


^ permalink raw reply	[flat|nested] 359+ messages in thread

* [dpdk-dev] [PATCH v7 02/25] ethdev: add a link status text representation
       [not found]                             ` <CGME20200710070242eucas1p2d638073836aab0f37966a801996ee08b@eucas1p2.samsung.com>
@ 2020-07-10  7:02                               ` Ivan Dyukov
  2020-07-10 13:06                                 ` Yigit, Ferruh
  2020-07-10 15:11                                 ` Thomas Monjalon
  0 siblings, 2 replies; 359+ messages in thread
From: Ivan Dyukov @ 2020-07-10  7:02 UTC (permalink / raw)
  To: dev, i.dyukov, v.kuramshin, thomas, david.marchand, ferruh.yigit,
	arybchenko, wei.zhao1, jia.guo, beilei.xing, qiming.yang,
	wenzhuo.lu, mb, stephen, nicolas.chautru, bruce.richardson,
	konstantin.ananyev, cristian.dumitrescu, radu.nicolau,
	akhil.goyal, declan.doherty, skori, pbhagavatula, jerinj,
	kirankumark, david.hunt, anatoly.burakov, xiaoyun.li,
	jingjing.wu, john.mcnamara, jasvinder.singh, byron.marohn,
	yipeng1.wang

This commit add function which treat link status structure
and format it to text representation.

Signed-off-by: Ivan Dyukov <i.dyukov@samsung.com>
---
 MAINTAINERS                              |   1 +
 app/test/Makefile                        |   3 +
 app/test/meson.build                     |   2 +
 app/test/test_ethdev_link.c              | 299 +++++++++++++++++++++++
 lib/librte_ethdev/rte_ethdev.c           | 174 +++++++++++++
 lib/librte_ethdev/rte_ethdev.h           |  54 ++++
 lib/librte_ethdev/rte_ethdev_version.map |   4 +
 7 files changed, 537 insertions(+)
 create mode 100644 app/test/test_ethdev_link.c

diff --git a/MAINTAINERS b/MAINTAINERS
index 5e706cd7e..f4fb31ea2 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -393,6 +393,7 @@ T: git://dpdk.org/next/dpdk-next-net
 F: lib/librte_ethdev/
 F: devtools/test-null.sh
 F: doc/guides/prog_guide/switch_representation.rst
+F: app/test/test_ethdev*
 
 Flow API
 M: Ori Kam <orika@mellanox.com>
diff --git a/app/test/Makefile b/app/test/Makefile
index e5440774b..9f43b8c3c 100644
--- a/app/test/Makefile
+++ b/app/test/Makefile
@@ -251,6 +251,9 @@ SRCS-$(CONFIG_RTE_LIBRTE_SECURITY) += test_security.c
 
 SRCS-$(CONFIG_RTE_LIBRTE_IPSEC) += test_ipsec.c test_ipsec_perf.c
 SRCS-$(CONFIG_RTE_LIBRTE_IPSEC) += test_ipsec_sad.c
+
+SRCS-$(CONFIG_RTE_LIBRTE_ETHER) += test_ethdev_link.c
+
 ifeq ($(CONFIG_RTE_LIBRTE_IPSEC),y)
 LDLIBS += -lrte_ipsec
 endif
diff --git a/app/test/meson.build b/app/test/meson.build
index 56591db4e..1e6acf701 100644
--- a/app/test/meson.build
+++ b/app/test/meson.build
@@ -39,6 +39,7 @@ test_sources = files('commands.c',
 	'test_efd.c',
 	'test_efd_perf.c',
 	'test_errno.c',
+	'test_ethdev_link.c',
 	'test_event_crypto_adapter.c',
 	'test_event_eth_rx_adapter.c',
 	'test_event_ring.c',
@@ -199,6 +200,7 @@ fast_tests = [
         ['eal_flags_misc_autotest', false],
         ['eal_fs_autotest', true],
         ['errno_autotest', true],
+        ['ethdev_link_status', true],
         ['event_ring_autotest', true],
         ['fib_autotest', true],
         ['fib6_autotest', true],
diff --git a/app/test/test_ethdev_link.c b/app/test/test_ethdev_link.c
new file mode 100644
index 000000000..8a2f133c0
--- /dev/null
+++ b/app/test/test_ethdev_link.c
@@ -0,0 +1,299 @@
+/* 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[128];
+	ret = rte_eth_link_strf(text, 128, NULL, &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 Gbit/s FDX Autoneg\n",
+		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_strf(text, 128, NULL, &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 Mbit/s HDX Fixed\n",
+		text, strlen(text), "Invalid default link status "
+		"string with HDX");
+
+	link_status.link_speed = ETH_SPEED_NUM_UNKNOWN,
+	ret = rte_eth_link_strf(text, 128, NULL, &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 speed HDX Fixed\n",
+		text, strlen(text), "Invalid default link status "
+		"string with HDX");
+	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[128];
+	ret = rte_eth_link_strf(text, 128, NULL, &link_status);
+	RTE_TEST_ASSERT(ret > 0, "Failed to format default string\n");
+	TEST_ASSERT_BUFFERS_ARE_EQUAL("Link down\n",
+		text, strlen(text), "Invalid default link status string");
+
+	return TEST_SUCCESS;
+}
+
+static int32_t
+test_link_status_string_overflow(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[128];
+	int i = 0;
+	for (i = 0; i < 128; i++)
+		text[i] = 'Y';
+	text[127] = '\0';
+
+	ret = rte_eth_link_strf(NULL, 2, "status %S, %G Gbits/s",
+		&link_status);
+	RTE_TEST_ASSERT(ret < 0, "Format string should fail, but it's ok\n");
+
+	ret = rte_eth_link_strf(text, 2, "status %S, %G Gbits/s",
+		&link_status);
+	RTE_TEST_ASSERT(ret < 0, "Format string should fail, but it's ok\n");
+	RTE_TEST_ASSERT(text[2] == 'Y', "String1 overflow\n");
+
+	ret = rte_eth_link_strf(text, 8, NULL,
+		&link_status);
+	RTE_TEST_ASSERT(ret < 0, "Default format string should fail,"
+			" but it's ok\n");
+	RTE_TEST_ASSERT(text[8] == 'Y', "String1 overflow\n");
+
+	ret = rte_eth_link_strf(text, 10, NULL,
+		&link_status);
+	RTE_TEST_ASSERT(ret < 0, "Default format string should fail,"
+			" but it's ok\n");
+	RTE_TEST_ASSERT(text[10] == 'Y', "String1 overflow\n");
+
+	text[1] = 'Y';
+	ret = rte_eth_link_strf(text, 1, "%S",
+		&link_status);
+	RTE_TEST_ASSERT(ret < 0, "Status string should fail, but it's ok\n");
+	RTE_TEST_ASSERT(text[1] == 'Y', "String1 overflow\n");
+
+	text[1] = 'Y';
+	ret = rte_eth_link_strf(text, 1, "%s",
+		&link_status);
+	RTE_TEST_ASSERT(ret < 0, "Status string should fail, but it's ok\n");
+	RTE_TEST_ASSERT(text[1] == 'Y', "String1 overflow\n");
+
+
+	return TEST_SUCCESS;
+}
+
+static int32_t
+test_link_status_format(void)
+{
+	int ret = 0;
+	struct rte_eth_link link_status = {
+		.link_speed = ETH_SPEED_NUM_40G,
+		.link_status = ETH_LINK_UP,
+		.link_autoneg = ETH_LINK_AUTONEG,
+		.link_duplex = ETH_LINK_FULL_DUPLEX
+	};
+	char text[128];
+	int i = 0;
+	for (i = 0; i < 128; i++)
+		text[i] = 'Y';
+	text[127] = '\0';
+	printf("status format #1: %s\n", text);
+	ret = rte_eth_link_strf(text, 128, "status = %S, duplex = %D\n",
+		&link_status);
+	printf("status format #2: %s\n", text);
+	RTE_TEST_ASSERT(ret > 0, "Failed to format string\n");
+	TEST_ASSERT_BUFFERS_ARE_EQUAL("status = Up, duplex = FDX\n",
+		text, strlen(text), "Invalid status string1.");
+
+	ret = rte_eth_link_strf(text, 128, "%A", &link_status);
+	printf("status format #3: %s\n", text);
+	RTE_TEST_ASSERT(ret > 0, "Failed to format string\n");
+	TEST_ASSERT_BUFFERS_ARE_EQUAL("Autoneg",
+		text, strlen(text), "Invalid status string2.");
+
+	ret = rte_eth_link_strf(text, 128,
+		"%G",
+		&link_status);
+	printf("status format #4: %s\n", text);
+	RTE_TEST_ASSERT(ret > 0, "Failed to format string\n");
+	TEST_ASSERT_BUFFERS_ARE_EQUAL("40.0",
+		text, strlen(text), "Invalid status string3.");
+
+	ret = rte_eth_link_strf(text, 128,
+		"%d %M %",
+		&link_status);
+	printf("status format #5: %s\n", text);
+	RTE_TEST_ASSERT(ret > 0, "Failed to format string\n");
+	TEST_ASSERT_BUFFERS_ARE_EQUAL("%d 40000 %",
+		text, strlen(text), "Invalid status string4.");
+	return TEST_SUCCESS;
+}
+
+static int32_t
+test_link_status_return_value(void)
+{
+	int ret = 0;
+	struct rte_eth_link link_status = {
+		.link_speed = ETH_SPEED_NUM_40G,
+		.link_status = ETH_LINK_UP,
+		.link_autoneg = ETH_LINK_AUTONEG,
+		.link_duplex = ETH_LINK_FULL_DUPLEX
+	};
+	char text[128];
+	int i = 0;
+	for (i = 0; i < 128; i++)
+		text[i] = 'Y';
+	text[127] = '\0';
+	ret = rte_eth_link_strf(text, 128, "status = %S, ",
+		&link_status);
+	printf("return value #1:ret=%u, text=%s\n", ret, text);
+	ret += rte_eth_link_strf(text + ret, 128 - ret,
+		"%A",
+		&link_status);
+	printf("return value #2:ret=%u, text=%s\n", ret, text);
+	ret += rte_eth_link_strf(text + ret, 128 - ret,
+		", duplex = %D\n",
+		&link_status);
+	printf("return value #3:ret=%u, text=%s\n", ret, text);
+	ret += rte_eth_link_strf(text + ret, 128 - ret,
+		"%M Mbits/s\n",
+		&link_status);
+	printf("return value #4:ret=%u, text=%s\n", ret, text);
+	RTE_TEST_ASSERT(ret > 0, "Failed to format string\n");
+	TEST_ASSERT_BUFFERS_ARE_EQUAL("status = Up, Autoneg, duplex = FDX\n"
+		"40000 Mbits/s\n",
+		text, strlen(text), "Invalid status string");
+
+	return TEST_SUCCESS;
+}
+
+static int32_t
+test_link_status_unknown_specifier(void)
+{
+	int ret = 0;
+	struct rte_eth_link link_status = {
+		.link_speed = ETH_SPEED_NUM_40G,
+		.link_status = ETH_LINK_UP,
+		.link_autoneg = ETH_LINK_AUTONEG,
+		.link_duplex = ETH_LINK_FULL_DUPLEX
+	};
+	char text[128];
+	ret = rte_eth_link_strf(text, 128, "status = %",
+		&link_status);
+	RTE_TEST_ASSERT(ret > 0, "Status string1 is failed\n");
+	TEST_ASSERT_BUFFERS_ARE_EQUAL("status = %",
+		text, strlen(text), "Invalid status string1");
+
+	ret = rte_eth_link_strf(text, 128,
+		", duplex = %d\n",
+		&link_status);
+	RTE_TEST_ASSERT(ret > 0, "Status string2 is failed\n");
+	TEST_ASSERT_BUFFERS_ARE_EQUAL(", duplex = %d\n",
+		text, strlen(text), "Invalid status string2");
+
+	ret = rte_eth_link_strf(text, 128,
+		"% Mbits/s\n",
+		&link_status);
+	RTE_TEST_ASSERT(ret > 0, "Status string3 is failed\n");
+	TEST_ASSERT_BUFFERS_ARE_EQUAL("% Mbits/s\n",
+		text, strlen(text), "Invalid status string3");
+
+	ret = rte_eth_link_strf(text, 128,
+		"%w Mbits/s\n",
+		&link_status);
+	RTE_TEST_ASSERT(ret > 0, "Status string4 should be ok, but it's fail\n");
+	TEST_ASSERT_BUFFERS_ARE_EQUAL("%w Mbits/s\n",
+		text, strlen(text), "Invalid status string4");
+	return TEST_SUCCESS;
+}
+
+static int32_t
+test_link_status_format_edges(void)
+{
+	int ret = 0;
+	struct rte_eth_link link_status = {
+		.link_speed = ETH_SPEED_NUM_UNKNOWN,
+		.link_status = ETH_LINK_DOWN,
+		.link_autoneg = ETH_LINK_AUTONEG,
+		.link_duplex = ETH_LINK_HALF_DUPLEX
+	};
+	char text[128];
+	ret = rte_eth_link_strf(text, 4, "%S", &link_status);
+	printf("format edges #1: %s\n", text);
+	RTE_TEST_ASSERT(ret < 0, "It should fail. No space for "
+				 "zero terminator\n");
+	ret = rte_eth_link_strf(text, 6, "123%D", &link_status);
+	printf("format edges #2: %s\n", text);
+	RTE_TEST_ASSERT(ret < 0, "It should fail. No space for "
+				 "zero terminator\n");
+	ret = rte_eth_link_strf(text, 7, "%A", &link_status);
+	printf("format edges #3: %s\n", text);
+	RTE_TEST_ASSERT(ret < 0, "It should fail. No space for "
+				 "zero terminator\n");
+	ret = rte_eth_link_strf(text, 8, "%A", &link_status);
+	printf("format edges #4: %s\n", text);
+	RTE_TEST_ASSERT(ret > 0, "It should ok, but it fails\n");
+	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_status_string_overflow),
+		TEST_CASE(test_link_status_format),
+		TEST_CASE(test_link_status_format_edges),
+		TEST_CASE(test_link_status_unknown_specifier),
+		TEST_CASE(test_link_status_return_value),
+		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);
diff --git a/lib/librte_ethdev/rte_ethdev.c b/lib/librte_ethdev/rte_ethdev.c
index d06b7f9b1..38332b1e4 100644
--- a/lib/librte_ethdev/rte_ethdev.c
+++ b/lib/librte_ethdev/rte_ethdev.c
@@ -2383,6 +2383,180 @@ rte_eth_link_get_nowait(uint16_t port_id, struct rte_eth_link *eth_link)
 	return 0;
 }
 
+static int
+rte_eth_link_strf_parser(char *str, size_t len, const char *const fmt,
+			   const struct rte_eth_link *link)
+{
+	size_t offset = 0;
+	const char *fmt_cur = fmt;
+	char *str_cur = str;
+	double gbits = (double)link->link_speed / 1000.;
+	static const char autoneg_str[]       = "Autoneg";
+	static const char fixed_str[]         = "Fixed";
+	static const char fdx_str[]           = "FDX";
+	static const char hdx_str[]           = "HDX";
+	static const char unknown_str[]       = "Unknown";
+	static const char up_str[]            = "Up";
+	static const char down_str[]          = "Down";
+	char gbits_str[20];
+	char mbits_str[20];
+
+	/* preformat complex formatting to easily concatinate it further */
+	snprintf(mbits_str, sizeof(mbits_str), "%u", link->link_speed);
+	snprintf(gbits_str, sizeof(gbits_str), "%.1f", gbits);
+	/* init str before formatting */
+	str[0] = 0;
+	while (*fmt_cur) {
+		/* check str bounds */
+		if (offset > (len - 1)) {
+			str[len - 1] = '\0';
+			return -1;
+		}
+		if (*fmt_cur == '%') {
+			/* set null terminator to current position,
+			 * it's required for strlcat
+			 */
+			*str_cur = '\0';
+			switch (*++fmt_cur) {
+			/* Speed in Mbits/s */
+			case 'M':
+				if (link->link_speed ==
+				    ETH_SPEED_NUM_UNKNOWN)
+					offset = strlcat(str, unknown_str,
+							 len);
+				else
+					offset = strlcat(str, mbits_str, len);
+				break;
+			/* Speed in Gbits/s */
+			case 'G':
+				if (link->link_speed ==
+				    ETH_SPEED_NUM_UNKNOWN)
+					offset = strlcat(str, unknown_str,
+							 len);
+				else
+					offset = strlcat(str, gbits_str, len);
+				break;
+			/* Link status */
+			case 'S':
+				offset = strlcat(str, link->link_status ?
+					up_str : down_str, len);
+				break;
+			/* Link autoneg */
+			case 'A':
+				offset = strlcat(str, link->link_autoneg ?
+					autoneg_str : fixed_str, len);
+				break;
+			/* Link duplex */
+			case 'D':
+				offset = strlcat(str, link->link_duplex ?
+					fdx_str : hdx_str, len);
+				break;
+			/* ignore unknown specifier */
+			default:
+				*str_cur = '%';
+				offset++;
+				fmt_cur--;
+				break;
+
+			}
+			if (offset > (len - 1))
+				return -1;
+
+			str_cur = str + offset;
+		} else {
+			*str_cur++ = *fmt_cur;
+			offset++;
+		}
+		fmt_cur++;
+	}
+	*str_cur = '\0';
+	return offset;
+}
+
+int
+rte_eth_link_printf(const char *const fmt,
+		    const struct rte_eth_link *link)
+{
+	char text[200];
+	int ret;
+
+	ret = rte_eth_link_strf(text, 200, fmt, link);
+	if (ret > 0)
+		printf("%s", text);
+	return ret;
+}
+
+int
+rte_eth_link_strf(char *str, size_t len, const char *const fmt,
+		    const struct rte_eth_link *link)
+{
+	size_t offset = 0;
+	double gbits = (double)link->link_speed / 1000.;
+	char speed_gbits_str[20];
+	char speed_mbits_str[20];
+	/* TBD: make it international? */
+	static const char link_down_str[]     = "Link down\n";
+	static const char link_up_str[]       = "Link up at ";
+	static const char unknown_speed_str[] = "Unknown speed ";
+	static const char mbits_str[]	      = "Mbit/s";
+	static const char gbits_str[]	      = "Gbit/s";
+	static const char fdx_str[]           = "FDX ";
+	static const char hdx_str[]           = "HDX ";
+	/* autoneg is latest param in default string, so add '\n' */
+	static const char autoneg_str[]       = "Autoneg\n";
+	static const char fixed_str[]         = "Fixed\n";
+	if (str == NULL || len == 0)
+		return -1;
+	/* default format string, if no fmt is specified */
+	if (fmt == NULL) {
+		if (link->link_status == ETH_LINK_DOWN) {
+			if (sizeof(link_down_str) > len)
+				return -1;
+			return strlcpy(str, link_down_str, len);
+		}
+
+		/* preformat complex strings to easily concatinate it further */
+		snprintf(speed_mbits_str, 20, "%u %s ", link->link_speed,
+			 mbits_str);
+		snprintf(speed_gbits_str, 20, "%.1f %s ", gbits, gbits_str);
+
+		offset = strlcpy(str, link_up_str, len);
+		/* reserve one byte to null terminator */
+		if (offset > (len - 1))
+			return -1;
+		/* link speed */
+		if (link->link_speed == ETH_SPEED_NUM_UNKNOWN) {
+			offset = strlcat(str, unknown_speed_str, len);
+			if (offset > (len - 1))
+				return -1;
+		} else {
+			if (link->link_speed < ETH_SPEED_NUM_1G) {
+				offset = strlcat(str, speed_mbits_str, len);
+				if (offset > (len - 1))
+					return -1;
+			} else {
+				offset = strlcat(str, speed_gbits_str, len);
+				if (offset > (len - 1))
+					return -1;
+			}
+		}
+		/* link duplex */
+		offset = strlcat(str, link->link_duplex ?
+			       fdx_str : hdx_str, len);
+		if (offset > (len - 1))
+			return -1;
+		/* link autonegotiation */
+		offset = strlcat(str, link->link_autoneg ?
+			       autoneg_str : fixed_str, len);
+		if (offset > (len - 1))
+			return -1;
+	/* Formatted status */
+	} else
+		offset = rte_eth_link_strf_parser(str, len, fmt, link);
+
+	return offset;
+}
+
 int
 rte_eth_stats_get(uint16_t port_id, struct rte_eth_stats *stats)
 {
diff --git a/lib/librte_ethdev/rte_ethdev.h b/lib/librte_ethdev/rte_ethdev.h
index 2090af501..9afb566b3 100644
--- a/lib/librte_ethdev/rte_ethdev.h
+++ b/lib/librte_ethdev/rte_ethdev.h
@@ -2295,6 +2295,60 @@ int rte_eth_link_get(uint16_t port_id, struct rte_eth_link *link);
  */
 int rte_eth_link_get_nowait(uint16_t port_id, struct rte_eth_link *link);
 
+
+/**
+ * print formatted link status to stdout. This function threats all
+ * special values like ETH_SPEED_NUM_UNKNOWN, ETH_LINK_DOWN etc. and convert
+ * them to textual representation.
+ *
+ * @param fmt
+ *   Format string which allow to format link status. If NULL is provided
+ *   , default formatting will be applied.
+ *   Following specifiers are available:
+ *    - '%M' link speed in Mbits/s
+ *    - '%G' link speed in Gbits/s
+ *    - '%S' link status. e.g. Up or Down
+ *    - '%A' link autonegotiation state
+ *    - '%D' link duplex state
+ * @param link
+ *   Link status provided by rte_eth_link_get function
+ * @return
+ *   - Number of bytes written to stdout. In case of error, -1 is returned.
+ *
+ */
+__rte_experimental
+int rte_eth_link_printf(const char *const fmt,
+			const struct rte_eth_link *link);
+
+/**
+ * Format link status to textual representation. This function threats all
+ * special values like ETH_SPEED_NUM_UNKNOWN, ETH_LINK_DOWN etc. and convert
+ * them to textual representation.
+ *
+ * @param str
+ *   A pointer to a string to be filled with textual representation of
+ *   device status.
+ * @param len
+ *   Length of available memory at 'str' string.
+ * @param fmt
+ *   Format string which allow to format link status. If NULL is provided
+ *   , default formatting will be applied.
+ *   Following specifiers are available:
+ *    - '%M' link speed in Mbits/s
+ *    - '%G' link speed in Gbits/s
+ *    - '%S' link status. e.g. Up or Down
+ *    - '%A' link autonegotiation state
+ *    - '%D' link duplex state
+ * @param link
+ *   Link status provided by rte_eth_link_get function
+ * @return
+ *   - Number of bytes written to str array. In case of error, -1 is returned.
+ *
+ */
+__rte_experimental
+int rte_eth_link_strf(char *str, size_t len, const char *const fmt,
+			const struct rte_eth_link *eth_link);
+
 /**
  * Retrieve the general I/O statistics of an Ethernet device.
  *
diff --git a/lib/librte_ethdev/rte_ethdev_version.map b/lib/librte_ethdev/rte_ethdev_version.map
index 715505604..6c80597d1 100644
--- a/lib/librte_ethdev/rte_ethdev_version.map
+++ b/lib/librte_ethdev/rte_ethdev_version.map
@@ -241,4 +241,8 @@ EXPERIMENTAL {
 	__rte_ethdev_trace_rx_burst;
 	__rte_ethdev_trace_tx_burst;
 	rte_flow_get_aged_flows;
+
+	# added in 20.08
+	rte_eth_link_strf;
+	rte_eth_link_printf;
 };
-- 
2.17.1


^ permalink raw reply	[flat|nested] 359+ messages in thread

* [dpdk-dev] [PATCH v7 03/25] app: UNKNOWN link speed print format
       [not found]                             ` <CGME20200710070245eucas1p1f291014b205a97bf72822e820d7b2c8c@eucas1p1.samsung.com>
@ 2020-07-10  7:02                               ` Ivan Dyukov
  0 siblings, 0 replies; 359+ messages in thread
From: Ivan Dyukov @ 2020-07-10  7:02 UTC (permalink / raw)
  To: dev, i.dyukov, v.kuramshin, thomas, david.marchand, ferruh.yigit,
	arybchenko, wei.zhao1, jia.guo, beilei.xing, qiming.yang,
	wenzhuo.lu, mb, stephen, nicolas.chautru, bruce.richardson,
	konstantin.ananyev, cristian.dumitrescu, radu.nicolau,
	akhil.goyal, declan.doherty, skori, pbhagavatula, jerinj,
	kirankumark, david.hunt, anatoly.burakov, xiaoyun.li,
	jingjing.wu, john.mcnamara, jasvinder.singh, byron.marohn,
	yipeng1.wang

Add usage of rte_eth_link_strf function to example
applications

Signed-off-by: Ivan Dyukov <i.dyukov@samsung.com>
---
 app/proc-info/main.c     |  9 +++------
 app/test-pipeline/init.c | 11 +++++------
 app/test-pmd/config.c    | 20 ++++++++++++--------
 app/test-pmd/testpmd.c   |  9 +--------
 app/test/test_pmd_perf.c | 17 +++++++----------
 5 files changed, 28 insertions(+), 38 deletions(-)

diff --git a/app/proc-info/main.c b/app/proc-info/main.c
index abeca4aab..4a4c572c3 100644
--- a/app/proc-info/main.c
+++ b/app/proc-info/main.c
@@ -685,12 +685,9 @@ show_port(void)
 			printf("Link get failed (port %u): %s\n",
 			       i, rte_strerror(-ret));
 		} else {
-			printf("\t  -- link speed %d duplex %d,"
-					" auto neg %d status %d\n",
-					link.link_speed,
-					link.link_duplex,
-					link.link_autoneg,
-					link.link_status);
+			rte_eth_