All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH v6 0/5] ethdev: add speed capabilities and refactor link API
       [not found] <1443993003-1059-1-git-send-email-marcdevel@gmail.com>
@ 2015-10-25 21:59 ` Marc Sune
  2015-10-25 21:59   ` [PATCH v6 1/5] ethdev: Added ETH_SPEED_CAP bitmap for ports Marc Sune
                     ` (6 more replies)
  0 siblings, 7 replies; 167+ messages in thread
From: Marc Sune @ 2015-10-25 21:59 UTC (permalink / raw)
  To: dev

The current rte_eth_dev_info abstraction does not provide any mechanism to
get the supported speed(s) of an ethdev.

For some drivers (e.g. ixgbe), an educated guess could be done based on the
driver's name (driver_name in rte_eth_dev_info), see:

http://dpdk.org/ml/archives/dev/2013-August/000412.html

However, i) doing string comparisons is annoying, and can silently
break existing applications if PMDs change their names ii) it does not
provide all the supported capabilities of the ethdev iii) for some drivers it
is impossible determine correctly the (max) speed by the application
(e.g. in i40, distinguish between XL710 and X710).

In addition, the link APIs do not allow to define a set of advertised link
speeds for autonegociation.

This series of patches adds the following capabilities:

* speed_capa bitmap in rte_eth_dev_info, which is filled by the PMDs
  according to the physical device capabilities.
* refactors link API in ethdev to allow the definition of the advertised
  link speeds, fix speed (no auto-negociation) or advertise all supported
  speeds (default).

WARNING: this patch series, specifically 3/4, is NOT tested for most of the
PMDs, due to the lack of hardware. Only generic EM is tested (VM).
Minor bugs expected.

* * * * *

v2: rebase, converted speed_capa into 32 bits bitmap, fixed alignment
(checkpatch).

v3: rebase to v2.1. unified ETH_LINK_SPEED and ETH_SPEED_CAP into ETH_SPEED.
    Converted field speed in struct rte_eth_conf to speed, to allow a bitmap
    for defining the announced speeds, as suggested M. Brorup. Fixed spelling
    issues.

v4: fixed errata in the documentation of field speeds of rte_eth_conf, and
    commit 1/2 message. rebased to v2.1.0. v3 was incorrectly based on
    ~2.1.0-rc1.

v5: revert to v2 speed capabilities patch. Fixed MLX4 speed capabilities
    (thanks N. Laranjeiro). Refactored link speed API to allow setting
    advertised speeds (3/4). Added NO_AUTONEG option to explicitely disable
    auto-negociation. Updated 2.2 rel. notes (4/4). Rebased to current HEAD.

v6: Move link_duplex to be part of bitfield. Fixed i40 autoneg flag link
    update code. Added rte_eth_speed_to_bm_flag() to .map file. Fixed other
    spelling issues. Rebased to current HEAD.

Marc Sune (5):
  ethdev: Added ETH_SPEED_CAP bitmap for ports
  ethdev: Fill speed capability bitmaps in the PMDs
  ethdev: redesign link speed config API
  doc: update with link changes
  ethdev: add rte_eth_speed_to_bm_flag() to ver. map

 app/test-pmd/cmdline.c                     | 124 +++++++++++++++--------------
 app/test/virtual_pmd.c                     |   4 +-
 doc/guides/rel_notes/release_2_2.rst       |  23 ++++++
 drivers/net/af_packet/rte_eth_af_packet.c  |   5 +-
 drivers/net/bonding/rte_eth_bond_8023ad.c  |  14 ++--
 drivers/net/cxgbe/base/t4_hw.c             |   8 +-
 drivers/net/e1000/base/e1000_80003es2lan.c |   6 +-
 drivers/net/e1000/base/e1000_82541.c       |   8 +-
 drivers/net/e1000/base/e1000_82543.c       |   4 +-
 drivers/net/e1000/base/e1000_82575.c       |  11 +--
 drivers/net/e1000/base/e1000_api.c         |   2 +-
 drivers/net/e1000/base/e1000_api.h         |   2 +-
 drivers/net/e1000/base/e1000_defines.h     |   4 +-
 drivers/net/e1000/base/e1000_hw.h          |   2 +-
 drivers/net/e1000/base/e1000_ich8lan.c     |   4 +-
 drivers/net/e1000/base/e1000_mac.c         |   9 ++-
 drivers/net/e1000/base/e1000_mac.h         |   6 +-
 drivers/net/e1000/base/e1000_vf.c          |   4 +-
 drivers/net/e1000/base/e1000_vf.h          |   2 +-
 drivers/net/e1000/em_ethdev.c              | 109 ++++++++++++-------------
 drivers/net/e1000/igb_ethdev.c             | 104 +++++++++++++-----------
 drivers/net/fm10k/fm10k_ethdev.c           |   5 +-
 drivers/net/i40e/i40e_ethdev.c             |  78 ++++++++++--------
 drivers/net/i40e/i40e_ethdev_vf.c          |  11 +--
 drivers/net/ixgbe/ixgbe_ethdev.c           |  74 ++++++++---------
 drivers/net/mlx4/mlx4.c                    |   6 ++
 drivers/net/mpipe/mpipe_tilegx.c           |   6 +-
 drivers/net/null/rte_eth_null.c            |   5 +-
 drivers/net/pcap/rte_eth_pcap.c            |   9 ++-
 drivers/net/ring/rte_eth_ring.c            |   5 +-
 drivers/net/virtio/virtio_ethdev.c         |   2 +-
 drivers/net/virtio/virtio_ethdev.h         |   2 -
 drivers/net/vmxnet3/vmxnet3_ethdev.c       |   5 +-
 drivers/net/xenvirt/rte_eth_xenvirt.c      |   5 +-
 examples/ip_pipeline/config_parse.c        |   3 +-
 lib/librte_ether/rte_ethdev.c              |  49 ++++++++++++
 lib/librte_ether/rte_ethdev.h              |  97 +++++++++++++++++-----
 lib/librte_ether/rte_ether_version.map     |   6 ++
 38 files changed, 501 insertions(+), 322 deletions(-)

-- 
2.1.4

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

* [PATCH v6 1/5] ethdev: Added ETH_SPEED_CAP bitmap for ports
  2015-10-25 21:59 ` [PATCH v6 0/5] ethdev: add speed capabilities and refactor link API Marc Sune
@ 2015-10-25 21:59   ` Marc Sune
  2015-11-01 22:11     ` Thomas Monjalon
  2015-10-25 21:59   ` [PATCH v6 2/5] ethdev: Fill speed capability bitmaps in the PMDs Marc Sune
                     ` (5 subsequent siblings)
  6 siblings, 1 reply; 167+ messages in thread
From: Marc Sune @ 2015-10-25 21:59 UTC (permalink / raw)
  To: dev

Added constants and bitmap to struct rte_eth_dev_info to be used by PMDs.

Signed-off-by: Marc Sune <marcdevel@gmail.com>
---
 lib/librte_ether/rte_ethdev.h | 24 ++++++++++++++++++++++++
 1 file changed, 24 insertions(+)

diff --git a/lib/librte_ether/rte_ethdev.h b/lib/librte_ether/rte_ethdev.h
index 8a8c82b..951a423 100644
--- a/lib/librte_ether/rte_ethdev.h
+++ b/lib/librte_ether/rte_ethdev.h
@@ -811,6 +811,29 @@ struct rte_eth_conf {
 #define DEV_TX_OFFLOAD_OUTER_IPV4_CKSUM 0x00000080 /**< Used for tunneling packet. */
 #define DEV_TX_OFFLOAD_QINQ_INSERT 0x00000100
 
+/**
+ * Device supported speeds
+ */
+#define ETH_SPEED_CAP_NOT_PHY	(0)  /*< No phy media > */
+#define ETH_SPEED_CAP_10M_HD	(1 << 0)  /*< 10 Mbps half-duplex> */
+#define ETH_SPEED_CAP_10M_FD	(1 << 1)  /*< 10 Mbps full-duplex> */
+#define ETH_SPEED_CAP_100M_HD	(1 << 2)  /*< 100 Mbps half-duplex> */
+#define ETH_SPEED_CAP_100M_FD	(1 << 3)  /*< 100 Mbps full-duplex> */
+#define ETH_SPEED_CAP_1G	(1 << 4)  /*< 1 Gbps > */
+#define ETH_SPEED_CAP_2_5G	(1 << 5)  /*< 2.5 Gbps > */
+#define ETH_SPEED_CAP_5G	(1 << 6)  /*< 5 Gbps > */
+#define ETH_SPEED_CAP_10G	(1 << 7)  /*< 10 Mbps > */
+#define ETH_SPEED_CAP_20G	(1 << 8)  /*< 20 Gbps > */
+#define ETH_SPEED_CAP_25G	(1 << 9)  /*< 25 Gbps > */
+#define ETH_SPEED_CAP_40G	(1 << 10)  /*< 40 Gbps > */
+#define ETH_SPEED_CAP_50G	(1 << 11)  /*< 50 Gbps > */
+#define ETH_SPEED_CAP_56G	(1 << 12)  /*< 56 Gbps > */
+#define ETH_SPEED_CAP_100G	(1 << 13)  /*< 100 Gbps > */
+
+
+/**
+ * Ethernet device information
+ */
 struct rte_eth_dev_info {
 	struct rte_pci_device *pci_dev; /**< Device PCI information. */
 	const char *driver_name; /**< Device Driver name. */
@@ -837,6 +860,7 @@ struct rte_eth_dev_info {
 	uint16_t vmdq_queue_base; /**< First queue ID for VMDQ pools. */
 	uint16_t vmdq_queue_num;  /**< Queue number for VMDQ pools. */
 	uint16_t vmdq_pool_base;  /**< First ID of VMDQ pools. */
+	uint32_t speed_capa;  /**< Supported speeds bitmap (ETH_SPEED_CAP_). */
 };
 
 /** Maximum name length for extended statistics counters */
-- 
2.1.4

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

* [PATCH v6 2/5] ethdev: Fill speed capability bitmaps in the PMDs
  2015-10-25 21:59 ` [PATCH v6 0/5] ethdev: add speed capabilities and refactor link API Marc Sune
  2015-10-25 21:59   ` [PATCH v6 1/5] ethdev: Added ETH_SPEED_CAP bitmap for ports Marc Sune
@ 2015-10-25 21:59   ` Marc Sune
  2015-10-25 21:59   ` [PATCH v6 3/5] ethdev: redesign link speed config API Marc Sune
                     ` (4 subsequent siblings)
  6 siblings, 0 replies; 167+ messages in thread
From: Marc Sune @ 2015-10-25 21:59 UTC (permalink / raw)
  To: dev

Added speed capabilities to all pmds supporting physical NICs:

* e1000
* ixgbe
* i40
* mlx4
* fm10k

Signed-off-by: Marc Sune <marcdevel@gmail.com>
---
 drivers/net/e1000/em_ethdev.c    |  6 ++++++
 drivers/net/e1000/igb_ethdev.c   |  6 ++++++
 drivers/net/fm10k/fm10k_ethdev.c |  3 +++
 drivers/net/i40e/i40e_ethdev.c   |  9 +++++++++
 drivers/net/ixgbe/ixgbe_ethdev.c | 10 ++++++++++
 drivers/net/mlx4/mlx4.c          |  4 ++++
 6 files changed, 38 insertions(+)

diff --git a/drivers/net/e1000/em_ethdev.c b/drivers/net/e1000/em_ethdev.c
index 912f5dd..72f792c 100644
--- a/drivers/net/e1000/em_ethdev.c
+++ b/drivers/net/e1000/em_ethdev.c
@@ -933,6 +933,12 @@ eth_em_infos_get(struct rte_eth_dev *dev, struct rte_eth_dev_info *dev_info)
 
 	dev_info->max_rx_queues = 1;
 	dev_info->max_tx_queues = 1;
+
+	dev_info->speed_capa = ETH_SPEED_CAP_10M_HD |
+					ETH_SPEED_CAP_10M_FD |
+					ETH_SPEED_CAP_100M_HD |
+					ETH_SPEED_CAP_100M_FD |
+					ETH_SPEED_CAP_1G;
 }
 
 /* return 0 means link status changed, -1 means not changed */
diff --git a/drivers/net/e1000/igb_ethdev.c b/drivers/net/e1000/igb_ethdev.c
index 848ef6e..927f5d9 100644
--- a/drivers/net/e1000/igb_ethdev.c
+++ b/drivers/net/e1000/igb_ethdev.c
@@ -1570,6 +1570,12 @@ eth_igb_infos_get(struct rte_eth_dev *dev, struct rte_eth_dev_info *dev_info)
 		},
 		.txq_flags = 0,
 	};
+
+	dev_info->speed_capa = ETH_SPEED_CAP_10M_HD |
+					ETH_SPEED_CAP_10M_FD |
+					ETH_SPEED_CAP_100M_HD |
+					ETH_SPEED_CAP_100M_FD |
+					ETH_SPEED_CAP_1G;
 }
 
 static void
diff --git a/drivers/net/fm10k/fm10k_ethdev.c b/drivers/net/fm10k/fm10k_ethdev.c
index a69c990..ca6357c 100644
--- a/drivers/net/fm10k/fm10k_ethdev.c
+++ b/drivers/net/fm10k/fm10k_ethdev.c
@@ -964,6 +964,9 @@ fm10k_dev_infos_get(struct rte_eth_dev *dev,
 				ETH_TXQ_FLAGS_NOOFFLOADS,
 	};
 
+	dev_info->speed_capa = ETH_SPEED_CAP_1G | ETH_SPEED_CAP_2_5G |
+					ETH_SPEED_CAP_10G | ETH_SPEED_CAP_25G |
+					ETH_SPEED_CAP_40G | ETH_SPEED_CAP_100G;
 }
 
 static int
diff --git a/drivers/net/i40e/i40e_ethdev.c b/drivers/net/i40e/i40e_ethdev.c
index 2dd9fdc..8a5dfbf 100644
--- a/drivers/net/i40e/i40e_ethdev.c
+++ b/drivers/net/i40e/i40e_ethdev.c
@@ -1624,6 +1624,7 @@ static void
 i40e_dev_info_get(struct rte_eth_dev *dev, struct rte_eth_dev_info *dev_info)
 {
 	struct i40e_pf *pf = I40E_DEV_PRIVATE_TO_PF(dev->data->dev_private);
+	struct i40e_hw *hw = I40E_DEV_PRIVATE_TO_HW(dev->data->dev_private);
 	struct i40e_vsi *vsi = pf->main_vsi;
 
 	dev_info->max_rx_queues = vsi->nb_qps;
@@ -1683,6 +1684,14 @@ i40e_dev_info_get(struct rte_eth_dev *dev, struct rte_eth_dev_info *dev_info)
 		dev_info->max_rx_queues += dev_info->vmdq_queue_num;
 		dev_info->max_tx_queues += dev_info->vmdq_queue_num;
 	}
+
+	if (i40e_is_40G_device(hw->device_id))
+		/* For XL710 */
+		dev_info->speed_capa = ETH_SPEED_CAP_1G | ETH_SPEED_CAP_10G;
+	else
+		/* For X710 */
+		dev_info->speed_capa = ETH_SPEED_CAP_10G | ETH_SPEED_CAP_40G;
+
 }
 
 static int
diff --git a/drivers/net/ixgbe/ixgbe_ethdev.c b/drivers/net/ixgbe/ixgbe_ethdev.c
index ec2918c..3be84aa 100644
--- a/drivers/net/ixgbe/ixgbe_ethdev.c
+++ b/drivers/net/ixgbe/ixgbe_ethdev.c
@@ -2399,6 +2399,16 @@ ixgbe_dev_info_get(struct rte_eth_dev *dev, struct rte_eth_dev_info *dev_info)
 	dev_info->hash_key_size = IXGBE_HKEY_MAX_INDEX * sizeof(uint32_t);
 	dev_info->reta_size = ETH_RSS_RETA_SIZE_128;
 	dev_info->flow_type_rss_offloads = IXGBE_RSS_OFFLOAD_ALL;
+
+	dev_info->speed_capa = ETH_SPEED_CAP_1G | ETH_SPEED_CAP_10G;
+
+	if (hw->mac.type == ixgbe_mac_X540 ||
+	    hw->mac.type == ixgbe_mac_X540_vf ||
+	    hw->mac.type == ixgbe_mac_X550 ||
+	    hw->mac.type == ixgbe_mac_X550_vf)
+
+		dev_info->speed_capa |= ETH_SPEED_CAP_100M_FD /*|
+					ETH_SPEED_CAP_100M_HD*/;
 }
 
 static void
diff --git a/drivers/net/mlx4/mlx4.c b/drivers/net/mlx4/mlx4.c
index 2f49ed5..b45e21a 100644
--- a/drivers/net/mlx4/mlx4.c
+++ b/drivers/net/mlx4/mlx4.c
@@ -3847,6 +3847,10 @@ mlx4_dev_infos_get(struct rte_eth_dev *dev, struct rte_eth_dev_info *info)
 		  DEV_TX_OFFLOAD_UDP_CKSUM |
 		  DEV_TX_OFFLOAD_TCP_CKSUM) :
 		 0);
+
+	info->speed_capa = ETH_SPEED_CAP_10G |ETH_SPEED_CAP_40G |
+					ETH_SPEED_CAP_56G;
+
 	priv_unlock(priv);
 }
 
-- 
2.1.4

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

* [PATCH v6 3/5] ethdev: redesign link speed config API
  2015-10-25 21:59 ` [PATCH v6 0/5] ethdev: add speed capabilities and refactor link API Marc Sune
  2015-10-25 21:59   ` [PATCH v6 1/5] ethdev: Added ETH_SPEED_CAP bitmap for ports Marc Sune
  2015-10-25 21:59   ` [PATCH v6 2/5] ethdev: Fill speed capability bitmaps in the PMDs Marc Sune
@ 2015-10-25 21:59   ` Marc Sune
  2015-10-25 22:03     ` Marc Sune
  2015-11-01 22:16     ` Thomas Monjalon
  2015-10-25 21:59   ` [PATCH v6 4/5] doc: update with link changes Marc Sune
                     ` (3 subsequent siblings)
  6 siblings, 2 replies; 167+ messages in thread
From: Marc Sune @ 2015-10-25 21:59 UTC (permalink / raw)
  To: dev

This patch redesigns the API to set the link speed/s configure
for an ethernet port. Specifically:

- it allows to define a set of advertised speeds for
  auto-negociation.
- it allows to disable link auto-negociation (single fixed speed).
- default: auto-negociate all supported speeds.

Other changes:

* Added utility MACROs ETH_SPEED_NUM_XXX with the numeric
  values of all supported link speeds, in Mbps.
* Converted link_speed to uint32_t to accomodate 100G speeds
  (bug).
* Added autoneg flag in struct rte_eth_link to indicate if
  link speed was a result of auto-negociation or was fixed
  by configuration.
* Added utility function to convert numeric speeds to bitmap
  fields.

Signed-off-by: Marc Sune <marcdevel@gmail.com>
---
 app/test-pmd/cmdline.c                     | 124 +++++++++++++++--------------
 app/test/virtual_pmd.c                     |   4 +-
 drivers/net/af_packet/rte_eth_af_packet.c  |   5 +-
 drivers/net/bonding/rte_eth_bond_8023ad.c  |  14 ++--
 drivers/net/cxgbe/base/t4_hw.c             |   8 +-
 drivers/net/e1000/base/e1000_80003es2lan.c |   6 +-
 drivers/net/e1000/base/e1000_82541.c       |   8 +-
 drivers/net/e1000/base/e1000_82543.c       |   4 +-
 drivers/net/e1000/base/e1000_82575.c       |  11 +--
 drivers/net/e1000/base/e1000_api.c         |   2 +-
 drivers/net/e1000/base/e1000_api.h         |   2 +-
 drivers/net/e1000/base/e1000_defines.h     |   4 +-
 drivers/net/e1000/base/e1000_hw.h          |   2 +-
 drivers/net/e1000/base/e1000_ich8lan.c     |   4 +-
 drivers/net/e1000/base/e1000_mac.c         |   9 ++-
 drivers/net/e1000/base/e1000_mac.h         |   6 +-
 drivers/net/e1000/base/e1000_vf.c          |   4 +-
 drivers/net/e1000/base/e1000_vf.h          |   2 +-
 drivers/net/e1000/em_ethdev.c              | 113 +++++++++++++-------------
 drivers/net/e1000/igb_ethdev.c             | 108 +++++++++++++------------
 drivers/net/fm10k/fm10k_ethdev.c           |   8 +-
 drivers/net/i40e/i40e_ethdev.c             |  73 ++++++++---------
 drivers/net/i40e/i40e_ethdev_vf.c          |  11 +--
 drivers/net/ixgbe/ixgbe_ethdev.c           |  72 ++++++++---------
 drivers/net/mlx4/mlx4.c                    |   2 +
 drivers/net/mpipe/mpipe_tilegx.c           |   6 +-
 drivers/net/null/rte_eth_null.c            |   5 +-
 drivers/net/pcap/rte_eth_pcap.c            |   9 ++-
 drivers/net/ring/rte_eth_ring.c            |   5 +-
 drivers/net/virtio/virtio_ethdev.c         |   2 +-
 drivers/net/virtio/virtio_ethdev.h         |   2 -
 drivers/net/vmxnet3/vmxnet3_ethdev.c       |   5 +-
 drivers/net/xenvirt/rte_eth_xenvirt.c      |   5 +-
 examples/ip_pipeline/config_parse.c        |   3 +-
 lib/librte_ether/rte_ethdev.c              |  49 ++++++++++++
 lib/librte_ether/rte_ethdev.h              | 113 ++++++++++++++++----------
 36 files changed, 449 insertions(+), 361 deletions(-)

diff --git a/app/test-pmd/cmdline.c b/app/test-pmd/cmdline.c
index 0f8f48f..c62f5be 100644
--- a/app/test-pmd/cmdline.c
+++ b/app/test-pmd/cmdline.c
@@ -897,14 +897,65 @@ struct cmd_config_speed_all {
 	cmdline_fixed_string_t value2;
 };
 
+static int
+parse_and_check_speed_duplex(char *value1, char *value2, uint32_t *link_speed)
+{
+
+	int duplex;
+
+	if (!strcmp(value2, "half")) {
+		duplex = 0;
+	} else if (!strcmp(value2, "full")) {
+		duplex = 1;
+	} else if (!strcmp(value2, "auto")) {
+		duplex = 1;
+	} else {
+		printf("Unknown parameter\n");
+		return -1;
+	}
+
+	if (!strcmp(value1, "10")) {
+		*link_speed = (duplex) ? ETH_LINK_SPEED_10M :
+							ETH_LINK_SPEED_10M_HD;
+	} else if (!strcmp(value1, "100")) {
+		*link_speed = (duplex) ? ETH_LINK_SPEED_100M :
+							ETH_LINK_SPEED_100M_HD;
+	} else if (!strcmp(value1, "1000")) {
+		if (!duplex)
+			goto invalid_speed_param;
+		*link_speed = ETH_LINK_SPEED_1G;
+	} else if (!strcmp(value1, "10000")) {
+		if (!duplex)
+			goto invalid_speed_param;
+		*link_speed = ETH_LINK_SPEED_10G;
+	} else if (!strcmp(value1, "40000")) {
+		if (!duplex)
+			goto invalid_speed_param;
+		*link_speed = ETH_LINK_SPEED_40G;
+	} else if (!strcmp(value1, "auto")) {
+		if (!duplex)
+			goto invalid_speed_param;
+		*link_speed = ETH_LINK_SPEED_AUTONEG;
+	} else {
+		printf("Unknown parameter\n");
+		return -1;
+	}
+
+	return 0;
+
+invalid_speed_param:
+
+	printf("Invalid speed parameter\n");
+	return -1;
+}
+
 static void
 cmd_config_speed_all_parsed(void *parsed_result,
 			__attribute__((unused)) struct cmdline *cl,
 			__attribute__((unused)) void *data)
 {
 	struct cmd_config_speed_all *res = parsed_result;
-	uint16_t link_speed = ETH_LINK_SPEED_AUTONEG;
-	uint16_t link_duplex = 0;
+	uint32_t link_speed;
 	portid_t pid;
 
 	if (!all_ports_stopped()) {
@@ -912,40 +963,18 @@ cmd_config_speed_all_parsed(void *parsed_result,
 		return;
 	}
 
-	if (!strcmp(res->value1, "10"))
-		link_speed = ETH_LINK_SPEED_10;
-	else if (!strcmp(res->value1, "100"))
-		link_speed = ETH_LINK_SPEED_100;
-	else if (!strcmp(res->value1, "1000"))
-		link_speed = ETH_LINK_SPEED_1000;
-	else if (!strcmp(res->value1, "10000"))
-		link_speed = ETH_LINK_SPEED_10G;
-	else if (!strcmp(res->value1, "40000"))
-		link_speed = ETH_LINK_SPEED_40G;
-	else if (!strcmp(res->value1, "auto"))
-		link_speed = ETH_LINK_SPEED_AUTONEG;
-	else {
-		printf("Unknown parameter\n");
+	if (parse_and_check_speed_duplex(res->value1,
+						res->value2,
+						&link_speed) < 0)
 		return;
-	}
-
-	if (!strcmp(res->value2, "half"))
-		link_duplex = ETH_LINK_HALF_DUPLEX;
-	else if (!strcmp(res->value2, "full"))
-		link_duplex = ETH_LINK_FULL_DUPLEX;
-	else if (!strcmp(res->value2, "auto"))
-		link_duplex = ETH_LINK_AUTONEG_DUPLEX;
-	else {
-		printf("Unknown parameter\n");
-		return;
-	}
 
 	FOREACH_PORT(pid, ports) {
-		ports[pid].dev_conf.link_speed = link_speed;
-		ports[pid].dev_conf.link_duplex = link_duplex;
+		ports[pid].dev_conf.link_speeds = link_speed;
 	}
 
 	cmd_reconfig_device_queue(RTE_PORT_ALL, 1, 1);
+
+	return;
 }
 
 cmdline_parse_token_string_t cmd_config_speed_all_port =
@@ -1000,8 +1029,7 @@ cmd_config_speed_specific_parsed(void *parsed_result,
 				__attribute__((unused)) void *data)
 {
 	struct cmd_config_speed_specific *res = parsed_result;
-	uint16_t link_speed = ETH_LINK_SPEED_AUTONEG;
-	uint16_t link_duplex = 0;
+	uint32_t link_speed;
 
 	if (!all_ports_stopped()) {
 		printf("Please stop all ports first\n");
@@ -1011,36 +1039,12 @@ cmd_config_speed_specific_parsed(void *parsed_result,
 	if (port_id_is_invalid(res->id, ENABLED_WARN))
 		return;
 
-	if (!strcmp(res->value1, "10"))
-		link_speed = ETH_LINK_SPEED_10;
-	else if (!strcmp(res->value1, "100"))
-		link_speed = ETH_LINK_SPEED_100;
-	else if (!strcmp(res->value1, "1000"))
-		link_speed = ETH_LINK_SPEED_1000;
-	else if (!strcmp(res->value1, "10000"))
-		link_speed = ETH_LINK_SPEED_10000;
-	else if (!strcmp(res->value1, "40000"))
-		link_speed = ETH_LINK_SPEED_40G;
-	else if (!strcmp(res->value1, "auto"))
-		link_speed = ETH_LINK_SPEED_AUTONEG;
-	else {
-		printf("Unknown parameter\n");
+	if (parse_and_check_speed_duplex(res->value1,
+						res->value2,
+						&link_speed) < 0)
 		return;
-	}
-
-	if (!strcmp(res->value2, "half"))
-		link_duplex = ETH_LINK_HALF_DUPLEX;
-	else if (!strcmp(res->value2, "full"))
-		link_duplex = ETH_LINK_FULL_DUPLEX;
-	else if (!strcmp(res->value2, "auto"))
-		link_duplex = ETH_LINK_AUTONEG_DUPLEX;
-	else {
-		printf("Unknown parameter\n");
-		return;
-	}
 
-	ports[res->id].dev_conf.link_speed = link_speed;
-	ports[res->id].dev_conf.link_duplex = link_duplex;
+	ports[res->id].dev_conf.link_speeds = link_speed;
 
 	cmd_reconfig_device_queue(RTE_PORT_ALL, 1, 1);
 }
diff --git a/app/test/virtual_pmd.c b/app/test/virtual_pmd.c
index a538c8a..3c4040b 100644
--- a/app/test/virtual_pmd.c
+++ b/app/test/virtual_pmd.c
@@ -603,8 +603,8 @@ virtual_ethdev_create(const char *name, struct ether_addr *mac_addr,
 
 	TAILQ_INIT(&(eth_dev->link_intr_cbs));
 
-	eth_dev->data->dev_link.link_status = 0;
-	eth_dev->data->dev_link.link_speed = ETH_LINK_SPEED_10000;
+	eth_dev->data->dev_link.link_status = ETH_LINK_DOWN;
+	eth_dev->data->dev_link.link_speed = ETH_SPEED_NUM_10G;
 	eth_dev->data->dev_link.link_duplex = ETH_LINK_FULL_DUPLEX;
 
 	eth_dev->data->mac_addrs = rte_zmalloc(name, ETHER_ADDR_LEN, 0);
diff --git a/drivers/net/af_packet/rte_eth_af_packet.c b/drivers/net/af_packet/rte_eth_af_packet.c
index bdd9628..a5d689d 100644
--- a/drivers/net/af_packet/rte_eth_af_packet.c
+++ b/drivers/net/af_packet/rte_eth_af_packet.c
@@ -115,9 +115,10 @@ static const char *valid_arguments[] = {
 static const char *drivername = "AF_PACKET PMD";
 
 static struct rte_eth_link pmd_link = {
-	.link_speed = 10000,
+	.link_speed = ETH_SPEED_NUM_10G,
 	.link_duplex = ETH_LINK_FULL_DUPLEX,
-	.link_status = 0
+	.link_status = ETH_LINK_DOWN,
+	.link_autoneg = ETH_LINK_SPEED_NEG
 };
 
 static uint16_t
diff --git a/drivers/net/bonding/rte_eth_bond_8023ad.c b/drivers/net/bonding/rte_eth_bond_8023ad.c
index c0f0b99..f375f95 100644
--- a/drivers/net/bonding/rte_eth_bond_8023ad.c
+++ b/drivers/net/bonding/rte_eth_bond_8023ad.c
@@ -708,25 +708,25 @@ link_speed_key(uint16_t speed) {
 	uint16_t key_speed;
 
 	switch (speed) {
-	case ETH_LINK_SPEED_AUTONEG:
+	case ETH_SPEED_NUM_NONE:
 		key_speed = 0x00;
 		break;
-	case ETH_LINK_SPEED_10:
+	case ETH_SPEED_NUM_10M:
 		key_speed = BOND_LINK_SPEED_KEY_10M;
 		break;
-	case ETH_LINK_SPEED_100:
+	case ETH_SPEED_NUM_100M:
 		key_speed = BOND_LINK_SPEED_KEY_100M;
 		break;
-	case ETH_LINK_SPEED_1000:
+	case ETH_SPEED_NUM_1G:
 		key_speed = BOND_LINK_SPEED_KEY_1000M;
 		break;
-	case ETH_LINK_SPEED_10G:
+	case ETH_SPEED_NUM_10G:
 		key_speed = BOND_LINK_SPEED_KEY_10G;
 		break;
-	case ETH_LINK_SPEED_20G:
+	case ETH_SPEED_NUM_20G:
 		key_speed = BOND_LINK_SPEED_KEY_20G;
 		break;
-	case ETH_LINK_SPEED_40G:
+	case ETH_SPEED_NUM_40G:
 		key_speed = BOND_LINK_SPEED_KEY_40G;
 		break;
 	default:
diff --git a/drivers/net/cxgbe/base/t4_hw.c b/drivers/net/cxgbe/base/t4_hw.c
index 884d2cf..79af806 100644
--- a/drivers/net/cxgbe/base/t4_hw.c
+++ b/drivers/net/cxgbe/base/t4_hw.c
@@ -2159,13 +2159,13 @@ int t4_handle_fw_rpl(struct adapter *adap, const __be64 *rpl)
 		if (stat & F_FW_PORT_CMD_TXPAUSE)
 			fc |= PAUSE_TX;
 		if (stat & V_FW_PORT_CMD_LSPEED(FW_PORT_CAP_SPEED_100M))
-			speed = ETH_LINK_SPEED_100;
+			speed = ETH_SPEED_NUM_100M;
 		else if (stat & V_FW_PORT_CMD_LSPEED(FW_PORT_CAP_SPEED_1G))
-			speed = ETH_LINK_SPEED_1000;
+			speed = ETH_SPEED_NUM_1G;
 		else if (stat & V_FW_PORT_CMD_LSPEED(FW_PORT_CAP_SPEED_10G))
-			speed = ETH_LINK_SPEED_10000;
+			speed = ETH_SPEED_NUM_10G;
 		else if (stat & V_FW_PORT_CMD_LSPEED(FW_PORT_CAP_SPEED_40G))
-			speed = ETH_LINK_SPEED_40G;
+			speed = ETH_SPEED_NUM_40G;
 
 		for_each_port(adap, i) {
 			pi = adap2pinfo(adap, i);
diff --git a/drivers/net/e1000/base/e1000_80003es2lan.c b/drivers/net/e1000/base/e1000_80003es2lan.c
index 72692d9..8ca66c4 100644
--- a/drivers/net/e1000/base/e1000_80003es2lan.c
+++ b/drivers/net/e1000/base/e1000_80003es2lan.c
@@ -52,7 +52,7 @@ STATIC s32  e1000_write_nvm_80003es2lan(struct e1000_hw *hw, u16 offset,
 STATIC s32  e1000_get_cfg_done_80003es2lan(struct e1000_hw *hw);
 STATIC s32  e1000_phy_force_speed_duplex_80003es2lan(struct e1000_hw *hw);
 STATIC s32  e1000_get_cable_length_80003es2lan(struct e1000_hw *hw);
-STATIC s32  e1000_get_link_up_info_80003es2lan(struct e1000_hw *hw, u16 *speed,
+STATIC s32  e1000_get_link_up_info_80003es2lan(struct e1000_hw *hw, u32 *speed,
 					       u16 *duplex);
 STATIC s32  e1000_reset_hw_80003es2lan(struct e1000_hw *hw);
 STATIC s32  e1000_init_hw_80003es2lan(struct e1000_hw *hw);
@@ -789,7 +789,7 @@ STATIC s32 e1000_get_cable_length_80003es2lan(struct e1000_hw *hw)
  *
  *  Retrieve the current speed and duplex configuration.
  **/
-STATIC s32 e1000_get_link_up_info_80003es2lan(struct e1000_hw *hw, u16 *speed,
+STATIC s32 e1000_get_link_up_info_80003es2lan(struct e1000_hw *hw, u32 *speed,
 					      u16 *duplex)
 {
 	s32 ret_val;
@@ -1236,7 +1236,7 @@ STATIC s32 e1000_setup_copper_link_80003es2lan(struct e1000_hw *hw)
 STATIC s32 e1000_cfg_on_link_up_80003es2lan(struct e1000_hw *hw)
 {
 	s32 ret_val = E1000_SUCCESS;
-	u16 speed;
+	u32 speed;
 	u16 duplex;
 
 	DEBUGFUNC("e1000_configure_on_link_up");
diff --git a/drivers/net/e1000/base/e1000_82541.c b/drivers/net/e1000/base/e1000_82541.c
index 952aea2..707b317 100644
--- a/drivers/net/e1000/base/e1000_82541.c
+++ b/drivers/net/e1000/base/e1000_82541.c
@@ -47,7 +47,7 @@ STATIC s32  e1000_init_nvm_params_82541(struct e1000_hw *hw);
 STATIC s32  e1000_init_mac_params_82541(struct e1000_hw *hw);
 STATIC s32  e1000_reset_hw_82541(struct e1000_hw *hw);
 STATIC s32  e1000_init_hw_82541(struct e1000_hw *hw);
-STATIC s32  e1000_get_link_up_info_82541(struct e1000_hw *hw, u16 *speed,
+STATIC s32  e1000_get_link_up_info_82541(struct e1000_hw *hw, u32 *speed,
 					 u16 *duplex);
 STATIC s32  e1000_phy_hw_reset_82541(struct e1000_hw *hw);
 STATIC s32  e1000_setup_copper_link_82541(struct e1000_hw *hw);
@@ -437,7 +437,7 @@ out:
  *
  * Retrieve the current speed and duplex configuration.
  **/
-STATIC s32 e1000_get_link_up_info_82541(struct e1000_hw *hw, u16 *speed,
+STATIC s32 e1000_get_link_up_info_82541(struct e1000_hw *hw, u32 *speed,
 					u16 *duplex)
 {
 	struct e1000_phy_info *phy = &hw->phy;
@@ -667,8 +667,8 @@ STATIC s32 e1000_config_dsp_after_link_change_82541(struct e1000_hw *hw,
 	struct e1000_phy_info *phy = &hw->phy;
 	struct e1000_dev_spec_82541 *dev_spec = &hw->dev_spec._82541;
 	s32 ret_val;
-	u32 idle_errs = 0;
-	u16 phy_data, phy_saved_data, speed, duplex, i;
+	u32 idle_errs = 0, speed;
+	u16 phy_data, phy_saved_data, duplex, i;
 	u16 ffe_idle_err_timeout = FFE_IDLE_ERR_COUNT_TIMEOUT_20;
 	u16 dsp_reg_array[IGP01E1000_PHY_CHANNEL_NUM] = {
 						IGP01E1000_PHY_AGC_PARAM_A,
diff --git a/drivers/net/e1000/base/e1000_82543.c b/drivers/net/e1000/base/e1000_82543.c
index 36335ba..9ef3d80 100644
--- a/drivers/net/e1000/base/e1000_82543.c
+++ b/drivers/net/e1000/base/e1000_82543.c
@@ -1192,9 +1192,9 @@ out:
 STATIC s32 e1000_check_for_copper_link_82543(struct e1000_hw *hw)
 {
 	struct e1000_mac_info *mac = &hw->mac;
-	u32 icr, rctl;
+	u32 icr, rctl, speed;
 	s32 ret_val;
-	u16 speed, duplex;
+	u16 duplex;
 	bool link;
 
 	DEBUGFUNC("e1000_check_for_copper_link_82543");
diff --git a/drivers/net/e1000/base/e1000_82575.c b/drivers/net/e1000/base/e1000_82575.c
index 25fa672..386f058 100644
--- a/drivers/net/e1000/base/e1000_82575.c
+++ b/drivers/net/e1000/base/e1000_82575.c
@@ -53,7 +53,7 @@ STATIC void e1000_release_nvm_82575(struct e1000_hw *hw);
 STATIC s32  e1000_check_for_link_82575(struct e1000_hw *hw);
 STATIC s32  e1000_check_for_link_media_swap(struct e1000_hw *hw);
 STATIC s32  e1000_get_cfg_done_82575(struct e1000_hw *hw);
-STATIC s32  e1000_get_link_up_info_82575(struct e1000_hw *hw, u16 *speed,
+STATIC s32  e1000_get_link_up_info_82575(struct e1000_hw *hw, u32 *speed,
 					 u16 *duplex);
 STATIC s32  e1000_phy_hw_reset_sgmii_82575(struct e1000_hw *hw);
 STATIC s32  e1000_read_phy_reg_sgmii_82575(struct e1000_hw *hw, u32 offset,
@@ -80,7 +80,7 @@ STATIC s32  e1000_write_phy_reg_sgmii_82575(struct e1000_hw *hw,
 STATIC void e1000_clear_hw_cntrs_82575(struct e1000_hw *hw);
 STATIC s32  e1000_acquire_swfw_sync_82575(struct e1000_hw *hw, u16 mask);
 STATIC s32  e1000_get_pcs_speed_and_duplex_82575(struct e1000_hw *hw,
-						 u16 *speed, u16 *duplex);
+						 u32 *speed, u16 *duplex);
 STATIC s32  e1000_get_phy_id_82575(struct e1000_hw *hw);
 STATIC void e1000_release_swfw_sync_82575(struct e1000_hw *hw, u16 mask);
 STATIC bool e1000_sgmii_active_82575(struct e1000_hw *hw);
@@ -1165,7 +1165,7 @@ STATIC s32 e1000_get_cfg_done_82575(struct e1000_hw *hw)
  *  interface, use PCS to retrieve the link speed and duplex information.
  *  Otherwise, use the generic function to get the link speed and duplex info.
  **/
-STATIC s32 e1000_get_link_up_info_82575(struct e1000_hw *hw, u16 *speed,
+STATIC s32 e1000_get_link_up_info_82575(struct e1000_hw *hw, u32 *speed,
 					u16 *duplex)
 {
 	s32 ret_val;
@@ -1192,7 +1192,8 @@ STATIC s32 e1000_get_link_up_info_82575(struct e1000_hw *hw, u16 *speed,
 STATIC s32 e1000_check_for_link_82575(struct e1000_hw *hw)
 {
 	s32 ret_val;
-	u16 speed, duplex;
+	u32 speed;
+	u16 duplex;
 
 	DEBUGFUNC("e1000_check_for_link_82575");
 
@@ -1316,7 +1317,7 @@ STATIC void e1000_power_up_serdes_link_82575(struct e1000_hw *hw)
  *  duplex, then store the values in the pointers provided.
  **/
 STATIC s32 e1000_get_pcs_speed_and_duplex_82575(struct e1000_hw *hw,
-						u16 *speed, u16 *duplex)
+						u32 *speed, u16 *duplex)
 {
 	struct e1000_mac_info *mac = &hw->mac;
 	u32 pcs;
diff --git a/drivers/net/e1000/base/e1000_api.c b/drivers/net/e1000/base/e1000_api.c
index a064565..08e103a 100644
--- a/drivers/net/e1000/base/e1000_api.c
+++ b/drivers/net/e1000/base/e1000_api.c
@@ -669,7 +669,7 @@ s32 e1000_setup_link(struct e1000_hw *hw)
  *  variables passed in. This is a function pointer entry point called
  *  by drivers.
  **/
-s32 e1000_get_speed_and_duplex(struct e1000_hw *hw, u16 *speed, u16 *duplex)
+s32 e1000_get_speed_and_duplex(struct e1000_hw *hw, u32 *speed, u16 *duplex)
 {
 	if (hw->mac.ops.get_link_up_info)
 		return hw->mac.ops.get_link_up_info(hw, speed, duplex);
diff --git a/drivers/net/e1000/base/e1000_api.h b/drivers/net/e1000/base/e1000_api.h
index 02b16da..39579e0 100644
--- a/drivers/net/e1000/base/e1000_api.h
+++ b/drivers/net/e1000/base/e1000_api.h
@@ -65,7 +65,7 @@ s32 e1000_check_for_link(struct e1000_hw *hw);
 s32 e1000_reset_hw(struct e1000_hw *hw);
 s32 e1000_init_hw(struct e1000_hw *hw);
 s32 e1000_setup_link(struct e1000_hw *hw);
-s32 e1000_get_speed_and_duplex(struct e1000_hw *hw, u16 *speed, u16 *duplex);
+s32 e1000_get_speed_and_duplex(struct e1000_hw *hw, u32 *speed, u16 *duplex);
 s32 e1000_disable_pcie_master(struct e1000_hw *hw);
 void e1000_config_collision_dist(struct e1000_hw *hw);
 void e1000_rar_set(struct e1000_hw *hw, u8 *addr, u32 index);
diff --git a/drivers/net/e1000/base/e1000_defines.h b/drivers/net/e1000/base/e1000_defines.h
index 278c507..20c4153 100644
--- a/drivers/net/e1000/base/e1000_defines.h
+++ b/drivers/net/e1000/base/e1000_defines.h
@@ -347,8 +347,8 @@ POSSIBILITY OF SUCH DAMAGE.
 #define SPEED_100	100
 #define SPEED_1000	1000
 #define SPEED_2500	2500
-#define HALF_DUPLEX	1
-#define FULL_DUPLEX	2
+#define HALF_DUPLEX	0
+#define FULL_DUPLEX	1
 
 #define PHY_FORCE_TIME	20
 
diff --git a/drivers/net/e1000/base/e1000_hw.h b/drivers/net/e1000/base/e1000_hw.h
index 4dd92a3..b48a759 100644
--- a/drivers/net/e1000/base/e1000_hw.h
+++ b/drivers/net/e1000/base/e1000_hw.h
@@ -682,7 +682,7 @@ struct e1000_mac_operations {
 	void (*clear_vfta)(struct e1000_hw *);
 	s32  (*get_bus_info)(struct e1000_hw *);
 	void (*set_lan_id)(struct e1000_hw *);
-	s32  (*get_link_up_info)(struct e1000_hw *, u16 *, u16 *);
+	s32  (*get_link_up_info)(struct e1000_hw *, u32 *, u16 *);
 	s32  (*led_on)(struct e1000_hw *);
 	s32  (*led_off)(struct e1000_hw *);
 	void (*update_mc_addr_list)(struct e1000_hw *, u8 *, u32);
diff --git a/drivers/net/e1000/base/e1000_ich8lan.c b/drivers/net/e1000/base/e1000_ich8lan.c
index 3b1627b..7fe9955 100644
--- a/drivers/net/e1000/base/e1000_ich8lan.c
+++ b/drivers/net/e1000/base/e1000_ich8lan.c
@@ -104,7 +104,7 @@ STATIC s32  e1000_setup_link_ich8lan(struct e1000_hw *hw);
 STATIC s32  e1000_setup_copper_link_ich8lan(struct e1000_hw *hw);
 STATIC s32  e1000_setup_copper_link_pch_lpt(struct e1000_hw *hw);
 STATIC s32  e1000_get_link_up_info_ich8lan(struct e1000_hw *hw,
-					   u16 *speed, u16 *duplex);
+					   u32 *speed, u16 *duplex);
 STATIC s32  e1000_cleanup_led_ich8lan(struct e1000_hw *hw);
 STATIC s32  e1000_led_on_ich8lan(struct e1000_hw *hw);
 STATIC s32  e1000_led_off_ich8lan(struct e1000_hw *hw);
@@ -4561,7 +4561,7 @@ STATIC s32 e1000_setup_copper_link_pch_lpt(struct e1000_hw *hw)
  *  information and then calls the Kumeran lock loss workaround for links at
  *  gigabit speeds.
  **/
-STATIC s32 e1000_get_link_up_info_ich8lan(struct e1000_hw *hw, u16 *speed,
+STATIC s32 e1000_get_link_up_info_ich8lan(struct e1000_hw *hw, u32 *speed,
 					  u16 *duplex)
 {
 	s32 ret_val;
diff --git a/drivers/net/e1000/base/e1000_mac.c b/drivers/net/e1000/base/e1000_mac.c
index c8ec049..6703a17 100644
--- a/drivers/net/e1000/base/e1000_mac.c
+++ b/drivers/net/e1000/base/e1000_mac.c
@@ -106,7 +106,7 @@ void e1000_null_mac_generic(struct e1000_hw E1000_UNUSEDARG *hw)
  *  @hw: pointer to the HW structure
  **/
 s32 e1000_null_link_info(struct e1000_hw E1000_UNUSEDARG *hw,
-			 u16 E1000_UNUSEDARG *s, u16 E1000_UNUSEDARG *d)
+			 u32 E1000_UNUSEDARG *s, u16 E1000_UNUSEDARG *d)
 {
 	DEBUGFUNC("e1000_null_link_info");
 	UNREFERENCED_3PARAMETER(hw, s, d);
@@ -1346,7 +1346,8 @@ s32 e1000_config_fc_after_link_up_generic(struct e1000_hw *hw)
 	s32 ret_val = E1000_SUCCESS;
 	u32 pcs_status_reg, pcs_adv_reg, pcs_lp_ability_reg, pcs_ctrl_reg;
 	u16 mii_status_reg, mii_nway_adv_reg, mii_nway_lp_ability_reg;
-	u16 speed, duplex;
+	u32 speed;
+	u16 duplex;
 
 	DEBUGFUNC("e1000_config_fc_after_link_up_generic");
 
@@ -1648,7 +1649,7 @@ s32 e1000_config_fc_after_link_up_generic(struct e1000_hw *hw)
  *  Read the status register for the current speed/duplex and store the current
  *  speed and duplex for copper connections.
  **/
-s32 e1000_get_speed_and_duplex_copper_generic(struct e1000_hw *hw, u16 *speed,
+s32 e1000_get_speed_and_duplex_copper_generic(struct e1000_hw *hw, u32 *speed,
 					      u16 *duplex)
 {
 	u32 status;
@@ -1688,7 +1689,7 @@ s32 e1000_get_speed_and_duplex_copper_generic(struct e1000_hw *hw, u16 *speed,
  *  for fiber/serdes links.
  **/
 s32 e1000_get_speed_and_duplex_fiber_serdes_generic(struct e1000_hw E1000_UNUSEDARG *hw,
-						    u16 *speed, u16 *duplex)
+						    u32 *speed, u16 *duplex)
 {
 	DEBUGFUNC("e1000_get_speed_and_duplex_fiber_serdes_generic");
 	UNREFERENCED_1PARAMETER(hw);
diff --git a/drivers/net/e1000/base/e1000_mac.h b/drivers/net/e1000/base/e1000_mac.h
index 5a7ce4a..987df76 100644
--- a/drivers/net/e1000/base/e1000_mac.h
+++ b/drivers/net/e1000/base/e1000_mac.h
@@ -40,7 +40,7 @@ void e1000_init_mac_ops_generic(struct e1000_hw *hw);
 #endif /* E1000_REMOVED */
 void e1000_null_mac_generic(struct e1000_hw *hw);
 s32  e1000_null_ops_generic(struct e1000_hw *hw);
-s32  e1000_null_link_info(struct e1000_hw *hw, u16 *s, u16 *d);
+s32  e1000_null_link_info(struct e1000_hw *hw, u32 *s, u16 *d);
 bool e1000_null_mng_mode(struct e1000_hw *hw);
 void e1000_null_update_mc(struct e1000_hw *hw, u8 *h, u32 a);
 void e1000_null_write_vfta(struct e1000_hw *hw, u32 a, u32 b);
@@ -61,10 +61,10 @@ s32  e1000_get_bus_info_pcie_generic(struct e1000_hw *hw);
 void e1000_set_lan_id_single_port(struct e1000_hw *hw);
 void e1000_set_lan_id_multi_port_pci(struct e1000_hw *hw);
 s32  e1000_get_hw_semaphore_generic(struct e1000_hw *hw);
-s32  e1000_get_speed_and_duplex_copper_generic(struct e1000_hw *hw, u16 *speed,
+s32  e1000_get_speed_and_duplex_copper_generic(struct e1000_hw *hw, u32 *speed,
 					       u16 *duplex);
 s32  e1000_get_speed_and_duplex_fiber_serdes_generic(struct e1000_hw *hw,
-						     u16 *speed, u16 *duplex);
+						     u32 *speed, u16 *duplex);
 s32  e1000_id_led_init_generic(struct e1000_hw *hw);
 s32  e1000_led_on_generic(struct e1000_hw *hw);
 s32  e1000_led_off_generic(struct e1000_hw *hw);
diff --git a/drivers/net/e1000/base/e1000_vf.c b/drivers/net/e1000/base/e1000_vf.c
index 778561e..2221f1c 100644
--- a/drivers/net/e1000/base/e1000_vf.c
+++ b/drivers/net/e1000/base/e1000_vf.c
@@ -43,7 +43,7 @@ STATIC s32 e1000_setup_link_vf(struct e1000_hw *hw);
 STATIC s32 e1000_get_bus_info_pcie_vf(struct e1000_hw *hw);
 STATIC s32 e1000_init_mac_params_vf(struct e1000_hw *hw);
 STATIC s32 e1000_check_for_link_vf(struct e1000_hw *hw);
-STATIC s32 e1000_get_link_up_info_vf(struct e1000_hw *hw, u16 *speed,
+STATIC s32 e1000_get_link_up_info_vf(struct e1000_hw *hw, u32 *speed,
 				     u16 *duplex);
 STATIC s32 e1000_init_hw_vf(struct e1000_hw *hw);
 STATIC s32 e1000_reset_hw_vf(struct e1000_hw *hw);
@@ -220,7 +220,7 @@ STATIC s32 e1000_get_bus_info_pcie_vf(struct e1000_hw *hw)
  *  Since we cannot read the PHY and get accurate link info, we must rely upon
  *  the status register's data which is often stale and inaccurate.
  **/
-STATIC s32 e1000_get_link_up_info_vf(struct e1000_hw *hw, u16 *speed,
+STATIC s32 e1000_get_link_up_info_vf(struct e1000_hw *hw, u32 *speed,
 				     u16 *duplex)
 {
 	s32 status;
diff --git a/drivers/net/e1000/base/e1000_vf.h b/drivers/net/e1000/base/e1000_vf.h
index 6d5bd99..9d801ad 100644
--- a/drivers/net/e1000/base/e1000_vf.h
+++ b/drivers/net/e1000/base/e1000_vf.h
@@ -201,7 +201,7 @@ struct e1000_mac_operations {
 	s32  (*check_for_link)(struct e1000_hw *);
 	void (*clear_vfta)(struct e1000_hw *);
 	s32  (*get_bus_info)(struct e1000_hw *);
-	s32  (*get_link_up_info)(struct e1000_hw *, u16 *, u16 *);
+	s32  (*get_link_up_info)(struct e1000_hw *, u32 *, u16 *);
 	void (*update_mc_addr_list)(struct e1000_hw *, u8 *, u32);
 	s32  (*reset_hw)(struct e1000_hw *);
 	s32  (*init_hw)(struct e1000_hw *);
diff --git a/drivers/net/e1000/em_ethdev.c b/drivers/net/e1000/em_ethdev.c
index 72f792c..35ef558 100644
--- a/drivers/net/e1000/em_ethdev.c
+++ b/drivers/net/e1000/em_ethdev.c
@@ -493,6 +493,9 @@ eth_em_start(struct rte_eth_dev *dev)
 	struct e1000_hw *hw =
 		E1000_DEV_PRIVATE_TO_HW(dev->data->dev_private);
 	int ret, mask;
+	uint32_t *speeds;
+	int num_speeds;
+	bool autoneg;
 
 	PMD_INIT_FUNC_TRACE();
 
@@ -547,56 +550,46 @@ eth_em_start(struct rte_eth_dev *dev)
 	E1000_WRITE_REG(hw, E1000_ITR, UINT16_MAX);
 
 	/* Setup link speed and duplex */
-	switch (dev->data->dev_conf.link_speed) {
-	case ETH_LINK_SPEED_AUTONEG:
-		if (dev->data->dev_conf.link_duplex == ETH_LINK_AUTONEG_DUPLEX)
-			hw->phy.autoneg_advertised = E1000_ALL_SPEED_DUPLEX;
-		else if (dev->data->dev_conf.link_duplex ==
-					ETH_LINK_HALF_DUPLEX)
-			hw->phy.autoneg_advertised = E1000_ALL_HALF_DUPLEX;
-		else if (dev->data->dev_conf.link_duplex ==
-					ETH_LINK_FULL_DUPLEX)
-			hw->phy.autoneg_advertised = E1000_ALL_FULL_DUPLEX;
-		else
-			goto error_invalid_config;
-		break;
-	case ETH_LINK_SPEED_10:
-		if (dev->data->dev_conf.link_duplex == ETH_LINK_AUTONEG_DUPLEX)
-			hw->phy.autoneg_advertised = E1000_ALL_10_SPEED;
-		else if (dev->data->dev_conf.link_duplex ==
-					ETH_LINK_HALF_DUPLEX)
-			hw->phy.autoneg_advertised = ADVERTISE_10_HALF;
-		else if (dev->data->dev_conf.link_duplex ==
-					ETH_LINK_FULL_DUPLEX)
-			hw->phy.autoneg_advertised = ADVERTISE_10_FULL;
-		else
-			goto error_invalid_config;
-		break;
-	case ETH_LINK_SPEED_100:
-		if (dev->data->dev_conf.link_duplex == ETH_LINK_AUTONEG_DUPLEX)
-			hw->phy.autoneg_advertised = E1000_ALL_100_SPEED;
-		else if (dev->data->dev_conf.link_duplex ==
-					ETH_LINK_HALF_DUPLEX)
-			hw->phy.autoneg_advertised = ADVERTISE_100_HALF;
-		else if (dev->data->dev_conf.link_duplex ==
-					ETH_LINK_FULL_DUPLEX)
-			hw->phy.autoneg_advertised = ADVERTISE_100_FULL;
-		else
+	speeds = &dev->data->dev_conf.link_speeds;
+	if (*speeds == ETH_LINK_SPEED_AUTONEG) {
+		hw->phy.autoneg_advertised = E1000_ALL_SPEED_DUPLEX;
+	} else {
+		num_speeds = 0;
+		autoneg = ~(*speeds & ETH_LINK_SPEED_NO_AUTONEG);
+
+		/* Reset */
+		hw->phy.autoneg_advertised = 0;
+
+		if (*speeds & ~(ETH_LINK_SPEED_10M_HD | ETH_LINK_SPEED_10M |
+				ETH_LINK_SPEED_100M_HD | ETH_LINK_SPEED_100M |
+				ETH_LINK_SPEED_1G)) {
+			num_speeds = -1;
 			goto error_invalid_config;
-		break;
-	case ETH_LINK_SPEED_1000:
-		if ((dev->data->dev_conf.link_duplex ==
-				ETH_LINK_AUTONEG_DUPLEX) ||
-			(dev->data->dev_conf.link_duplex ==
-					ETH_LINK_FULL_DUPLEX))
-			hw->phy.autoneg_advertised = ADVERTISE_1000_FULL;
-		else
+		}
+		if (*speeds & ETH_LINK_SPEED_10M_HD) {
+			hw->phy.autoneg_advertised |= ADVERTISE_10_HALF;
+			num_speeds++;
+		}
+		if (*speeds & ETH_LINK_SPEED_10M) {
+			hw->phy.autoneg_advertised |= ADVERTISE_10_FULL;
+			num_speeds++;
+		}
+		if (*speeds & ETH_LINK_SPEED_100M_HD) {
+			hw->phy.autoneg_advertised |= ADVERTISE_100_HALF;
+			num_speeds++;
+		}
+		if (*speeds & ETH_LINK_SPEED_100M) {
+			hw->phy.autoneg_advertised |= ADVERTISE_100_FULL;
+			num_speeds++;
+		}
+		if (*speeds & ETH_LINK_SPEED_1G) {
+			hw->phy.autoneg_advertised |= ADVERTISE_1000_FULL;
+			num_speeds++;
+		}
+		if (num_speeds == 0 || (!autoneg && (num_speeds > 2)))
 			goto error_invalid_config;
-		break;
-	case ETH_LINK_SPEED_10000:
-	default:
-		goto error_invalid_config;
 	}
+
 	e1000_setup_link(hw);
 
 	/* check if lsc interrupt feature is enabled */
@@ -616,9 +609,8 @@ eth_em_start(struct rte_eth_dev *dev)
 	return (0);
 
 error_invalid_config:
-	PMD_INIT_LOG(ERR, "Invalid link_speed/link_duplex (%u/%u) for port %u",
-		     dev->data->dev_conf.link_speed,
-		     dev->data->dev_conf.link_duplex, dev->data->port_id);
+	PMD_INIT_LOG(ERR, "Invalid advertised speeds (%u) for port %u",
+		     dev->data->dev_conf.link_speeds, dev->data->port_id);
 	em_dev_clear_queues(dev);
 	return (-EINVAL);
 }
@@ -934,11 +926,11 @@ eth_em_infos_get(struct rte_eth_dev *dev, struct rte_eth_dev_info *dev_info)
 	dev_info->max_rx_queues = 1;
 	dev_info->max_tx_queues = 1;
 
-	dev_info->speed_capa = ETH_SPEED_CAP_10M_HD |
-					ETH_SPEED_CAP_10M_FD |
-					ETH_SPEED_CAP_100M_HD |
-					ETH_SPEED_CAP_100M_FD |
-					ETH_SPEED_CAP_1G;
+	dev_info->speed_capa = ETH_LINK_SPEED_10M_HD |
+					ETH_LINK_SPEED_10M |
+					ETH_LINK_SPEED_100M_HD |
+					ETH_LINK_SPEED_100M |
+					ETH_LINK_SPEED_1G;
 }
 
 /* return 0 means link status changed, -1 means not changed */
@@ -987,13 +979,16 @@ eth_em_link_update(struct rte_eth_dev *dev, int wait_to_complete)
 
 	/* Now we check if a transition has happened */
 	if (link_check && (link.link_status == 0)) {
+		uint16_t duplex;
 		hw->mac.ops.get_link_up_info(hw, &link.link_speed,
-			&link.link_duplex);
-		link.link_status = 1;
+			&duplex);
+		link.link_duplex = (duplex) ? ETH_LINK_FULL_DUPLEX :
+						ETH_LINK_HALF_DUPLEX;
+		link.link_status = ETH_LINK_UP;
 	} else if (!link_check && (link.link_status == 1)) {
 		link.link_speed = 0;
-		link.link_duplex = 0;
-		link.link_status = 0;
+		link.link_duplex = ETH_LINK_HALF_DUPLEX;
+		link.link_status = ETH_LINK_DOWN;
 	}
 	rte_em_dev_atomic_write_link_status(dev, &link);
 
diff --git a/drivers/net/e1000/igb_ethdev.c b/drivers/net/e1000/igb_ethdev.c
index 927f5d9..2bbac02 100644
--- a/drivers/net/e1000/igb_ethdev.c
+++ b/drivers/net/e1000/igb_ethdev.c
@@ -889,6 +889,9 @@ eth_igb_start(struct rte_eth_dev *dev)
 	int ret, mask;
 	uint32_t intr_vector = 0;
 	uint32_t ctrl_ext;
+	uint32_t *speeds;
+	int num_speeds;
+	bool autoneg;
 
 	PMD_INIT_FUNC_TRACE();
 
@@ -984,48 +987,46 @@ eth_igb_start(struct rte_eth_dev *dev)
 	}
 
 	/* Setup link speed and duplex */
-	switch (dev->data->dev_conf.link_speed) {
-	case ETH_LINK_SPEED_AUTONEG:
-		if (dev->data->dev_conf.link_duplex == ETH_LINK_AUTONEG_DUPLEX)
-			hw->phy.autoneg_advertised = E1000_ALL_SPEED_DUPLEX;
-		else if (dev->data->dev_conf.link_duplex == ETH_LINK_HALF_DUPLEX)
-			hw->phy.autoneg_advertised = E1000_ALL_HALF_DUPLEX;
-		else if (dev->data->dev_conf.link_duplex == ETH_LINK_FULL_DUPLEX)
-			hw->phy.autoneg_advertised = E1000_ALL_FULL_DUPLEX;
-		else
-			goto error_invalid_config;
-		break;
-	case ETH_LINK_SPEED_10:
-		if (dev->data->dev_conf.link_duplex == ETH_LINK_AUTONEG_DUPLEX)
-			hw->phy.autoneg_advertised = E1000_ALL_10_SPEED;
-		else if (dev->data->dev_conf.link_duplex == ETH_LINK_HALF_DUPLEX)
-			hw->phy.autoneg_advertised = ADVERTISE_10_HALF;
-		else if (dev->data->dev_conf.link_duplex == ETH_LINK_FULL_DUPLEX)
-			hw->phy.autoneg_advertised = ADVERTISE_10_FULL;
-		else
-			goto error_invalid_config;
-		break;
-	case ETH_LINK_SPEED_100:
-		if (dev->data->dev_conf.link_duplex == ETH_LINK_AUTONEG_DUPLEX)
-			hw->phy.autoneg_advertised = E1000_ALL_100_SPEED;
-		else if (dev->data->dev_conf.link_duplex == ETH_LINK_HALF_DUPLEX)
-			hw->phy.autoneg_advertised = ADVERTISE_100_HALF;
-		else if (dev->data->dev_conf.link_duplex == ETH_LINK_FULL_DUPLEX)
-			hw->phy.autoneg_advertised = ADVERTISE_100_FULL;
-		else
+	speeds = &dev->data->dev_conf.link_speeds;
+	if (*speeds == ETH_LINK_SPEED_AUTONEG) {
+		hw->phy.autoneg_advertised = E1000_ALL_SPEED_DUPLEX;
+	} else {
+		num_speeds = 0;
+		autoneg = ~(*speeds & ETH_LINK_SPEED_NO_AUTONEG);
+
+		/* Reset */
+		hw->phy.autoneg_advertised = 0;
+
+		if (*speeds & ~(ETH_LINK_SPEED_10M_HD | ETH_LINK_SPEED_10M |
+				ETH_LINK_SPEED_100M_HD | ETH_LINK_SPEED_100M |
+				ETH_LINK_SPEED_1G)) {
+			num_speeds = -1;
 			goto error_invalid_config;
-		break;
-	case ETH_LINK_SPEED_1000:
-		if ((dev->data->dev_conf.link_duplex == ETH_LINK_AUTONEG_DUPLEX) ||
-				(dev->data->dev_conf.link_duplex == ETH_LINK_FULL_DUPLEX))
-			hw->phy.autoneg_advertised = ADVERTISE_1000_FULL;
-		else
+		}
+		if (*speeds & ETH_LINK_SPEED_10M_HD) {
+			hw->phy.autoneg_advertised |= ADVERTISE_10_HALF;
+			num_speeds++;
+		}
+		if (*speeds & ETH_LINK_SPEED_10M) {
+			hw->phy.autoneg_advertised |= ADVERTISE_10_FULL;
+			num_speeds++;
+		}
+		if (*speeds & ETH_LINK_SPEED_100M_HD) {
+			hw->phy.autoneg_advertised |= ADVERTISE_100_HALF;
+			num_speeds++;
+		}
+		if (*speeds & ETH_LINK_SPEED_100M) {
+			hw->phy.autoneg_advertised |= ADVERTISE_100_FULL;
+			num_speeds++;
+		}
+		if (*speeds & ETH_LINK_SPEED_1G) {
+			hw->phy.autoneg_advertised |= ADVERTISE_1000_FULL;
+			num_speeds++;
+		}
+		if (num_speeds == 0 || (!autoneg && (num_speeds > 2)))
 			goto error_invalid_config;
-		break;
-	case ETH_LINK_SPEED_10000:
-	default:
-		goto error_invalid_config;
 	}
+
 	e1000_setup_link(hw);
 
 	/* check if lsc interrupt feature is enabled */
@@ -1055,9 +1056,8 @@ eth_igb_start(struct rte_eth_dev *dev)
 	return (0);
 
 error_invalid_config:
-	PMD_INIT_LOG(ERR, "Invalid link_speed/link_duplex (%u/%u) for port %u",
-		     dev->data->dev_conf.link_speed,
-		     dev->data->dev_conf.link_duplex, dev->data->port_id);
+	PMD_INIT_LOG(ERR, "Invalid advertised speeds (%u) for port %u",
+		     dev->data->dev_conf.link_speeds, dev->data->port_id);
 	igb_dev_clear_queues(dev);
 	return (-EINVAL);
 }
@@ -1571,11 +1571,11 @@ eth_igb_infos_get(struct rte_eth_dev *dev, struct rte_eth_dev_info *dev_info)
 		.txq_flags = 0,
 	};
 
-	dev_info->speed_capa = ETH_SPEED_CAP_10M_HD |
-					ETH_SPEED_CAP_10M_FD |
-					ETH_SPEED_CAP_100M_HD |
-					ETH_SPEED_CAP_100M_FD |
-					ETH_SPEED_CAP_1G;
+	dev_info->speed_capa = ETH_LINK_SPEED_10M_HD |
+					ETH_LINK_SPEED_10M |
+					ETH_LINK_SPEED_100M_HD |
+					ETH_LINK_SPEED_100M |
+					ETH_LINK_SPEED_1G;
 }
 
 static void
@@ -1681,13 +1681,19 @@ eth_igb_link_update(struct rte_eth_dev *dev, int wait_to_complete)
 
 	/* Now we check if a transition has happened */
 	if (link_check) {
+		uint16_t duplex;
 		hw->mac.ops.get_link_up_info(hw, &link.link_speed,
-					  &link.link_duplex);
-		link.link_status = 1;
+					  &duplex);
+		link.link_duplex = (duplex) ? ETH_LINK_FULL_DUPLEX :
+							ETH_LINK_HALF_DUPLEX ;
+		link.link_status = ETH_LINK_UP;
+		link.link_autoneg = ~(dev->data->dev_conf.link_speeds &
+						ETH_LINK_SPEED_NO_AUTONEG);
 	} else if (!link_check) {
 		link.link_speed = 0;
-		link.link_duplex = 0;
-		link.link_status = 0;
+		link.link_duplex = ETH_LINK_HALF_DUPLEX;
+		link.link_status = ETH_LINK_DOWN;
+		link.link_autoneg = ETH_LINK_SPEED_FIXED;
 	}
 	rte_igb_dev_atomic_write_link_status(dev, &link);
 
diff --git a/drivers/net/fm10k/fm10k_ethdev.c b/drivers/net/fm10k/fm10k_ethdev.c
index ca6357c..6e05355 100644
--- a/drivers/net/fm10k/fm10k_ethdev.c
+++ b/drivers/net/fm10k/fm10k_ethdev.c
@@ -862,7 +862,7 @@ fm10k_link_update(struct rte_eth_dev *dev,
 	 * is no 50Gbps Ethernet. */
 	dev->data->dev_link.link_speed  = 0;
 	dev->data->dev_link.link_duplex = ETH_LINK_FULL_DUPLEX;
-	dev->data->dev_link.link_status = 1;
+	dev->data->dev_link.link_status = ETH_LINK_UP;
 
 	return 0;
 }
@@ -964,9 +964,9 @@ fm10k_dev_infos_get(struct rte_eth_dev *dev,
 				ETH_TXQ_FLAGS_NOOFFLOADS,
 	};
 
-	dev_info->speed_capa = ETH_SPEED_CAP_1G | ETH_SPEED_CAP_2_5G |
-					ETH_SPEED_CAP_10G | ETH_SPEED_CAP_25G |
-					ETH_SPEED_CAP_40G | ETH_SPEED_CAP_100G;
+	dev_info->speed_capa = ETH_LINK_SPEED_1G | ETH_LINK_SPEED_2_5G |
+				ETH_LINK_SPEED_10G | ETH_LINK_SPEED_25G |
+				ETH_LINK_SPEED_40G | ETH_LINK_SPEED_100G;
 }
 
 static int
diff --git a/drivers/net/i40e/i40e_ethdev.c b/drivers/net/i40e/i40e_ethdev.c
index 8a5dfbf..b18e81f 100644
--- a/drivers/net/i40e/i40e_ethdev.c
+++ b/drivers/net/i40e/i40e_ethdev.c
@@ -835,27 +835,20 @@ i40e_vsi_disable_queues_intr(struct i40e_vsi *vsi)
 }
 
 static inline uint8_t
-i40e_parse_link_speed(uint16_t eth_link_speed)
+i40e_parse_link_speeds(uint16_t link_speeds)
 {
 	uint8_t link_speed = I40E_LINK_SPEED_UNKNOWN;
 
-	switch (eth_link_speed) {
-	case ETH_LINK_SPEED_40G:
-		link_speed = I40E_LINK_SPEED_40GB;
-		break;
-	case ETH_LINK_SPEED_20G:
-		link_speed = I40E_LINK_SPEED_20GB;
-		break;
-	case ETH_LINK_SPEED_10G:
-		link_speed = I40E_LINK_SPEED_10GB;
-		break;
-	case ETH_LINK_SPEED_1000:
-		link_speed = I40E_LINK_SPEED_1GB;
-		break;
-	case ETH_LINK_SPEED_100:
-		link_speed = I40E_LINK_SPEED_100MB;
-		break;
-	}
+	if (link_speeds & ETH_LINK_SPEED_40G)
+		link_speed |= I40E_LINK_SPEED_40GB;
+	if (link_speeds & ETH_LINK_SPEED_20G)
+		link_speed |= I40E_LINK_SPEED_20GB;
+	if (link_speeds & ETH_LINK_SPEED_10G)
+		link_speed |= I40E_LINK_SPEED_10GB;
+	if (link_speeds & ETH_LINK_SPEED_1G)
+		link_speed |= I40E_LINK_SPEED_1GB;
+	if (link_speeds & ETH_LINK_SPEED_100M)
+		link_speed |= I40E_LINK_SPEED_100MB;
 
 	return link_speed;
 }
@@ -924,9 +917,9 @@ i40e_apply_link_speed(struct rte_eth_dev *dev)
 	struct i40e_hw *hw = I40E_DEV_PRIVATE_TO_HW(dev->data->dev_private);
 	struct rte_eth_conf *conf = &dev->data->dev_conf;
 
-	speed = i40e_parse_link_speed(conf->link_speed);
+	speed = i40e_parse_link_speeds(conf->link_speeds);
 	abilities |= I40E_AQ_PHY_ENABLE_ATOMIC_LINK;
-	if (conf->link_speed == ETH_LINK_SPEED_AUTONEG)
+	if (conf->link_speeds & ETH_LINK_SPEED_AUTONEG)
 		abilities |= I40E_AQ_PHY_AN_ENABLED;
 	else
 		abilities |= I40E_AQ_PHY_LINK_ENABLED;
@@ -944,10 +937,8 @@ i40e_dev_start(struct rte_eth_dev *dev)
 
 	hw->adapter_stopped = 0;
 
-	if ((dev->data->dev_conf.link_duplex != ETH_LINK_AUTONEG_DUPLEX) &&
-		(dev->data->dev_conf.link_duplex != ETH_LINK_FULL_DUPLEX)) {
-		PMD_INIT_LOG(ERR, "Invalid link_duplex (%hu) for port %hhu",
-			     dev->data->dev_conf.link_duplex,
+	if (dev->data->dev_conf.link_speeds & ETH_LINK_SPEED_NO_AUTONEG) {
+		PMD_INIT_LOG(ERR, "Invalid link_speeds for port %hhu; autonegociation disabled",
 			     dev->data->port_id);
 		return -EINVAL;
 	}
@@ -995,6 +986,13 @@ i40e_dev_start(struct rte_eth_dev *dev)
 	}
 
 	/* Apply link configure */
+	if (dev->data->dev_conf.link_speeds & ~(ETH_LINK_SPEED_100M |
+				ETH_LINK_SPEED_1G | ETH_LINK_SPEED_10G |
+				ETH_LINK_SPEED_20G | ETH_LINK_SPEED_40G)) {
+		PMD_DRV_LOG(ERR, "Invalid link setting");
+		goto err_up;
+	}
+
 	ret = i40e_apply_link_speed(dev);
 	if (I40E_SUCCESS != ret) {
 		PMD_DRV_LOG(ERR, "Fail to apply link setting");
@@ -1209,7 +1207,7 @@ i40e_dev_link_update(struct rte_eth_dev *dev,
 		/* Get link status information from hardware */
 		status = i40e_aq_get_link_info(hw, false, &link_status, NULL);
 		if (status != I40E_SUCCESS) {
-			link.link_speed = ETH_LINK_SPEED_100;
+			link.link_speed = ETH_SPEED_NUM_100M;
 			link.link_duplex = ETH_LINK_FULL_DUPLEX;
 			PMD_DRV_LOG(ERR, "Failed to get link info");
 			goto out;
@@ -1231,25 +1229,28 @@ i40e_dev_link_update(struct rte_eth_dev *dev,
 	/* Parse the link status */
 	switch (link_status.link_speed) {
 	case I40E_LINK_SPEED_100MB:
-		link.link_speed = ETH_LINK_SPEED_100;
+		link.link_speed = ETH_SPEED_NUM_100M;
 		break;
 	case I40E_LINK_SPEED_1GB:
-		link.link_speed = ETH_LINK_SPEED_1000;
+		link.link_speed = ETH_SPEED_NUM_1G;
 		break;
 	case I40E_LINK_SPEED_10GB:
-		link.link_speed = ETH_LINK_SPEED_10G;
+		link.link_speed = ETH_SPEED_NUM_10G;
 		break;
 	case I40E_LINK_SPEED_20GB:
-		link.link_speed = ETH_LINK_SPEED_20G;
+		link.link_speed = ETH_SPEED_NUM_20G;
 		break;
 	case I40E_LINK_SPEED_40GB:
-		link.link_speed = ETH_LINK_SPEED_40G;
+		link.link_speed = ETH_SPEED_NUM_40G;
 		break;
 	default:
-		link.link_speed = ETH_LINK_SPEED_100;
+		link.link_speed = ETH_SPEED_NUM_100M;
 		break;
 	}
 
+	link.link_autoneg = ~(dev->data->dev_conf.link_speeds &
+						ETH_LINK_SPEED_NO_AUTONEG);
+
 out:
 	rte_i40e_dev_atomic_write_link_status(dev, &link);
 	if (link.link_status == old.link_status)
@@ -1687,10 +1688,10 @@ i40e_dev_info_get(struct rte_eth_dev *dev, struct rte_eth_dev_info *dev_info)
 
 	if (i40e_is_40G_device(hw->device_id))
 		/* For XL710 */
-		dev_info->speed_capa = ETH_SPEED_CAP_1G | ETH_SPEED_CAP_10G;
+		dev_info->speed_capa = ETH_LINK_SPEED_1G | ETH_LINK_SPEED_10G;
 	else
 		/* For X710 */
-		dev_info->speed_capa = ETH_SPEED_CAP_10G | ETH_SPEED_CAP_40G;
+		dev_info->speed_capa = ETH_LINK_SPEED_10G | ETH_LINK_SPEED_40G;
 
 }
 
@@ -6195,15 +6196,15 @@ i40e_timesync_enable(struct rte_eth_dev *dev)
 	uint32_t tsync_inc_h;
 
 	switch (link->link_speed) {
-	case ETH_LINK_SPEED_40G:
+	case ETH_SPEED_NUM_40G:
 		tsync_inc_l = I40E_PTP_40GB_INCVAL & 0xFFFFFFFF;
 		tsync_inc_h = I40E_PTP_40GB_INCVAL >> 32;
 		break;
-	case ETH_LINK_SPEED_10G:
+	case ETH_SPEED_NUM_10G:
 		tsync_inc_l = I40E_PTP_10GB_INCVAL & 0xFFFFFFFF;
 		tsync_inc_h = I40E_PTP_10GB_INCVAL >> 32;
 		break;
-	case ETH_LINK_SPEED_1000:
+	case ETH_SPEED_NUM_1G:
 		tsync_inc_l = I40E_PTP_1GB_INCVAL & 0xFFFFFFFF;
 		tsync_inc_h = I40E_PTP_1GB_INCVAL >> 32;
 		break;
diff --git a/drivers/net/i40e/i40e_ethdev_vf.c b/drivers/net/i40e/i40e_ethdev_vf.c
index b694400..8d3acae 100644
--- a/drivers/net/i40e/i40e_ethdev_vf.c
+++ b/drivers/net/i40e/i40e_ethdev_vf.c
@@ -1635,13 +1635,14 @@ i40evf_dev_link_update(struct rte_eth_dev *dev,
 	 * DPDK pf host provide interfacet to acquire link status
 	 * while Linux driver does not
 	 */
-	if (vf->version_major == I40E_DPDK_VERSION_MAJOR)
+	if (vf->version_major == I40E_DPDK_VERSION_MAJOR) {
 		i40evf_get_link_status(dev, &new_link);
-	else {
+	} else {
 		/* Always assume it's up, for Linux driver PF host */
-		new_link.link_duplex = ETH_LINK_AUTONEG_DUPLEX;
-		new_link.link_speed  = ETH_LINK_SPEED_10000;
-		new_link.link_status = 1;
+		new_link.link_speed  = ETH_SPEED_NUM_10G;
+		new_link.link_duplex = ETH_LINK_FULL_DUPLEX;
+		new_link.link_autoneg = ETH_LINK_SPEED_NEG;
+		new_link.link_status = ETH_LINK_UP;
 	}
 	i40evf_dev_atomic_write_link_status(dev, &new_link);
 
diff --git a/drivers/net/ixgbe/ixgbe_ethdev.c b/drivers/net/ixgbe/ixgbe_ethdev.c
index 3be84aa..f4dd1d2 100644
--- a/drivers/net/ixgbe/ixgbe_ethdev.c
+++ b/drivers/net/ixgbe/ixgbe_ethdev.c
@@ -1676,14 +1676,13 @@ ixgbe_dev_start(struct rte_eth_dev *dev)
 	int mask = 0;
 	int status;
 	uint16_t vf, idx;
+	uint32_t *link_speeds;
 
 	PMD_INIT_FUNC_TRACE();
 
 	/* IXGBE devices don't support half duplex */
-	if ((dev->data->dev_conf.link_duplex != ETH_LINK_AUTONEG_DUPLEX) &&
-			(dev->data->dev_conf.link_duplex != ETH_LINK_FULL_DUPLEX)) {
-		PMD_INIT_LOG(ERR, "Invalid link_duplex (%hu) for port %hhu",
-			     dev->data->dev_conf.link_duplex,
+	if (dev->data->dev_conf.link_speeds & ETH_LINK_SPEED_NO_AUTONEG) {
+		PMD_INIT_LOG(ERR, "Invalid link_speeds for port %hhu; autonegociation disabled",
 			     dev->data->port_id);
 		return -EINVAL;
 	}
@@ -1769,32 +1768,22 @@ ixgbe_dev_start(struct rte_eth_dev *dev)
 	if (err)
 		goto error;
 
-	switch(dev->data->dev_conf.link_speed) {
-	case ETH_LINK_SPEED_AUTONEG:
-		speed = (hw->mac.type != ixgbe_mac_82598EB) ?
-				IXGBE_LINK_SPEED_82599_AUTONEG :
-				IXGBE_LINK_SPEED_82598_AUTONEG;
-		break;
-	case ETH_LINK_SPEED_100:
-		/*
-		 * Invalid for 82598 but error will be detected by
-		 * ixgbe_setup_link()
-		 */
-		speed = IXGBE_LINK_SPEED_100_FULL;
-		break;
-	case ETH_LINK_SPEED_1000:
-		speed = IXGBE_LINK_SPEED_1GB_FULL;
-		break;
-	case ETH_LINK_SPEED_10000:
-		speed = IXGBE_LINK_SPEED_10GB_FULL;
-		break;
-	default:
-		PMD_INIT_LOG(ERR, "Invalid link_speed (%hu) for port %hhu",
-			     dev->data->dev_conf.link_speed,
-			     dev->data->port_id);
+	link_speeds = &dev->data->dev_conf.link_speeds;
+	if (*link_speeds & ~(ETH_LINK_SPEED_100M | ETH_LINK_SPEED_1G |
+							ETH_LINK_SPEED_10G)) {
+		PMD_INIT_LOG(ERR, "Invalid link setting");
 		goto error;
 	}
 
+	speed = 0x0;
+
+	if (*link_speeds & ETH_LINK_SPEED_10G)
+		speed |= IXGBE_LINK_SPEED_10GB_FULL;
+	if (*link_speeds & ETH_LINK_SPEED_1G)
+		speed |= IXGBE_LINK_SPEED_1GB_FULL;
+	if (*link_speeds & ETH_LINK_SPEED_100M)
+		speed |= IXGBE_LINK_SPEED_100_FULL;
+
 	err = ixgbe_setup_link(hw, speed, link_up);
 	if (err)
 		goto error;
@@ -2400,15 +2389,16 @@ ixgbe_dev_info_get(struct rte_eth_dev *dev, struct rte_eth_dev_info *dev_info)
 	dev_info->reta_size = ETH_RSS_RETA_SIZE_128;
 	dev_info->flow_type_rss_offloads = IXGBE_RSS_OFFLOAD_ALL;
 
-	dev_info->speed_capa = ETH_SPEED_CAP_1G | ETH_SPEED_CAP_10G;
+	dev_info->speed_capa = ETH_LINK_SPEED_1G | ETH_LINK_SPEED_10G;
 
 	if (hw->mac.type == ixgbe_mac_X540 ||
 	    hw->mac.type == ixgbe_mac_X540_vf ||
 	    hw->mac.type == ixgbe_mac_X550 ||
-	    hw->mac.type == ixgbe_mac_X550_vf)
+	    hw->mac.type == ixgbe_mac_X550_vf) {
 
-		dev_info->speed_capa |= ETH_SPEED_CAP_100M_FD /*|
-					ETH_SPEED_CAP_100M_HD*/;
+		dev_info->speed_capa |= ETH_LINK_SPEED_100M /*|
+					ETH_LINK_SPEED_100M_HD*/;
+	}
 }
 
 static void
@@ -2471,9 +2461,9 @@ ixgbe_dev_link_update(struct rte_eth_dev *dev, int wait_to_complete)
 	int link_up;
 	int diag;
 
-	link.link_status = 0;
+	link.link_status = ETH_LINK_DOWN;
 	link.link_speed = 0;
-	link.link_duplex = 0;
+	link.link_duplex = ETH_LINK_HALF_DUPLEX;
 	memset(&old, 0, sizeof(old));
 	rte_ixgbe_dev_atomic_read_link_status(dev, &old);
 
@@ -2486,8 +2476,8 @@ ixgbe_dev_link_update(struct rte_eth_dev *dev, int wait_to_complete)
 		diag = ixgbe_check_link(hw, &link_speed, &link_up, 1);
 
 	if (diag != 0) {
-		link.link_speed = ETH_LINK_SPEED_100;
-		link.link_duplex = ETH_LINK_HALF_DUPLEX;
+		link.link_speed = ETH_SPEED_NUM_100M;
+		link.link_duplex = ETH_LINK_FULL_DUPLEX;
 		rte_ixgbe_dev_atomic_write_link_status(dev, &link);
 		if (link.link_status == old.link_status)
 			return -1;
@@ -2500,26 +2490,26 @@ ixgbe_dev_link_update(struct rte_eth_dev *dev, int wait_to_complete)
 			return -1;
 		return 0;
 	}
-	link.link_status = 1;
+	link.link_status = ETH_LINK_UP;
 	link.link_duplex = ETH_LINK_FULL_DUPLEX;
 
 	switch (link_speed) {
 	default:
 	case IXGBE_LINK_SPEED_UNKNOWN:
-		link.link_duplex = ETH_LINK_HALF_DUPLEX;
-		link.link_speed = ETH_LINK_SPEED_100;
+		link.link_duplex = ETH_LINK_FULL_DUPLEX;
+		link.link_speed = ETH_SPEED_NUM_100M;
 		break;
 
 	case IXGBE_LINK_SPEED_100_FULL:
-		link.link_speed = ETH_LINK_SPEED_100;
+		link.link_speed = ETH_SPEED_NUM_100M;
 		break;
 
 	case IXGBE_LINK_SPEED_1GB_FULL:
-		link.link_speed = ETH_LINK_SPEED_1000;
+		link.link_speed = ETH_SPEED_NUM_1G;
 		break;
 
 	case IXGBE_LINK_SPEED_10GB_FULL:
-		link.link_speed = ETH_LINK_SPEED_10000;
+		link.link_speed = ETH_SPEED_NUM_10G;
 		break;
 	}
 	rte_ixgbe_dev_atomic_write_link_status(dev, &link);
diff --git a/drivers/net/mlx4/mlx4.c b/drivers/net/mlx4/mlx4.c
index b45e21a..96fe4b6 100644
--- a/drivers/net/mlx4/mlx4.c
+++ b/drivers/net/mlx4/mlx4.c
@@ -4207,6 +4207,8 @@ mlx4_link_update_unlocked(struct rte_eth_dev *dev, int wait_to_complete)
 		dev_link.link_speed = link_speed;
 	dev_link.link_duplex = ((edata.duplex == DUPLEX_HALF) ?
 				ETH_LINK_HALF_DUPLEX : ETH_LINK_FULL_DUPLEX);
+	dev_link.link_autoneg = ~(dev->data->dev_conf.link_speeds &
+						ETH_LINK_SPEED_NO_AUTONEG);
 	if (memcmp(&dev_link, &dev->data->dev_link, sizeof(dev_link))) {
 		/* Link status changed. */
 		dev->data->dev_link = dev_link;
diff --git a/drivers/net/mpipe/mpipe_tilegx.c b/drivers/net/mpipe/mpipe_tilegx.c
index 743feef..5875371 100644
--- a/drivers/net/mpipe/mpipe_tilegx.c
+++ b/drivers/net/mpipe/mpipe_tilegx.c
@@ -388,14 +388,16 @@ mpipe_link_update(struct rte_eth_dev *dev, int wait_to_complete)
 
 		speed = state & GXIO_MPIPE_LINK_SPEED_MASK;
 
+		new.link_autoneg = ~(dev->data->dev_conf.link_speeds &
+						ETH_LINK_SPEED_NO_AUTONEG);
 		if (speed == GXIO_MPIPE_LINK_1G) {
 			new.link_speed = ETH_LINK_SPEED_1000;
 			new.link_duplex = ETH_LINK_FULL_DUPLEX;
-			new.link_status = 1;
+			new.link_status = ETH_LINK_UP;
 		} else if (speed == GXIO_MPIPE_LINK_10G) {
 			new.link_speed = ETH_LINK_SPEED_10000;
 			new.link_duplex = ETH_LINK_FULL_DUPLEX;
-			new.link_status = 1;
+			new.link_status = ETH_LINK_UP;
 		}
 
 		rc = mpipe_link_compare(&old, &new);
diff --git a/drivers/net/null/rte_eth_null.c b/drivers/net/null/rte_eth_null.c
index e244595..7704fa6 100644
--- a/drivers/net/null/rte_eth_null.c
+++ b/drivers/net/null/rte_eth_null.c
@@ -79,9 +79,10 @@ struct pmd_internals {
 static struct ether_addr eth_addr = { .addr_bytes = {0} };
 static const char *drivername = "Null PMD";
 static struct rte_eth_link pmd_link = {
-	.link_speed = 10000,
+	.link_speed = ETH_SPEED_NUM_10G,
 	.link_duplex = ETH_LINK_FULL_DUPLEX,
-	.link_status = 0
+	.link_status = ETH_LINK_DOWN,
+	.link_autoneg = ETH_LINK_SPEED_NEG,
 };
 
 static uint16_t
diff --git a/drivers/net/pcap/rte_eth_pcap.c b/drivers/net/pcap/rte_eth_pcap.c
index f2e4634..ea7a28f 100644
--- a/drivers/net/pcap/rte_eth_pcap.c
+++ b/drivers/net/pcap/rte_eth_pcap.c
@@ -125,9 +125,10 @@ static int open_single_iface(const char *iface, pcap_t **pcap);
 static struct ether_addr eth_addr = { .addr_bytes = { 0, 0, 0, 0x1, 0x2, 0x3 } };
 static const char *drivername = "Pcap PMD";
 static struct rte_eth_link pmd_link = {
-		.link_speed = 10000,
+		.link_speed = ETH_SPEED_NUM_10G,
 		.link_duplex = ETH_LINK_FULL_DUPLEX,
-		.link_status = 0
+		.link_status = ETH_LINK_DOWN,
+		.link_autoneg = ETH_LINK_SPEED_FIXED,
 };
 
 static int
@@ -430,7 +431,7 @@ eth_dev_start(struct rte_eth_dev *dev)
 
 status_up:
 
-	dev->data->dev_link.link_status = 1;
+	dev->data->dev_link.link_status = ETH_LINK_UP;
 	return 0;
 }
 
@@ -481,7 +482,7 @@ eth_dev_stop(struct rte_eth_dev *dev)
 	}
 
 status_down:
-	dev->data->dev_link.link_status = 0;
+	dev->data->dev_link.link_status = ETH_LINK_DOWN;
 }
 
 static int
diff --git a/drivers/net/ring/rte_eth_ring.c b/drivers/net/ring/rte_eth_ring.c
index 0ba36d5..626c381 100644
--- a/drivers/net/ring/rte_eth_ring.c
+++ b/drivers/net/ring/rte_eth_ring.c
@@ -71,9 +71,10 @@ struct pmd_internals {
 
 static const char *drivername = "Rings PMD";
 static struct rte_eth_link pmd_link = {
-		.link_speed = 10000,
+		.link_speed = ETH_SPEED_NUM_10G,
 		.link_duplex = ETH_LINK_FULL_DUPLEX,
-		.link_status = 0
+		.link_status = ETH_LINK_DOWN,
+		.link_autoneg = ETH_LINK_SPEED_NEG
 };
 
 static uint16_t
diff --git a/drivers/net/virtio/virtio_ethdev.c b/drivers/net/virtio/virtio_ethdev.c
index 465d3cd..ecbf9f2 100644
--- a/drivers/net/virtio/virtio_ethdev.c
+++ b/drivers/net/virtio/virtio_ethdev.c
@@ -1517,7 +1517,7 @@ virtio_dev_link_update(struct rte_eth_dev *dev, __rte_unused int wait_to_complet
 	memset(&link, 0, sizeof(link));
 	virtio_dev_atomic_read_link_status(dev, &link);
 	old = link;
-	link.link_duplex = FULL_DUPLEX;
+	link.link_duplex = ETH_LINK_FULL_DUPLEX;
 	link.link_speed  = SPEED_10G;
 
 	if (vtpci_with_feature(hw, VIRTIO_NET_F_STATUS)) {
diff --git a/drivers/net/virtio/virtio_ethdev.h b/drivers/net/virtio/virtio_ethdev.h
index 9026d42..424d650 100644
--- a/drivers/net/virtio/virtio_ethdev.h
+++ b/drivers/net/virtio/virtio_ethdev.h
@@ -42,8 +42,6 @@
 #define SPEED_100	100
 #define SPEED_1000	1000
 #define SPEED_10G	10000
-#define HALF_DUPLEX	1
-#define FULL_DUPLEX	2
 
 #ifndef PAGE_SIZE
 #define PAGE_SIZE 4096
diff --git a/drivers/net/vmxnet3/vmxnet3_ethdev.c b/drivers/net/vmxnet3/vmxnet3_ethdev.c
index a70be5c..6860360 100644
--- a/drivers/net/vmxnet3/vmxnet3_ethdev.c
+++ b/drivers/net/vmxnet3/vmxnet3_ethdev.c
@@ -697,9 +697,10 @@ vmxnet3_dev_link_update(struct rte_eth_dev *dev, __attribute__((unused)) int wai
 	ret = VMXNET3_READ_BAR1_REG(hw, VMXNET3_REG_CMD);
 
 	if (ret & 0x1) {
-		link.link_status = 1;
+		link.link_status = ETH_LINK_UP;
 		link.link_duplex = ETH_LINK_FULL_DUPLEX;
-		link.link_speed = ETH_LINK_SPEED_10000;
+		link.link_speed = ETH_SPEED_NUM_10G;
+		link.link_autoneg = ETH_LINK_SPEED_FIXED;
 	}
 
 	vmxnet3_dev_atomic_write_link_status(dev, &link);
diff --git a/drivers/net/xenvirt/rte_eth_xenvirt.c b/drivers/net/xenvirt/rte_eth_xenvirt.c
index 73e8bce..fb492ee 100644
--- a/drivers/net/xenvirt/rte_eth_xenvirt.c
+++ b/drivers/net/xenvirt/rte_eth_xenvirt.c
@@ -70,9 +70,10 @@ static int virtio_idx = 0;
 static const char *drivername = "xen dummy virtio PMD";
 
 static struct rte_eth_link pmd_link = {
-		.link_speed = 10000,
+		.link_speed = ETH_SPEED_NUM_10G,
 		.link_duplex = ETH_LINK_FULL_DUPLEX,
-		.link_status = 0
+		.link_status = ETH_LINK_DOWN,
+		.link_autoneg = ETH_LINK_SPEED_FIXED
 };
 
 static inline struct rte_mbuf *
diff --git a/examples/ip_pipeline/config_parse.c b/examples/ip_pipeline/config_parse.c
index c9b78f9..92e6a18 100644
--- a/examples/ip_pipeline/config_parse.c
+++ b/examples/ip_pipeline/config_parse.c
@@ -83,8 +83,7 @@ static const struct app_link_params link_params_default = {
 	.mac_addr = 0,
 
 	.conf = {
-		.link_speed = 0,
-		.link_duplex = 0,
+		.link_speeds = 0,
 		.rxmode = {
 			.mq_mode = ETH_MQ_RX_NONE,
 
diff --git a/lib/librte_ether/rte_ethdev.c b/lib/librte_ether/rte_ethdev.c
index f593f6e..29b2960 100644
--- a/lib/librte_ether/rte_ethdev.c
+++ b/lib/librte_ether/rte_ethdev.c
@@ -1072,6 +1072,55 @@ rte_eth_dev_check_mq_mode(uint8_t port_id, uint16_t nb_rx_q, uint16_t nb_tx_q,
 }
 
 int
+rte_eth_speed_to_bm_flag(uint32_t speed, int duplex, uint32_t *flag)
+{
+	switch (speed) {
+	case ETH_SPEED_NUM_10M:
+		*flag = (duplex) ? ETH_LINK_SPEED_10M :
+							ETH_LINK_SPEED_10M_HD;
+		break;
+	case ETH_SPEED_NUM_100M:
+		*flag = (duplex) ? ETH_LINK_SPEED_100M :
+							ETH_LINK_SPEED_100M_HD;
+		break;
+	case ETH_SPEED_NUM_1G:
+		*flag = ETH_LINK_SPEED_1G;
+		break;
+	case ETH_SPEED_NUM_2_5G:
+		*flag = ETH_LINK_SPEED_2_5G;
+		break;
+	case ETH_SPEED_NUM_5G:
+		*flag = ETH_LINK_SPEED_5G;
+		break;
+	case ETH_SPEED_NUM_10G:
+		*flag = ETH_LINK_SPEED_10G;
+		break;
+	case ETH_SPEED_NUM_20G:
+		*flag = ETH_LINK_SPEED_20G;
+		break;
+	case ETH_SPEED_NUM_25G:
+		*flag = ETH_LINK_SPEED_25G;
+		break;
+	case ETH_SPEED_NUM_40G:
+		*flag = ETH_LINK_SPEED_40G;
+		break;
+	case ETH_SPEED_NUM_50G:
+		*flag = ETH_LINK_SPEED_50G;
+		break;
+	case ETH_SPEED_NUM_56G:
+		*flag = ETH_LINK_SPEED_56G;
+		break;
+	case ETH_SPEED_NUM_100G:
+		*flag = ETH_LINK_SPEED_100G;
+		break;
+	default:
+		return -EINVAL;
+	}
+
+	return 0;
+}
+
+int
 rte_eth_dev_configure(uint8_t port_id, uint16_t nb_rx_q, uint16_t nb_tx_q,
 		      const struct rte_eth_conf *dev_conf)
 {
diff --git a/lib/librte_ether/rte_ethdev.h b/lib/librte_ether/rte_ethdev.h
index 951a423..54ee6f9 100644
--- a/lib/librte_ether/rte_ethdev.h
+++ b/lib/librte_ether/rte_ethdev.h
@@ -238,26 +238,59 @@ struct rte_eth_stats {
 };
 
 /**
+ * Device supported speeds bitmap flags
+ */
+#define ETH_LINK_SPEED_AUTONEG		(0 << 0)  /*< Autonegociate (all speeds)  */
+#define ETH_LINK_SPEED_NO_AUTONEG	(1 << 0)  /*< Disable autoneg (fixed speed)  */
+#define ETH_LINK_SPEED_10M_HD		(1 << 1)  /*< 10 Mbps half-duplex */
+#define ETH_LINK_SPEED_10M		(1 << 2)  /*< 10 Mbps full-duplex */
+#define ETH_LINK_SPEED_100M_HD		(1 << 3)  /*< 100 Mbps half-duplex */
+#define ETH_LINK_SPEED_100M		(1 << 4)  /*< 100 Mbps full-duplex */
+#define ETH_LINK_SPEED_1G		(1 << 5)  /*< 1 Gbps */
+#define ETH_LINK_SPEED_2_5G		(1 << 6)  /*< 2.5 Gbps */
+#define ETH_LINK_SPEED_5G		(1 << 7)  /*< 5 Gbps */
+#define ETH_LINK_SPEED_10G		(1 << 8)  /*< 10 Mbps */
+#define ETH_LINK_SPEED_20G		(1 << 9)  /*< 20 Gbps */
+#define ETH_LINK_SPEED_25G		(1 << 10)  /*< 25 Gbps */
+#define ETH_LINK_SPEED_40G		(1 << 11)  /*< 40 Gbps */
+#define ETH_LINK_SPEED_50G		(1 << 12)  /*< 50 Gbps */
+#define ETH_LINK_SPEED_56G		(1 << 13)  /*< 56 Gbps */
+#define ETH_LINK_SPEED_100G		(1 << 14)  /*< 100 Gbps */
+
+/**
+ * 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 Mbps */
+#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 */
+
+/**
  * A structure used to retrieve link-level information of an Ethernet port.
  */
 struct rte_eth_link {
-	uint16_t link_speed;      /**< ETH_LINK_SPEED_[10, 100, 1000, 10000] */
-	uint16_t link_duplex;     /**< ETH_LINK_[HALF_DUPLEX, FULL_DUPLEX] */
-	uint8_t  link_status : 1; /**< 1 -> link up, 0 -> link down */
-}__attribute__((aligned(8)));     /**< aligned for atomic64 read/write */
-
-#define ETH_LINK_SPEED_AUTONEG  0       /**< Auto-negotiate link speed. */
-#define ETH_LINK_SPEED_10       10      /**< 10 megabits/second. */
-#define ETH_LINK_SPEED_100      100     /**< 100 megabits/second. */
-#define ETH_LINK_SPEED_1000     1000    /**< 1 gigabits/second. */
-#define ETH_LINK_SPEED_10000    10000   /**< 10 gigabits/second. */
-#define ETH_LINK_SPEED_10G      10000   /**< alias of 10 gigabits/second. */
-#define ETH_LINK_SPEED_20G      20000   /**< 20 gigabits/second. */
-#define ETH_LINK_SPEED_40G      40000   /**< 40 gigabits/second. */
+	uint32_t link_speed;        /**< Link speed (ETH_SPEED_NUM_) */
+	uint16_t link_duplex  : 1;  /**< 1 -> full duplex, 0 -> half duplex */
+	uint16_t link_autoneg : 1;  /**< 1 -> link speed has been autoneg */
+	uint16_t link_status  : 1;  /**< 1 -> link up, 0 -> link down */
+} __attribute__((aligned(8)));      /**< aligned for atomic64 read/write */
 
-#define ETH_LINK_AUTONEG_DUPLEX 0       /**< Auto-negotiate duplex. */
-#define ETH_LINK_HALF_DUPLEX    1       /**< Half-duplex connection. */
-#define ETH_LINK_FULL_DUPLEX    2       /**< Full-duplex connection. */
+/* Utility constants */
+#define ETH_LINK_HALF_DUPLEX    0	/**< Half-duplex connection. */
+#define ETH_LINK_FULL_DUPLEX    1	/**< Full-duplex connection. */
+#define ETH_LINK_SPEED_FIXED    0	/**< Link speed was not autonegociated. */
+#define ETH_LINK_SPEED_NEG      1	/**< Link speed was autonegociated. */
+#define ETH_LINK_DOWN		0	/**< Link is down. */
+#define ETH_LINK_UP		1	/**< Link is up. */
 
 /**
  * A structure used to configure the ring threshold registers of an RX/TX
@@ -747,10 +780,14 @@ struct rte_intr_conf {
  * configuration settings may be needed.
  */
 struct rte_eth_conf {
-	uint16_t link_speed;
-	/**< ETH_LINK_SPEED_10[0|00|000], or 0 for autonegotation */
-	uint16_t link_duplex;
-	/**< ETH_LINK_[HALF_DUPLEX|FULL_DUPLEX], or 0 for autonegotation */
+	uint32_t link_speeds; /**< bitmap of ETH_LINK_SPEED_XXX of speeds to be
+				used. ETH_LINK_SPEED_NO_AUTONEG disables link
+				autonegociation, and a unique speed shall be
+				set. Otherwise, the bitmap defines the set of
+				speeds to be advertised. If the special value
+				ETH_LINK_SPEED_AUTONEG (0) is used, all speeds
+				supported are advertised.
+				*/
 	struct rte_eth_rxmode rxmode; /**< Port RX configuration. */
 	struct rte_eth_txmode txmode; /**< Port TX configuration. */
 	uint32_t lpbk_mode; /**< Loopback operation mode. By default the value
@@ -812,26 +849,6 @@ struct rte_eth_conf {
 #define DEV_TX_OFFLOAD_QINQ_INSERT 0x00000100
 
 /**
- * Device supported speeds
- */
-#define ETH_SPEED_CAP_NOT_PHY	(0)  /*< No phy media > */
-#define ETH_SPEED_CAP_10M_HD	(1 << 0)  /*< 10 Mbps half-duplex> */
-#define ETH_SPEED_CAP_10M_FD	(1 << 1)  /*< 10 Mbps full-duplex> */
-#define ETH_SPEED_CAP_100M_HD	(1 << 2)  /*< 100 Mbps half-duplex> */
-#define ETH_SPEED_CAP_100M_FD	(1 << 3)  /*< 100 Mbps full-duplex> */
-#define ETH_SPEED_CAP_1G	(1 << 4)  /*< 1 Gbps > */
-#define ETH_SPEED_CAP_2_5G	(1 << 5)  /*< 2.5 Gbps > */
-#define ETH_SPEED_CAP_5G	(1 << 6)  /*< 5 Gbps > */
-#define ETH_SPEED_CAP_10G	(1 << 7)  /*< 10 Mbps > */
-#define ETH_SPEED_CAP_20G	(1 << 8)  /*< 20 Gbps > */
-#define ETH_SPEED_CAP_25G	(1 << 9)  /*< 25 Gbps > */
-#define ETH_SPEED_CAP_40G	(1 << 10)  /*< 40 Gbps > */
-#define ETH_SPEED_CAP_50G	(1 << 11)  /*< 50 Gbps > */
-#define ETH_SPEED_CAP_56G	(1 << 12)  /*< 56 Gbps > */
-#define ETH_SPEED_CAP_100G	(1 << 13)  /*< 100 Gbps > */
-
-
-/**
  * Ethernet device information
  */
 struct rte_eth_dev_info {
@@ -1667,6 +1684,22 @@ struct eth_driver {
 extern void rte_eth_driver_register(struct eth_driver *eth_drv);
 
 /**
+ * Convert a numerical speed in Mbps to a bitmap flag that can be used in
+ * the bitmap link_speeds of the struct rte_eth_conf
+ *
+ * @param
+ *   Numerical speed value in Mbps
+ * @param
+ *   Boolean is duplex (only for 10/100 speeds)
+ * @param
+ *   On success, the converted speed into a bitmap flag
+ * @return
+ *   0 on success, -EINVAL if the speed cannot be mapped
+ */
+extern int rte_eth_speed_to_bm_flag(uint32_t speed, int duplex,
+							uint32_t *flag);
+
+/**
  * Configure an Ethernet device.
  * This function must be invoked first before any other function in the
  * Ethernet API. This function can also be re-invoked when a device is in the
-- 
2.1.4

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

* [PATCH v6 4/5] doc: update with link changes
  2015-10-25 21:59 ` [PATCH v6 0/5] ethdev: add speed capabilities and refactor link API Marc Sune
                     ` (2 preceding siblings ...)
  2015-10-25 21:59   ` [PATCH v6 3/5] ethdev: redesign link speed config API Marc Sune
@ 2015-10-25 21:59   ` Marc Sune
  2015-10-25 22:00   ` [PATCH v6 5/5] ethdev: add rte_eth_speed_to_bm_flag() to ver. map Marc Sune
                     ` (2 subsequent siblings)
  6 siblings, 0 replies; 167+ messages in thread
From: Marc Sune @ 2015-10-25 21:59 UTC (permalink / raw)
  To: dev

Add new features, ABI changes and resolved issues notice for
the refactored link patch.

Signed-off-by: Marc Sune <marcdevel@gmail.com>
---
 doc/guides/rel_notes/release_2_2.rst | 23 +++++++++++++++++++++++
 1 file changed, 23 insertions(+)

diff --git a/doc/guides/rel_notes/release_2_2.rst b/doc/guides/rel_notes/release_2_2.rst
index 5687676..e0d1741 100644
--- a/doc/guides/rel_notes/release_2_2.rst
+++ b/doc/guides/rel_notes/release_2_2.rst
@@ -4,6 +4,17 @@ DPDK Release 2.2
 New Features
 ------------
 
+* **ethdev: define a set of advertised link speeds.**
+
+  Allowing to define a set of advertised speeds for auto-negociation,
+  explicitely disable link auto-negociation (single speed) and full
+  auto-negociation.
+
+* **ethdev: add speed_cap bitmap to recover eth device link speed capabilities
+  define a set of advertised link speeds.**
+
+  ``struct rte_eth_dev_info`` has now speed_cap bitmap, which allows the
+  application to recover the supported speeds for that ethernet device.
 
 Resolved Issues
 ---------------
@@ -48,6 +59,11 @@ Libraries
   Fixed issue where an incorrect Cuckoo Hash key table size could be
   calculated limiting the size to 4GB.
 
+* **ethdev: Fixed link_speed overflow in rte_eth_link for 100Gbps.**
+
+  100Gbps in Mbps (100000) exceeds 16 bit max value of ``link_speed`` in
+  ``rte_eth_link``.
+
 
 Examples
 ~~~~~~~~
@@ -81,6 +97,8 @@ API Changes
 * The deprecated ring PMD functions are removed:
   rte_eth_ring_pair_create() and rte_eth_ring_pair_attach().
 
+* New API call, rte_eth_speed_to_bm_flag(), in ethdev to map numerical speeds
+  to bitmap fields.
 
 ABI Changes
 -----------
@@ -91,6 +109,11 @@ ABI Changes
 * The ethdev flow director entries for SCTP were changed.
   It was already done in 2.1 for CONFIG_RTE_NEXT_ABI.
 
+* The ethdev rte_eth_link and rte_eth_conf structures were changed to
+  support the new link API, as well as ETH_LINK_HALF/FULL_DUPLEX.
+
+* The ethdev rte_eth_dev_info was changed to support device speed capabilities.
+
 * The mbuf structure was changed to support unified packet type.
   It was already done in 2.1 for CONFIG_RTE_NEXT_ABI.
 
-- 
2.1.4

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

* [PATCH v6 5/5] ethdev: add rte_eth_speed_to_bm_flag() to ver. map
  2015-10-25 21:59 ` [PATCH v6 0/5] ethdev: add speed capabilities and refactor link API Marc Sune
                     ` (3 preceding siblings ...)
  2015-10-25 21:59   ` [PATCH v6 4/5] doc: update with link changes Marc Sune
@ 2015-10-25 22:00   ` Marc Sune
  2015-12-16 20:37   ` [PATCH v6 0/5] ethdev: add speed capabilities and refactor link API Marc Sune
  2016-01-29  0:42   ` [PATCH v7 " Marc Sune
  6 siblings, 0 replies; 167+ messages in thread
From: Marc Sune @ 2015-10-25 22:00 UTC (permalink / raw)
  To: dev

Added rte_eth_speed_to_bm_flag() to DPDK2.2 version map.

Signed-off-by: Marc Sune <marcdevel@gmail.com>
---
 lib/librte_ether/rte_ether_version.map | 6 ++++++
 1 file changed, 6 insertions(+)

diff --git a/lib/librte_ether/rte_ether_version.map b/lib/librte_ether/rte_ether_version.map
index 8345a6c..cbfe0c8 100644
--- a/lib/librte_ether/rte_ether_version.map
+++ b/lib/librte_ether/rte_ether_version.map
@@ -127,3 +127,9 @@ DPDK_2.1 {
 	rte_eth_timesync_read_tx_timestamp;
 
 } DPDK_2.0;
+
+DPDK_2.2 {
+	global:
+
+	rte_eth_speed_to_bm_flag;
+} DPDK_2.1;
-- 
2.1.4

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

* Re: [PATCH v6 3/5] ethdev: redesign link speed config API
  2015-10-25 21:59   ` [PATCH v6 3/5] ethdev: redesign link speed config API Marc Sune
@ 2015-10-25 22:03     ` Marc Sune
  2015-11-01 22:16     ` Thomas Monjalon
  1 sibling, 0 replies; 167+ messages in thread
From: Marc Sune @ 2015-10-25 22:03 UTC (permalink / raw)
  To: dev

While testing this patch with some XL710, it seems even with current HEAD,
setting link speed into dev_conf to 10G does not work, it always takes
autoneg with all speeds.

Besides, this patch in particular should be tested for the rest of drivers
which I don't have HW for.

Regards
marc

2015-10-25 22:59 GMT+01:00 Marc Sune <marcdevel@gmail.com>:

> This patch redesigns the API to set the link speed/s configure
> for an ethernet port. Specifically:
>
> - it allows to define a set of advertised speeds for
>   auto-negociation.
> - it allows to disable link auto-negociation (single fixed speed).
> - default: auto-negociate all supported speeds.
>
> Other changes:
>
> * Added utility MACROs ETH_SPEED_NUM_XXX with the numeric
>   values of all supported link speeds, in Mbps.
> * Converted link_speed to uint32_t to accomodate 100G speeds
>   (bug).
> * Added autoneg flag in struct rte_eth_link to indicate if
>   link speed was a result of auto-negociation or was fixed
>   by configuration.
> * Added utility function to convert numeric speeds to bitmap
>   fields.
>
> Signed-off-by: Marc Sune <marcdevel@gmail.com>
> ---
>  app/test-pmd/cmdline.c                     | 124
> +++++++++++++++--------------
>  app/test/virtual_pmd.c                     |   4 +-
>  drivers/net/af_packet/rte_eth_af_packet.c  |   5 +-
>  drivers/net/bonding/rte_eth_bond_8023ad.c  |  14 ++--
>  drivers/net/cxgbe/base/t4_hw.c             |   8 +-
>  drivers/net/e1000/base/e1000_80003es2lan.c |   6 +-
>  drivers/net/e1000/base/e1000_82541.c       |   8 +-
>  drivers/net/e1000/base/e1000_82543.c       |   4 +-
>  drivers/net/e1000/base/e1000_82575.c       |  11 +--
>  drivers/net/e1000/base/e1000_api.c         |   2 +-
>  drivers/net/e1000/base/e1000_api.h         |   2 +-
>  drivers/net/e1000/base/e1000_defines.h     |   4 +-
>  drivers/net/e1000/base/e1000_hw.h          |   2 +-
>  drivers/net/e1000/base/e1000_ich8lan.c     |   4 +-
>  drivers/net/e1000/base/e1000_mac.c         |   9 ++-
>  drivers/net/e1000/base/e1000_mac.h         |   6 +-
>  drivers/net/e1000/base/e1000_vf.c          |   4 +-
>  drivers/net/e1000/base/e1000_vf.h          |   2 +-
>  drivers/net/e1000/em_ethdev.c              | 113
> +++++++++++++-------------
>  drivers/net/e1000/igb_ethdev.c             | 108 +++++++++++++------------
>  drivers/net/fm10k/fm10k_ethdev.c           |   8 +-
>  drivers/net/i40e/i40e_ethdev.c             |  73 ++++++++---------
>  drivers/net/i40e/i40e_ethdev_vf.c          |  11 +--
>  drivers/net/ixgbe/ixgbe_ethdev.c           |  72 ++++++++---------
>  drivers/net/mlx4/mlx4.c                    |   2 +
>  drivers/net/mpipe/mpipe_tilegx.c           |   6 +-
>  drivers/net/null/rte_eth_null.c            |   5 +-
>  drivers/net/pcap/rte_eth_pcap.c            |   9 ++-
>  drivers/net/ring/rte_eth_ring.c            |   5 +-
>  drivers/net/virtio/virtio_ethdev.c         |   2 +-
>  drivers/net/virtio/virtio_ethdev.h         |   2 -
>  drivers/net/vmxnet3/vmxnet3_ethdev.c       |   5 +-
>  drivers/net/xenvirt/rte_eth_xenvirt.c      |   5 +-
>  examples/ip_pipeline/config_parse.c        |   3 +-
>  lib/librte_ether/rte_ethdev.c              |  49 ++++++++++++
>  lib/librte_ether/rte_ethdev.h              | 113
> ++++++++++++++++----------
>  36 files changed, 449 insertions(+), 361 deletions(-)
>
> diff --git a/app/test-pmd/cmdline.c b/app/test-pmd/cmdline.c
> index 0f8f48f..c62f5be 100644
> --- a/app/test-pmd/cmdline.c
> +++ b/app/test-pmd/cmdline.c
> @@ -897,14 +897,65 @@ struct cmd_config_speed_all {
>         cmdline_fixed_string_t value2;
>  };
>
> +static int
> +parse_and_check_speed_duplex(char *value1, char *value2, uint32_t
> *link_speed)
> +{
> +
> +       int duplex;
> +
> +       if (!strcmp(value2, "half")) {
> +               duplex = 0;
> +       } else if (!strcmp(value2, "full")) {
> +               duplex = 1;
> +       } else if (!strcmp(value2, "auto")) {
> +               duplex = 1;
> +       } else {
> +               printf("Unknown parameter\n");
> +               return -1;
> +       }
> +
> +       if (!strcmp(value1, "10")) {
> +               *link_speed = (duplex) ? ETH_LINK_SPEED_10M :
> +
>  ETH_LINK_SPEED_10M_HD;
> +       } else if (!strcmp(value1, "100")) {
> +               *link_speed = (duplex) ? ETH_LINK_SPEED_100M :
> +
>  ETH_LINK_SPEED_100M_HD;
> +       } else if (!strcmp(value1, "1000")) {
> +               if (!duplex)
> +                       goto invalid_speed_param;
> +               *link_speed = ETH_LINK_SPEED_1G;
> +       } else if (!strcmp(value1, "10000")) {
> +               if (!duplex)
> +                       goto invalid_speed_param;
> +               *link_speed = ETH_LINK_SPEED_10G;
> +       } else if (!strcmp(value1, "40000")) {
> +               if (!duplex)
> +                       goto invalid_speed_param;
> +               *link_speed = ETH_LINK_SPEED_40G;
> +       } else if (!strcmp(value1, "auto")) {
> +               if (!duplex)
> +                       goto invalid_speed_param;
> +               *link_speed = ETH_LINK_SPEED_AUTONEG;
> +       } else {
> +               printf("Unknown parameter\n");
> +               return -1;
> +       }
> +
> +       return 0;
> +
> +invalid_speed_param:
> +
> +       printf("Invalid speed parameter\n");
> +       return -1;
> +}
> +
>  static void
>  cmd_config_speed_all_parsed(void *parsed_result,
>                         __attribute__((unused)) struct cmdline *cl,
>                         __attribute__((unused)) void *data)
>  {
>         struct cmd_config_speed_all *res = parsed_result;
> -       uint16_t link_speed = ETH_LINK_SPEED_AUTONEG;
> -       uint16_t link_duplex = 0;
> +       uint32_t link_speed;
>         portid_t pid;
>
>         if (!all_ports_stopped()) {
> @@ -912,40 +963,18 @@ cmd_config_speed_all_parsed(void *parsed_result,
>                 return;
>         }
>
> -       if (!strcmp(res->value1, "10"))
> -               link_speed = ETH_LINK_SPEED_10;
> -       else if (!strcmp(res->value1, "100"))
> -               link_speed = ETH_LINK_SPEED_100;
> -       else if (!strcmp(res->value1, "1000"))
> -               link_speed = ETH_LINK_SPEED_1000;
> -       else if (!strcmp(res->value1, "10000"))
> -               link_speed = ETH_LINK_SPEED_10G;
> -       else if (!strcmp(res->value1, "40000"))
> -               link_speed = ETH_LINK_SPEED_40G;
> -       else if (!strcmp(res->value1, "auto"))
> -               link_speed = ETH_LINK_SPEED_AUTONEG;
> -       else {
> -               printf("Unknown parameter\n");
> +       if (parse_and_check_speed_duplex(res->value1,
> +                                               res->value2,
> +                                               &link_speed) < 0)
>                 return;
> -       }
> -
> -       if (!strcmp(res->value2, "half"))
> -               link_duplex = ETH_LINK_HALF_DUPLEX;
> -       else if (!strcmp(res->value2, "full"))
> -               link_duplex = ETH_LINK_FULL_DUPLEX;
> -       else if (!strcmp(res->value2, "auto"))
> -               link_duplex = ETH_LINK_AUTONEG_DUPLEX;
> -       else {
> -               printf("Unknown parameter\n");
> -               return;
> -       }
>
>         FOREACH_PORT(pid, ports) {
> -               ports[pid].dev_conf.link_speed = link_speed;
> -               ports[pid].dev_conf.link_duplex = link_duplex;
> +               ports[pid].dev_conf.link_speeds = link_speed;
>         }
>
>         cmd_reconfig_device_queue(RTE_PORT_ALL, 1, 1);
> +
> +       return;
>  }
>
>  cmdline_parse_token_string_t cmd_config_speed_all_port =
> @@ -1000,8 +1029,7 @@ cmd_config_speed_specific_parsed(void *parsed_result,
>                                 __attribute__((unused)) void *data)
>  {
>         struct cmd_config_speed_specific *res = parsed_result;
> -       uint16_t link_speed = ETH_LINK_SPEED_AUTONEG;
> -       uint16_t link_duplex = 0;
> +       uint32_t link_speed;
>
>         if (!all_ports_stopped()) {
>                 printf("Please stop all ports first\n");
> @@ -1011,36 +1039,12 @@ cmd_config_speed_specific_parsed(void
> *parsed_result,
>         if (port_id_is_invalid(res->id, ENABLED_WARN))
>                 return;
>
> -       if (!strcmp(res->value1, "10"))
> -               link_speed = ETH_LINK_SPEED_10;
> -       else if (!strcmp(res->value1, "100"))
> -               link_speed = ETH_LINK_SPEED_100;
> -       else if (!strcmp(res->value1, "1000"))
> -               link_speed = ETH_LINK_SPEED_1000;
> -       else if (!strcmp(res->value1, "10000"))
> -               link_speed = ETH_LINK_SPEED_10000;
> -       else if (!strcmp(res->value1, "40000"))
> -               link_speed = ETH_LINK_SPEED_40G;
> -       else if (!strcmp(res->value1, "auto"))
> -               link_speed = ETH_LINK_SPEED_AUTONEG;
> -       else {
> -               printf("Unknown parameter\n");
> +       if (parse_and_check_speed_duplex(res->value1,
> +                                               res->value2,
> +                                               &link_speed) < 0)
>                 return;
> -       }
> -
> -       if (!strcmp(res->value2, "half"))
> -               link_duplex = ETH_LINK_HALF_DUPLEX;
> -       else if (!strcmp(res->value2, "full"))
> -               link_duplex = ETH_LINK_FULL_DUPLEX;
> -       else if (!strcmp(res->value2, "auto"))
> -               link_duplex = ETH_LINK_AUTONEG_DUPLEX;
> -       else {
> -               printf("Unknown parameter\n");
> -               return;
> -       }
>
> -       ports[res->id].dev_conf.link_speed = link_speed;
> -       ports[res->id].dev_conf.link_duplex = link_duplex;
> +       ports[res->id].dev_conf.link_speeds = link_speed;
>
>         cmd_reconfig_device_queue(RTE_PORT_ALL, 1, 1);
>  }
> diff --git a/app/test/virtual_pmd.c b/app/test/virtual_pmd.c
> index a538c8a..3c4040b 100644
> --- a/app/test/virtual_pmd.c
> +++ b/app/test/virtual_pmd.c
> @@ -603,8 +603,8 @@ virtual_ethdev_create(const char *name, struct
> ether_addr *mac_addr,
>
>         TAILQ_INIT(&(eth_dev->link_intr_cbs));
>
> -       eth_dev->data->dev_link.link_status = 0;
> -       eth_dev->data->dev_link.link_speed = ETH_LINK_SPEED_10000;
> +       eth_dev->data->dev_link.link_status = ETH_LINK_DOWN;
> +       eth_dev->data->dev_link.link_speed = ETH_SPEED_NUM_10G;
>         eth_dev->data->dev_link.link_duplex = ETH_LINK_FULL_DUPLEX;
>
>         eth_dev->data->mac_addrs = rte_zmalloc(name, ETHER_ADDR_LEN, 0);
> diff --git a/drivers/net/af_packet/rte_eth_af_packet.c
> b/drivers/net/af_packet/rte_eth_af_packet.c
> index bdd9628..a5d689d 100644
> --- a/drivers/net/af_packet/rte_eth_af_packet.c
> +++ b/drivers/net/af_packet/rte_eth_af_packet.c
> @@ -115,9 +115,10 @@ static const char *valid_arguments[] = {
>  static const char *drivername = "AF_PACKET PMD";
>
>  static struct rte_eth_link pmd_link = {
> -       .link_speed = 10000,
> +       .link_speed = ETH_SPEED_NUM_10G,
>         .link_duplex = ETH_LINK_FULL_DUPLEX,
> -       .link_status = 0
> +       .link_status = ETH_LINK_DOWN,
> +       .link_autoneg = ETH_LINK_SPEED_NEG
>  };
>
>  static uint16_t
> diff --git a/drivers/net/bonding/rte_eth_bond_8023ad.c
> b/drivers/net/bonding/rte_eth_bond_8023ad.c
> index c0f0b99..f375f95 100644
> --- a/drivers/net/bonding/rte_eth_bond_8023ad.c
> +++ b/drivers/net/bonding/rte_eth_bond_8023ad.c
> @@ -708,25 +708,25 @@ link_speed_key(uint16_t speed) {
>         uint16_t key_speed;
>
>         switch (speed) {
> -       case ETH_LINK_SPEED_AUTONEG:
> +       case ETH_SPEED_NUM_NONE:
>                 key_speed = 0x00;
>                 break;
> -       case ETH_LINK_SPEED_10:
> +       case ETH_SPEED_NUM_10M:
>                 key_speed = BOND_LINK_SPEED_KEY_10M;
>                 break;
> -       case ETH_LINK_SPEED_100:
> +       case ETH_SPEED_NUM_100M:
>                 key_speed = BOND_LINK_SPEED_KEY_100M;
>                 break;
> -       case ETH_LINK_SPEED_1000:
> +       case ETH_SPEED_NUM_1G:
>                 key_speed = BOND_LINK_SPEED_KEY_1000M;
>                 break;
> -       case ETH_LINK_SPEED_10G:
> +       case ETH_SPEED_NUM_10G:
>                 key_speed = BOND_LINK_SPEED_KEY_10G;
>                 break;
> -       case ETH_LINK_SPEED_20G:
> +       case ETH_SPEED_NUM_20G:
>                 key_speed = BOND_LINK_SPEED_KEY_20G;
>                 break;
> -       case ETH_LINK_SPEED_40G:
> +       case ETH_SPEED_NUM_40G:
>                 key_speed = BOND_LINK_SPEED_KEY_40G;
>                 break;
>         default:
> diff --git a/drivers/net/cxgbe/base/t4_hw.c
> b/drivers/net/cxgbe/base/t4_hw.c
> index 884d2cf..79af806 100644
> --- a/drivers/net/cxgbe/base/t4_hw.c
> +++ b/drivers/net/cxgbe/base/t4_hw.c
> @@ -2159,13 +2159,13 @@ int t4_handle_fw_rpl(struct adapter *adap, const
> __be64 *rpl)
>                 if (stat & F_FW_PORT_CMD_TXPAUSE)
>                         fc |= PAUSE_TX;
>                 if (stat & V_FW_PORT_CMD_LSPEED(FW_PORT_CAP_SPEED_100M))
> -                       speed = ETH_LINK_SPEED_100;
> +                       speed = ETH_SPEED_NUM_100M;
>                 else if (stat & V_FW_PORT_CMD_LSPEED(FW_PORT_CAP_SPEED_1G))
> -                       speed = ETH_LINK_SPEED_1000;
> +                       speed = ETH_SPEED_NUM_1G;
>                 else if (stat &
> V_FW_PORT_CMD_LSPEED(FW_PORT_CAP_SPEED_10G))
> -                       speed = ETH_LINK_SPEED_10000;
> +                       speed = ETH_SPEED_NUM_10G;
>                 else if (stat &
> V_FW_PORT_CMD_LSPEED(FW_PORT_CAP_SPEED_40G))
> -                       speed = ETH_LINK_SPEED_40G;
> +                       speed = ETH_SPEED_NUM_40G;
>
>                 for_each_port(adap, i) {
>                         pi = adap2pinfo(adap, i);
> diff --git a/drivers/net/e1000/base/e1000_80003es2lan.c
> b/drivers/net/e1000/base/e1000_80003es2lan.c
> index 72692d9..8ca66c4 100644
> --- a/drivers/net/e1000/base/e1000_80003es2lan.c
> +++ b/drivers/net/e1000/base/e1000_80003es2lan.c
> @@ -52,7 +52,7 @@ STATIC s32  e1000_write_nvm_80003es2lan(struct e1000_hw
> *hw, u16 offset,
>  STATIC s32  e1000_get_cfg_done_80003es2lan(struct e1000_hw *hw);
>  STATIC s32  e1000_phy_force_speed_duplex_80003es2lan(struct e1000_hw *hw);
>  STATIC s32  e1000_get_cable_length_80003es2lan(struct e1000_hw *hw);
> -STATIC s32  e1000_get_link_up_info_80003es2lan(struct e1000_hw *hw, u16
> *speed,
> +STATIC s32  e1000_get_link_up_info_80003es2lan(struct e1000_hw *hw, u32
> *speed,
>                                                u16 *duplex);
>  STATIC s32  e1000_reset_hw_80003es2lan(struct e1000_hw *hw);
>  STATIC s32  e1000_init_hw_80003es2lan(struct e1000_hw *hw);
> @@ -789,7 +789,7 @@ STATIC s32 e1000_get_cable_length_80003es2lan(struct
> e1000_hw *hw)
>   *
>   *  Retrieve the current speed and duplex configuration.
>   **/
> -STATIC s32 e1000_get_link_up_info_80003es2lan(struct e1000_hw *hw, u16
> *speed,
> +STATIC s32 e1000_get_link_up_info_80003es2lan(struct e1000_hw *hw, u32
> *speed,
>                                               u16 *duplex)
>  {
>         s32 ret_val;
> @@ -1236,7 +1236,7 @@ STATIC s32
> e1000_setup_copper_link_80003es2lan(struct e1000_hw *hw)
>  STATIC s32 e1000_cfg_on_link_up_80003es2lan(struct e1000_hw *hw)
>  {
>         s32 ret_val = E1000_SUCCESS;
> -       u16 speed;
> +       u32 speed;
>         u16 duplex;
>
>         DEBUGFUNC("e1000_configure_on_link_up");
> diff --git a/drivers/net/e1000/base/e1000_82541.c
> b/drivers/net/e1000/base/e1000_82541.c
> index 952aea2..707b317 100644
> --- a/drivers/net/e1000/base/e1000_82541.c
> +++ b/drivers/net/e1000/base/e1000_82541.c
> @@ -47,7 +47,7 @@ STATIC s32  e1000_init_nvm_params_82541(struct e1000_hw
> *hw);
>  STATIC s32  e1000_init_mac_params_82541(struct e1000_hw *hw);
>  STATIC s32  e1000_reset_hw_82541(struct e1000_hw *hw);
>  STATIC s32  e1000_init_hw_82541(struct e1000_hw *hw);
> -STATIC s32  e1000_get_link_up_info_82541(struct e1000_hw *hw, u16 *speed,
> +STATIC s32  e1000_get_link_up_info_82541(struct e1000_hw *hw, u32 *speed,
>                                          u16 *duplex);
>  STATIC s32  e1000_phy_hw_reset_82541(struct e1000_hw *hw);
>  STATIC s32  e1000_setup_copper_link_82541(struct e1000_hw *hw);
> @@ -437,7 +437,7 @@ out:
>   *
>   * Retrieve the current speed and duplex configuration.
>   **/
> -STATIC s32 e1000_get_link_up_info_82541(struct e1000_hw *hw, u16 *speed,
> +STATIC s32 e1000_get_link_up_info_82541(struct e1000_hw *hw, u32 *speed,
>                                         u16 *duplex)
>  {
>         struct e1000_phy_info *phy = &hw->phy;
> @@ -667,8 +667,8 @@ STATIC s32
> e1000_config_dsp_after_link_change_82541(struct e1000_hw *hw,
>         struct e1000_phy_info *phy = &hw->phy;
>         struct e1000_dev_spec_82541 *dev_spec = &hw->dev_spec._82541;
>         s32 ret_val;
> -       u32 idle_errs = 0;
> -       u16 phy_data, phy_saved_data, speed, duplex, i;
> +       u32 idle_errs = 0, speed;
> +       u16 phy_data, phy_saved_data, duplex, i;
>         u16 ffe_idle_err_timeout = FFE_IDLE_ERR_COUNT_TIMEOUT_20;
>         u16 dsp_reg_array[IGP01E1000_PHY_CHANNEL_NUM] = {
>                                                 IGP01E1000_PHY_AGC_PARAM_A,
> diff --git a/drivers/net/e1000/base/e1000_82543.c
> b/drivers/net/e1000/base/e1000_82543.c
> index 36335ba..9ef3d80 100644
> --- a/drivers/net/e1000/base/e1000_82543.c
> +++ b/drivers/net/e1000/base/e1000_82543.c
> @@ -1192,9 +1192,9 @@ out:
>  STATIC s32 e1000_check_for_copper_link_82543(struct e1000_hw *hw)
>  {
>         struct e1000_mac_info *mac = &hw->mac;
> -       u32 icr, rctl;
> +       u32 icr, rctl, speed;
>         s32 ret_val;
> -       u16 speed, duplex;
> +       u16 duplex;
>         bool link;
>
>         DEBUGFUNC("e1000_check_for_copper_link_82543");
> diff --git a/drivers/net/e1000/base/e1000_82575.c
> b/drivers/net/e1000/base/e1000_82575.c
> index 25fa672..386f058 100644
> --- a/drivers/net/e1000/base/e1000_82575.c
> +++ b/drivers/net/e1000/base/e1000_82575.c
> @@ -53,7 +53,7 @@ STATIC void e1000_release_nvm_82575(struct e1000_hw *hw);
>  STATIC s32  e1000_check_for_link_82575(struct e1000_hw *hw);
>  STATIC s32  e1000_check_for_link_media_swap(struct e1000_hw *hw);
>  STATIC s32  e1000_get_cfg_done_82575(struct e1000_hw *hw);
> -STATIC s32  e1000_get_link_up_info_82575(struct e1000_hw *hw, u16 *speed,
> +STATIC s32  e1000_get_link_up_info_82575(struct e1000_hw *hw, u32 *speed,
>                                          u16 *duplex);
>  STATIC s32  e1000_phy_hw_reset_sgmii_82575(struct e1000_hw *hw);
>  STATIC s32  e1000_read_phy_reg_sgmii_82575(struct e1000_hw *hw, u32
> offset,
> @@ -80,7 +80,7 @@ STATIC s32  e1000_write_phy_reg_sgmii_82575(struct
> e1000_hw *hw,
>  STATIC void e1000_clear_hw_cntrs_82575(struct e1000_hw *hw);
>  STATIC s32  e1000_acquire_swfw_sync_82575(struct e1000_hw *hw, u16 mask);
>  STATIC s32  e1000_get_pcs_speed_and_duplex_82575(struct e1000_hw *hw,
> -                                                u16 *speed, u16 *duplex);
> +                                                u32 *speed, u16 *duplex);
>  STATIC s32  e1000_get_phy_id_82575(struct e1000_hw *hw);
>  STATIC void e1000_release_swfw_sync_82575(struct e1000_hw *hw, u16 mask);
>  STATIC bool e1000_sgmii_active_82575(struct e1000_hw *hw);
> @@ -1165,7 +1165,7 @@ STATIC s32 e1000_get_cfg_done_82575(struct e1000_hw
> *hw)
>   *  interface, use PCS to retrieve the link speed and duplex information.
>   *  Otherwise, use the generic function to get the link speed and duplex
> info.
>   **/
> -STATIC s32 e1000_get_link_up_info_82575(struct e1000_hw *hw, u16 *speed,
> +STATIC s32 e1000_get_link_up_info_82575(struct e1000_hw *hw, u32 *speed,
>                                         u16 *duplex)
>  {
>         s32 ret_val;
> @@ -1192,7 +1192,8 @@ STATIC s32 e1000_get_link_up_info_82575(struct
> e1000_hw *hw, u16 *speed,
>  STATIC s32 e1000_check_for_link_82575(struct e1000_hw *hw)
>  {
>         s32 ret_val;
> -       u16 speed, duplex;
> +       u32 speed;
> +       u16 duplex;
>
>         DEBUGFUNC("e1000_check_for_link_82575");
>
> @@ -1316,7 +1317,7 @@ STATIC void e1000_power_up_serdes_link_82575(struct
> e1000_hw *hw)
>   *  duplex, then store the values in the pointers provided.
>   **/
>  STATIC s32 e1000_get_pcs_speed_and_duplex_82575(struct e1000_hw *hw,
> -                                               u16 *speed, u16 *duplex)
> +                                               u32 *speed, u16 *duplex)
>  {
>         struct e1000_mac_info *mac = &hw->mac;
>         u32 pcs;
> diff --git a/drivers/net/e1000/base/e1000_api.c
> b/drivers/net/e1000/base/e1000_api.c
> index a064565..08e103a 100644
> --- a/drivers/net/e1000/base/e1000_api.c
> +++ b/drivers/net/e1000/base/e1000_api.c
> @@ -669,7 +669,7 @@ s32 e1000_setup_link(struct e1000_hw *hw)
>   *  variables passed in. This is a function pointer entry point called
>   *  by drivers.
>   **/
> -s32 e1000_get_speed_and_duplex(struct e1000_hw *hw, u16 *speed, u16
> *duplex)
> +s32 e1000_get_speed_and_duplex(struct e1000_hw *hw, u32 *speed, u16
> *duplex)
>  {
>         if (hw->mac.ops.get_link_up_info)
>                 return hw->mac.ops.get_link_up_info(hw, speed, duplex);
> diff --git a/drivers/net/e1000/base/e1000_api.h
> b/drivers/net/e1000/base/e1000_api.h
> index 02b16da..39579e0 100644
> --- a/drivers/net/e1000/base/e1000_api.h
> +++ b/drivers/net/e1000/base/e1000_api.h
> @@ -65,7 +65,7 @@ s32 e1000_check_for_link(struct e1000_hw *hw);
>  s32 e1000_reset_hw(struct e1000_hw *hw);
>  s32 e1000_init_hw(struct e1000_hw *hw);
>  s32 e1000_setup_link(struct e1000_hw *hw);
> -s32 e1000_get_speed_and_duplex(struct e1000_hw *hw, u16 *speed, u16
> *duplex);
> +s32 e1000_get_speed_and_duplex(struct e1000_hw *hw, u32 *speed, u16
> *duplex);
>  s32 e1000_disable_pcie_master(struct e1000_hw *hw);
>  void e1000_config_collision_dist(struct e1000_hw *hw);
>  void e1000_rar_set(struct e1000_hw *hw, u8 *addr, u32 index);
> diff --git a/drivers/net/e1000/base/e1000_defines.h
> b/drivers/net/e1000/base/e1000_defines.h
> index 278c507..20c4153 100644
> --- a/drivers/net/e1000/base/e1000_defines.h
> +++ b/drivers/net/e1000/base/e1000_defines.h
> @@ -347,8 +347,8 @@ POSSIBILITY OF SUCH DAMAGE.
>  #define SPEED_100      100
>  #define SPEED_1000     1000
>  #define SPEED_2500     2500
> -#define HALF_DUPLEX    1
> -#define FULL_DUPLEX    2
> +#define HALF_DUPLEX    0
> +#define FULL_DUPLEX    1
>
>  #define PHY_FORCE_TIME 20
>
> diff --git a/drivers/net/e1000/base/e1000_hw.h
> b/drivers/net/e1000/base/e1000_hw.h
> index 4dd92a3..b48a759 100644
> --- a/drivers/net/e1000/base/e1000_hw.h
> +++ b/drivers/net/e1000/base/e1000_hw.h
> @@ -682,7 +682,7 @@ struct e1000_mac_operations {
>         void (*clear_vfta)(struct e1000_hw *);
>         s32  (*get_bus_info)(struct e1000_hw *);
>         void (*set_lan_id)(struct e1000_hw *);
> -       s32  (*get_link_up_info)(struct e1000_hw *, u16 *, u16 *);
> +       s32  (*get_link_up_info)(struct e1000_hw *, u32 *, u16 *);
>         s32  (*led_on)(struct e1000_hw *);
>         s32  (*led_off)(struct e1000_hw *);
>         void (*update_mc_addr_list)(struct e1000_hw *, u8 *, u32);
> diff --git a/drivers/net/e1000/base/e1000_ich8lan.c
> b/drivers/net/e1000/base/e1000_ich8lan.c
> index 3b1627b..7fe9955 100644
> --- a/drivers/net/e1000/base/e1000_ich8lan.c
> +++ b/drivers/net/e1000/base/e1000_ich8lan.c
> @@ -104,7 +104,7 @@ STATIC s32  e1000_setup_link_ich8lan(struct e1000_hw
> *hw);
>  STATIC s32  e1000_setup_copper_link_ich8lan(struct e1000_hw *hw);
>  STATIC s32  e1000_setup_copper_link_pch_lpt(struct e1000_hw *hw);
>  STATIC s32  e1000_get_link_up_info_ich8lan(struct e1000_hw *hw,
> -                                          u16 *speed, u16 *duplex);
> +                                          u32 *speed, u16 *duplex);
>  STATIC s32  e1000_cleanup_led_ich8lan(struct e1000_hw *hw);
>  STATIC s32  e1000_led_on_ich8lan(struct e1000_hw *hw);
>  STATIC s32  e1000_led_off_ich8lan(struct e1000_hw *hw);
> @@ -4561,7 +4561,7 @@ STATIC s32 e1000_setup_copper_link_pch_lpt(struct
> e1000_hw *hw)
>   *  information and then calls the Kumeran lock loss workaround for links
> at
>   *  gigabit speeds.
>   **/
> -STATIC s32 e1000_get_link_up_info_ich8lan(struct e1000_hw *hw, u16 *speed,
> +STATIC s32 e1000_get_link_up_info_ich8lan(struct e1000_hw *hw, u32 *speed,
>                                           u16 *duplex)
>  {
>         s32 ret_val;
> diff --git a/drivers/net/e1000/base/e1000_mac.c
> b/drivers/net/e1000/base/e1000_mac.c
> index c8ec049..6703a17 100644
> --- a/drivers/net/e1000/base/e1000_mac.c
> +++ b/drivers/net/e1000/base/e1000_mac.c
> @@ -106,7 +106,7 @@ void e1000_null_mac_generic(struct e1000_hw
> E1000_UNUSEDARG *hw)
>   *  @hw: pointer to the HW structure
>   **/
>  s32 e1000_null_link_info(struct e1000_hw E1000_UNUSEDARG *hw,
> -                        u16 E1000_UNUSEDARG *s, u16 E1000_UNUSEDARG *d)
> +                        u32 E1000_UNUSEDARG *s, u16 E1000_UNUSEDARG *d)
>  {
>         DEBUGFUNC("e1000_null_link_info");
>         UNREFERENCED_3PARAMETER(hw, s, d);
> @@ -1346,7 +1346,8 @@ s32 e1000_config_fc_after_link_up_generic(struct
> e1000_hw *hw)
>         s32 ret_val = E1000_SUCCESS;
>         u32 pcs_status_reg, pcs_adv_reg, pcs_lp_ability_reg, pcs_ctrl_reg;
>         u16 mii_status_reg, mii_nway_adv_reg, mii_nway_lp_ability_reg;
> -       u16 speed, duplex;
> +       u32 speed;
> +       u16 duplex;
>
>         DEBUGFUNC("e1000_config_fc_after_link_up_generic");
>
> @@ -1648,7 +1649,7 @@ s32 e1000_config_fc_after_link_up_generic(struct
> e1000_hw *hw)
>   *  Read the status register for the current speed/duplex and store the
> current
>   *  speed and duplex for copper connections.
>   **/
> -s32 e1000_get_speed_and_duplex_copper_generic(struct e1000_hw *hw, u16
> *speed,
> +s32 e1000_get_speed_and_duplex_copper_generic(struct e1000_hw *hw, u32
> *speed,
>                                               u16 *duplex)
>  {
>         u32 status;
> @@ -1688,7 +1689,7 @@ s32 e1000_get_speed_and_duplex_copper_generic(struct
> e1000_hw *hw, u16 *speed,
>   *  for fiber/serdes links.
>   **/
>  s32 e1000_get_speed_and_duplex_fiber_serdes_generic(struct e1000_hw
> E1000_UNUSEDARG *hw,
> -                                                   u16 *speed, u16
> *duplex)
> +                                                   u32 *speed, u16
> *duplex)
>  {
>         DEBUGFUNC("e1000_get_speed_and_duplex_fiber_serdes_generic");
>         UNREFERENCED_1PARAMETER(hw);
> diff --git a/drivers/net/e1000/base/e1000_mac.h
> b/drivers/net/e1000/base/e1000_mac.h
> index 5a7ce4a..987df76 100644
> --- a/drivers/net/e1000/base/e1000_mac.h
> +++ b/drivers/net/e1000/base/e1000_mac.h
> @@ -40,7 +40,7 @@ void e1000_init_mac_ops_generic(struct e1000_hw *hw);
>  #endif /* E1000_REMOVED */
>  void e1000_null_mac_generic(struct e1000_hw *hw);
>  s32  e1000_null_ops_generic(struct e1000_hw *hw);
> -s32  e1000_null_link_info(struct e1000_hw *hw, u16 *s, u16 *d);
> +s32  e1000_null_link_info(struct e1000_hw *hw, u32 *s, u16 *d);
>  bool e1000_null_mng_mode(struct e1000_hw *hw);
>  void e1000_null_update_mc(struct e1000_hw *hw, u8 *h, u32 a);
>  void e1000_null_write_vfta(struct e1000_hw *hw, u32 a, u32 b);
> @@ -61,10 +61,10 @@ s32  e1000_get_bus_info_pcie_generic(struct e1000_hw
> *hw);
>  void e1000_set_lan_id_single_port(struct e1000_hw *hw);
>  void e1000_set_lan_id_multi_port_pci(struct e1000_hw *hw);
>  s32  e1000_get_hw_semaphore_generic(struct e1000_hw *hw);
> -s32  e1000_get_speed_and_duplex_copper_generic(struct e1000_hw *hw, u16
> *speed,
> +s32  e1000_get_speed_and_duplex_copper_generic(struct e1000_hw *hw, u32
> *speed,
>                                                u16 *duplex);
>  s32  e1000_get_speed_and_duplex_fiber_serdes_generic(struct e1000_hw *hw,
> -                                                    u16 *speed, u16
> *duplex);
> +                                                    u32 *speed, u16
> *duplex);
>  s32  e1000_id_led_init_generic(struct e1000_hw *hw);
>  s32  e1000_led_on_generic(struct e1000_hw *hw);
>  s32  e1000_led_off_generic(struct e1000_hw *hw);
> diff --git a/drivers/net/e1000/base/e1000_vf.c
> b/drivers/net/e1000/base/e1000_vf.c
> index 778561e..2221f1c 100644
> --- a/drivers/net/e1000/base/e1000_vf.c
> +++ b/drivers/net/e1000/base/e1000_vf.c
> @@ -43,7 +43,7 @@ STATIC s32 e1000_setup_link_vf(struct e1000_hw *hw);
>  STATIC s32 e1000_get_bus_info_pcie_vf(struct e1000_hw *hw);
>  STATIC s32 e1000_init_mac_params_vf(struct e1000_hw *hw);
>  STATIC s32 e1000_check_for_link_vf(struct e1000_hw *hw);
> -STATIC s32 e1000_get_link_up_info_vf(struct e1000_hw *hw, u16 *speed,
> +STATIC s32 e1000_get_link_up_info_vf(struct e1000_hw *hw, u32 *speed,
>                                      u16 *duplex);
>  STATIC s32 e1000_init_hw_vf(struct e1000_hw *hw);
>  STATIC s32 e1000_reset_hw_vf(struct e1000_hw *hw);
> @@ -220,7 +220,7 @@ STATIC s32 e1000_get_bus_info_pcie_vf(struct e1000_hw
> *hw)
>   *  Since we cannot read the PHY and get accurate link info, we must rely
> upon
>   *  the status register's data which is often stale and inaccurate.
>   **/
> -STATIC s32 e1000_get_link_up_info_vf(struct e1000_hw *hw, u16 *speed,
> +STATIC s32 e1000_get_link_up_info_vf(struct e1000_hw *hw, u32 *speed,
>                                      u16 *duplex)
>  {
>         s32 status;
> diff --git a/drivers/net/e1000/base/e1000_vf.h
> b/drivers/net/e1000/base/e1000_vf.h
> index 6d5bd99..9d801ad 100644
> --- a/drivers/net/e1000/base/e1000_vf.h
> +++ b/drivers/net/e1000/base/e1000_vf.h
> @@ -201,7 +201,7 @@ struct e1000_mac_operations {
>         s32  (*check_for_link)(struct e1000_hw *);
>         void (*clear_vfta)(struct e1000_hw *);
>         s32  (*get_bus_info)(struct e1000_hw *);
> -       s32  (*get_link_up_info)(struct e1000_hw *, u16 *, u16 *);
> +       s32  (*get_link_up_info)(struct e1000_hw *, u32 *, u16 *);
>         void (*update_mc_addr_list)(struct e1000_hw *, u8 *, u32);
>         s32  (*reset_hw)(struct e1000_hw *);
>         s32  (*init_hw)(struct e1000_hw *);
> diff --git a/drivers/net/e1000/em_ethdev.c b/drivers/net/e1000/em_ethdev.c
> index 72f792c..35ef558 100644
> --- a/drivers/net/e1000/em_ethdev.c
> +++ b/drivers/net/e1000/em_ethdev.c
> @@ -493,6 +493,9 @@ eth_em_start(struct rte_eth_dev *dev)
>         struct e1000_hw *hw =
>                 E1000_DEV_PRIVATE_TO_HW(dev->data->dev_private);
>         int ret, mask;
> +       uint32_t *speeds;
> +       int num_speeds;
> +       bool autoneg;
>
>         PMD_INIT_FUNC_TRACE();
>
> @@ -547,56 +550,46 @@ eth_em_start(struct rte_eth_dev *dev)
>         E1000_WRITE_REG(hw, E1000_ITR, UINT16_MAX);
>
>         /* Setup link speed and duplex */
> -       switch (dev->data->dev_conf.link_speed) {
> -       case ETH_LINK_SPEED_AUTONEG:
> -               if (dev->data->dev_conf.link_duplex ==
> ETH_LINK_AUTONEG_DUPLEX)
> -                       hw->phy.autoneg_advertised =
> E1000_ALL_SPEED_DUPLEX;
> -               else if (dev->data->dev_conf.link_duplex ==
> -                                       ETH_LINK_HALF_DUPLEX)
> -                       hw->phy.autoneg_advertised = E1000_ALL_HALF_DUPLEX;
> -               else if (dev->data->dev_conf.link_duplex ==
> -                                       ETH_LINK_FULL_DUPLEX)
> -                       hw->phy.autoneg_advertised = E1000_ALL_FULL_DUPLEX;
> -               else
> -                       goto error_invalid_config;
> -               break;
> -       case ETH_LINK_SPEED_10:
> -               if (dev->data->dev_conf.link_duplex ==
> ETH_LINK_AUTONEG_DUPLEX)
> -                       hw->phy.autoneg_advertised = E1000_ALL_10_SPEED;
> -               else if (dev->data->dev_conf.link_duplex ==
> -                                       ETH_LINK_HALF_DUPLEX)
> -                       hw->phy.autoneg_advertised = ADVERTISE_10_HALF;
> -               else if (dev->data->dev_conf.link_duplex ==
> -                                       ETH_LINK_FULL_DUPLEX)
> -                       hw->phy.autoneg_advertised = ADVERTISE_10_FULL;
> -               else
> -                       goto error_invalid_config;
> -               break;
> -       case ETH_LINK_SPEED_100:
> -               if (dev->data->dev_conf.link_duplex ==
> ETH_LINK_AUTONEG_DUPLEX)
> -                       hw->phy.autoneg_advertised = E1000_ALL_100_SPEED;
> -               else if (dev->data->dev_conf.link_duplex ==
> -                                       ETH_LINK_HALF_DUPLEX)
> -                       hw->phy.autoneg_advertised = ADVERTISE_100_HALF;
> -               else if (dev->data->dev_conf.link_duplex ==
> -                                       ETH_LINK_FULL_DUPLEX)
> -                       hw->phy.autoneg_advertised = ADVERTISE_100_FULL;
> -               else
> +       speeds = &dev->data->dev_conf.link_speeds;
> +       if (*speeds == ETH_LINK_SPEED_AUTONEG) {
> +               hw->phy.autoneg_advertised = E1000_ALL_SPEED_DUPLEX;
> +       } else {
> +               num_speeds = 0;
> +               autoneg = ~(*speeds & ETH_LINK_SPEED_NO_AUTONEG);
> +
> +               /* Reset */
> +               hw->phy.autoneg_advertised = 0;
> +
> +               if (*speeds & ~(ETH_LINK_SPEED_10M_HD | ETH_LINK_SPEED_10M
> |
> +                               ETH_LINK_SPEED_100M_HD |
> ETH_LINK_SPEED_100M |
> +                               ETH_LINK_SPEED_1G)) {
> +                       num_speeds = -1;
>                         goto error_invalid_config;
> -               break;
> -       case ETH_LINK_SPEED_1000:
> -               if ((dev->data->dev_conf.link_duplex ==
> -                               ETH_LINK_AUTONEG_DUPLEX) ||
> -                       (dev->data->dev_conf.link_duplex ==
> -                                       ETH_LINK_FULL_DUPLEX))
> -                       hw->phy.autoneg_advertised = ADVERTISE_1000_FULL;
> -               else
> +               }
> +               if (*speeds & ETH_LINK_SPEED_10M_HD) {
> +                       hw->phy.autoneg_advertised |= ADVERTISE_10_HALF;
> +                       num_speeds++;
> +               }
> +               if (*speeds & ETH_LINK_SPEED_10M) {
> +                       hw->phy.autoneg_advertised |= ADVERTISE_10_FULL;
> +                       num_speeds++;
> +               }
> +               if (*speeds & ETH_LINK_SPEED_100M_HD) {
> +                       hw->phy.autoneg_advertised |= ADVERTISE_100_HALF;
> +                       num_speeds++;
> +               }
> +               if (*speeds & ETH_LINK_SPEED_100M) {
> +                       hw->phy.autoneg_advertised |= ADVERTISE_100_FULL;
> +                       num_speeds++;
> +               }
> +               if (*speeds & ETH_LINK_SPEED_1G) {
> +                       hw->phy.autoneg_advertised |= ADVERTISE_1000_FULL;
> +                       num_speeds++;
> +               }
> +               if (num_speeds == 0 || (!autoneg && (num_speeds > 2)))
>                         goto error_invalid_config;
> -               break;
> -       case ETH_LINK_SPEED_10000:
> -       default:
> -               goto error_invalid_config;
>         }
> +
>         e1000_setup_link(hw);
>
>         /* check if lsc interrupt feature is enabled */
> @@ -616,9 +609,8 @@ eth_em_start(struct rte_eth_dev *dev)
>         return (0);
>
>  error_invalid_config:
> -       PMD_INIT_LOG(ERR, "Invalid link_speed/link_duplex (%u/%u) for port
> %u",
> -                    dev->data->dev_conf.link_speed,
> -                    dev->data->dev_conf.link_duplex, dev->data->port_id);
> +       PMD_INIT_LOG(ERR, "Invalid advertised speeds (%u) for port %u",
> +                    dev->data->dev_conf.link_speeds, dev->data->port_id);
>         em_dev_clear_queues(dev);
>         return (-EINVAL);
>  }
> @@ -934,11 +926,11 @@ eth_em_infos_get(struct rte_eth_dev *dev, struct
> rte_eth_dev_info *dev_info)
>         dev_info->max_rx_queues = 1;
>         dev_info->max_tx_queues = 1;
>
> -       dev_info->speed_capa = ETH_SPEED_CAP_10M_HD |
> -                                       ETH_SPEED_CAP_10M_FD |
> -                                       ETH_SPEED_CAP_100M_HD |
> -                                       ETH_SPEED_CAP_100M_FD |
> -                                       ETH_SPEED_CAP_1G;
> +       dev_info->speed_capa = ETH_LINK_SPEED_10M_HD |
> +                                       ETH_LINK_SPEED_10M |
> +                                       ETH_LINK_SPEED_100M_HD |
> +                                       ETH_LINK_SPEED_100M |
> +                                       ETH_LINK_SPEED_1G;
>  }
>
>  /* return 0 means link status changed, -1 means not changed */
> @@ -987,13 +979,16 @@ eth_em_link_update(struct rte_eth_dev *dev, int
> wait_to_complete)
>
>         /* Now we check if a transition has happened */
>         if (link_check && (link.link_status == 0)) {
> +               uint16_t duplex;
>                 hw->mac.ops.get_link_up_info(hw, &link.link_speed,
> -                       &link.link_duplex);
> -               link.link_status = 1;
> +                       &duplex);
> +               link.link_duplex = (duplex) ? ETH_LINK_FULL_DUPLEX :
> +                                               ETH_LINK_HALF_DUPLEX;
> +               link.link_status = ETH_LINK_UP;
>         } else if (!link_check && (link.link_status == 1)) {
>                 link.link_speed = 0;
> -               link.link_duplex = 0;
> -               link.link_status = 0;
> +               link.link_duplex = ETH_LINK_HALF_DUPLEX;
> +               link.link_status = ETH_LINK_DOWN;
>         }
>         rte_em_dev_atomic_write_link_status(dev, &link);
>
> diff --git a/drivers/net/e1000/igb_ethdev.c
> b/drivers/net/e1000/igb_ethdev.c
> index 927f5d9..2bbac02 100644
> --- a/drivers/net/e1000/igb_ethdev.c
> +++ b/drivers/net/e1000/igb_ethdev.c
> @@ -889,6 +889,9 @@ eth_igb_start(struct rte_eth_dev *dev)
>         int ret, mask;
>         uint32_t intr_vector = 0;
>         uint32_t ctrl_ext;
> +       uint32_t *speeds;
> +       int num_speeds;
> +       bool autoneg;
>
>         PMD_INIT_FUNC_TRACE();
>
> @@ -984,48 +987,46 @@ eth_igb_start(struct rte_eth_dev *dev)
>         }
>
>         /* Setup link speed and duplex */
> -       switch (dev->data->dev_conf.link_speed) {
> -       case ETH_LINK_SPEED_AUTONEG:
> -               if (dev->data->dev_conf.link_duplex ==
> ETH_LINK_AUTONEG_DUPLEX)
> -                       hw->phy.autoneg_advertised =
> E1000_ALL_SPEED_DUPLEX;
> -               else if (dev->data->dev_conf.link_duplex ==
> ETH_LINK_HALF_DUPLEX)
> -                       hw->phy.autoneg_advertised = E1000_ALL_HALF_DUPLEX;
> -               else if (dev->data->dev_conf.link_duplex ==
> ETH_LINK_FULL_DUPLEX)
> -                       hw->phy.autoneg_advertised = E1000_ALL_FULL_DUPLEX;
> -               else
> -                       goto error_invalid_config;
> -               break;
> -       case ETH_LINK_SPEED_10:
> -               if (dev->data->dev_conf.link_duplex ==
> ETH_LINK_AUTONEG_DUPLEX)
> -                       hw->phy.autoneg_advertised = E1000_ALL_10_SPEED;
> -               else if (dev->data->dev_conf.link_duplex ==
> ETH_LINK_HALF_DUPLEX)
> -                       hw->phy.autoneg_advertised = ADVERTISE_10_HALF;
> -               else if (dev->data->dev_conf.link_duplex ==
> ETH_LINK_FULL_DUPLEX)
> -                       hw->phy.autoneg_advertised = ADVERTISE_10_FULL;
> -               else
> -                       goto error_invalid_config;
> -               break;
> -       case ETH_LINK_SPEED_100:
> -               if (dev->data->dev_conf.link_duplex ==
> ETH_LINK_AUTONEG_DUPLEX)
> -                       hw->phy.autoneg_advertised = E1000_ALL_100_SPEED;
> -               else if (dev->data->dev_conf.link_duplex ==
> ETH_LINK_HALF_DUPLEX)
> -                       hw->phy.autoneg_advertised = ADVERTISE_100_HALF;
> -               else if (dev->data->dev_conf.link_duplex ==
> ETH_LINK_FULL_DUPLEX)
> -                       hw->phy.autoneg_advertised = ADVERTISE_100_FULL;
> -               else
> +       speeds = &dev->data->dev_conf.link_speeds;
> +       if (*speeds == ETH_LINK_SPEED_AUTONEG) {
> +               hw->phy.autoneg_advertised = E1000_ALL_SPEED_DUPLEX;
> +       } else {
> +               num_speeds = 0;
> +               autoneg = ~(*speeds & ETH_LINK_SPEED_NO_AUTONEG);
> +
> +               /* Reset */
> +               hw->phy.autoneg_advertised = 0;
> +
> +               if (*speeds & ~(ETH_LINK_SPEED_10M_HD | ETH_LINK_SPEED_10M
> |
> +                               ETH_LINK_SPEED_100M_HD |
> ETH_LINK_SPEED_100M |
> +                               ETH_LINK_SPEED_1G)) {
> +                       num_speeds = -1;
>                         goto error_invalid_config;
> -               break;
> -       case ETH_LINK_SPEED_1000:
> -               if ((dev->data->dev_conf.link_duplex ==
> ETH_LINK_AUTONEG_DUPLEX) ||
> -                               (dev->data->dev_conf.link_duplex ==
> ETH_LINK_FULL_DUPLEX))
> -                       hw->phy.autoneg_advertised = ADVERTISE_1000_FULL;
> -               else
> +               }
> +               if (*speeds & ETH_LINK_SPEED_10M_HD) {
> +                       hw->phy.autoneg_advertised |= ADVERTISE_10_HALF;
> +                       num_speeds++;
> +               }
> +               if (*speeds & ETH_LINK_SPEED_10M) {
> +                       hw->phy.autoneg_advertised |= ADVERTISE_10_FULL;
> +                       num_speeds++;
> +               }
> +               if (*speeds & ETH_LINK_SPEED_100M_HD) {
> +                       hw->phy.autoneg_advertised |= ADVERTISE_100_HALF;
> +                       num_speeds++;
> +               }
> +               if (*speeds & ETH_LINK_SPEED_100M) {
> +                       hw->phy.autoneg_advertised |= ADVERTISE_100_FULL;
> +                       num_speeds++;
> +               }
> +               if (*speeds & ETH_LINK_SPEED_1G) {
> +                       hw->phy.autoneg_advertised |= ADVERTISE_1000_FULL;
> +                       num_speeds++;
> +               }
> +               if (num_speeds == 0 || (!autoneg && (num_speeds > 2)))
>                         goto error_invalid_config;
> -               break;
> -       case ETH_LINK_SPEED_10000:
> -       default:
> -               goto error_invalid_config;
>         }
> +
>         e1000_setup_link(hw);
>
>         /* check if lsc interrupt feature is enabled */
> @@ -1055,9 +1056,8 @@ eth_igb_start(struct rte_eth_dev *dev)
>         return (0);
>
>  error_invalid_config:
> -       PMD_INIT_LOG(ERR, "Invalid link_speed/link_duplex (%u/%u) for port
> %u",
> -                    dev->data->dev_conf.link_speed,
> -                    dev->data->dev_conf.link_duplex, dev->data->port_id);
> +       PMD_INIT_LOG(ERR, "Invalid advertised speeds (%u) for port %u",
> +                    dev->data->dev_conf.link_speeds, dev->data->port_id);
>         igb_dev_clear_queues(dev);
>         return (-EINVAL);
>  }
> @@ -1571,11 +1571,11 @@ eth_igb_infos_get(struct rte_eth_dev *dev, struct
> rte_eth_dev_info *dev_info)
>                 .txq_flags = 0,
>         };
>
> -       dev_info->speed_capa = ETH_SPEED_CAP_10M_HD |
> -                                       ETH_SPEED_CAP_10M_FD |
> -                                       ETH_SPEED_CAP_100M_HD |
> -                                       ETH_SPEED_CAP_100M_FD |
> -                                       ETH_SPEED_CAP_1G;
> +       dev_info->speed_capa = ETH_LINK_SPEED_10M_HD |
> +                                       ETH_LINK_SPEED_10M |
> +                                       ETH_LINK_SPEED_100M_HD |
> +                                       ETH_LINK_SPEED_100M |
> +                                       ETH_LINK_SPEED_1G;
>  }
>
>  static void
> @@ -1681,13 +1681,19 @@ eth_igb_link_update(struct rte_eth_dev *dev, int
> wait_to_complete)
>
>         /* Now we check if a transition has happened */
>         if (link_check) {
> +               uint16_t duplex;
>                 hw->mac.ops.get_link_up_info(hw, &link.link_speed,
> -                                         &link.link_duplex);
> -               link.link_status = 1;
> +                                         &duplex);
> +               link.link_duplex = (duplex) ? ETH_LINK_FULL_DUPLEX :
> +
>  ETH_LINK_HALF_DUPLEX ;
> +               link.link_status = ETH_LINK_UP;
> +               link.link_autoneg = ~(dev->data->dev_conf.link_speeds &
> +                                               ETH_LINK_SPEED_NO_AUTONEG);
>         } else if (!link_check) {
>                 link.link_speed = 0;
> -               link.link_duplex = 0;
> -               link.link_status = 0;
> +               link.link_duplex = ETH_LINK_HALF_DUPLEX;
> +               link.link_status = ETH_LINK_DOWN;
> +               link.link_autoneg = ETH_LINK_SPEED_FIXED;
>         }
>         rte_igb_dev_atomic_write_link_status(dev, &link);
>
> diff --git a/drivers/net/fm10k/fm10k_ethdev.c
> b/drivers/net/fm10k/fm10k_ethdev.c
> index ca6357c..6e05355 100644
> --- a/drivers/net/fm10k/fm10k_ethdev.c
> +++ b/drivers/net/fm10k/fm10k_ethdev.c
> @@ -862,7 +862,7 @@ fm10k_link_update(struct rte_eth_dev *dev,
>          * is no 50Gbps Ethernet. */
>         dev->data->dev_link.link_speed  = 0;
>         dev->data->dev_link.link_duplex = ETH_LINK_FULL_DUPLEX;
> -       dev->data->dev_link.link_status = 1;
> +       dev->data->dev_link.link_status = ETH_LINK_UP;
>
>         return 0;
>  }
> @@ -964,9 +964,9 @@ fm10k_dev_infos_get(struct rte_eth_dev *dev,
>                                 ETH_TXQ_FLAGS_NOOFFLOADS,
>         };
>
> -       dev_info->speed_capa = ETH_SPEED_CAP_1G | ETH_SPEED_CAP_2_5G |
> -                                       ETH_SPEED_CAP_10G |
> ETH_SPEED_CAP_25G |
> -                                       ETH_SPEED_CAP_40G |
> ETH_SPEED_CAP_100G;
> +       dev_info->speed_capa = ETH_LINK_SPEED_1G | ETH_LINK_SPEED_2_5G |
> +                               ETH_LINK_SPEED_10G | ETH_LINK_SPEED_25G |
> +                               ETH_LINK_SPEED_40G | ETH_LINK_SPEED_100G;
>  }
>
>  static int
> diff --git a/drivers/net/i40e/i40e_ethdev.c
> b/drivers/net/i40e/i40e_ethdev.c
> index 8a5dfbf..b18e81f 100644
> --- a/drivers/net/i40e/i40e_ethdev.c
> +++ b/drivers/net/i40e/i40e_ethdev.c
> @@ -835,27 +835,20 @@ i40e_vsi_disable_queues_intr(struct i40e_vsi *vsi)
>  }
>
>  static inline uint8_t
> -i40e_parse_link_speed(uint16_t eth_link_speed)
> +i40e_parse_link_speeds(uint16_t link_speeds)
>  {
>         uint8_t link_speed = I40E_LINK_SPEED_UNKNOWN;
>
> -       switch (eth_link_speed) {
> -       case ETH_LINK_SPEED_40G:
> -               link_speed = I40E_LINK_SPEED_40GB;
> -               break;
> -       case ETH_LINK_SPEED_20G:
> -               link_speed = I40E_LINK_SPEED_20GB;
> -               break;
> -       case ETH_LINK_SPEED_10G:
> -               link_speed = I40E_LINK_SPEED_10GB;
> -               break;
> -       case ETH_LINK_SPEED_1000:
> -               link_speed = I40E_LINK_SPEED_1GB;
> -               break;
> -       case ETH_LINK_SPEED_100:
> -               link_speed = I40E_LINK_SPEED_100MB;
> -               break;
> -       }
> +       if (link_speeds & ETH_LINK_SPEED_40G)
> +               link_speed |= I40E_LINK_SPEED_40GB;
> +       if (link_speeds & ETH_LINK_SPEED_20G)
> +               link_speed |= I40E_LINK_SPEED_20GB;
> +       if (link_speeds & ETH_LINK_SPEED_10G)
> +               link_speed |= I40E_LINK_SPEED_10GB;
> +       if (link_speeds & ETH_LINK_SPEED_1G)
> +               link_speed |= I40E_LINK_SPEED_1GB;
> +       if (link_speeds & ETH_LINK_SPEED_100M)
> +               link_speed |= I40E_LINK_SPEED_100MB;
>
>         return link_speed;
>  }
> @@ -924,9 +917,9 @@ i40e_apply_link_speed(struct rte_eth_dev *dev)
>         struct i40e_hw *hw =
> I40E_DEV_PRIVATE_TO_HW(dev->data->dev_private);
>         struct rte_eth_conf *conf = &dev->data->dev_conf;
>
> -       speed = i40e_parse_link_speed(conf->link_speed);
> +       speed = i40e_parse_link_speeds(conf->link_speeds);
>         abilities |= I40E_AQ_PHY_ENABLE_ATOMIC_LINK;
> -       if (conf->link_speed == ETH_LINK_SPEED_AUTONEG)
> +       if (conf->link_speeds & ETH_LINK_SPEED_AUTONEG)
>                 abilities |= I40E_AQ_PHY_AN_ENABLED;
>         else
>                 abilities |= I40E_AQ_PHY_LINK_ENABLED;
> @@ -944,10 +937,8 @@ i40e_dev_start(struct rte_eth_dev *dev)
>
>         hw->adapter_stopped = 0;
>
> -       if ((dev->data->dev_conf.link_duplex != ETH_LINK_AUTONEG_DUPLEX) &&
> -               (dev->data->dev_conf.link_duplex != ETH_LINK_FULL_DUPLEX))
> {
> -               PMD_INIT_LOG(ERR, "Invalid link_duplex (%hu) for port
> %hhu",
> -                            dev->data->dev_conf.link_duplex,
> +       if (dev->data->dev_conf.link_speeds & ETH_LINK_SPEED_NO_AUTONEG) {
> +               PMD_INIT_LOG(ERR, "Invalid link_speeds for port %hhu;
> autonegociation disabled",
>                              dev->data->port_id);
>                 return -EINVAL;
>         }
> @@ -995,6 +986,13 @@ i40e_dev_start(struct rte_eth_dev *dev)
>         }
>
>         /* Apply link configure */
> +       if (dev->data->dev_conf.link_speeds & ~(ETH_LINK_SPEED_100M |
> +                               ETH_LINK_SPEED_1G | ETH_LINK_SPEED_10G |
> +                               ETH_LINK_SPEED_20G | ETH_LINK_SPEED_40G)) {
> +               PMD_DRV_LOG(ERR, "Invalid link setting");
> +               goto err_up;
> +       }
> +
>         ret = i40e_apply_link_speed(dev);
>         if (I40E_SUCCESS != ret) {
>                 PMD_DRV_LOG(ERR, "Fail to apply link setting");
> @@ -1209,7 +1207,7 @@ i40e_dev_link_update(struct rte_eth_dev *dev,
>                 /* Get link status information from hardware */
>                 status = i40e_aq_get_link_info(hw, false, &link_status,
> NULL);
>                 if (status != I40E_SUCCESS) {
> -                       link.link_speed = ETH_LINK_SPEED_100;
> +                       link.link_speed = ETH_SPEED_NUM_100M;
>                         link.link_duplex = ETH_LINK_FULL_DUPLEX;
>                         PMD_DRV_LOG(ERR, "Failed to get link info");
>                         goto out;
> @@ -1231,25 +1229,28 @@ i40e_dev_link_update(struct rte_eth_dev *dev,
>         /* Parse the link status */
>         switch (link_status.link_speed) {
>         case I40E_LINK_SPEED_100MB:
> -               link.link_speed = ETH_LINK_SPEED_100;
> +               link.link_speed = ETH_SPEED_NUM_100M;
>                 break;
>         case I40E_LINK_SPEED_1GB:
> -               link.link_speed = ETH_LINK_SPEED_1000;
> +               link.link_speed = ETH_SPEED_NUM_1G;
>                 break;
>         case I40E_LINK_SPEED_10GB:
> -               link.link_speed = ETH_LINK_SPEED_10G;
> +               link.link_speed = ETH_SPEED_NUM_10G;
>                 break;
>         case I40E_LINK_SPEED_20GB:
> -               link.link_speed = ETH_LINK_SPEED_20G;
> +               link.link_speed = ETH_SPEED_NUM_20G;
>                 break;
>         case I40E_LINK_SPEED_40GB:
> -               link.link_speed = ETH_LINK_SPEED_40G;
> +               link.link_speed = ETH_SPEED_NUM_40G;
>                 break;
>         default:
> -               link.link_speed = ETH_LINK_SPEED_100;
> +               link.link_speed = ETH_SPEED_NUM_100M;
>                 break;
>         }
>
> +       link.link_autoneg = ~(dev->data->dev_conf.link_speeds &
> +                                               ETH_LINK_SPEED_NO_AUTONEG);
> +
>  out:
>         rte_i40e_dev_atomic_write_link_status(dev, &link);
>         if (link.link_status == old.link_status)
> @@ -1687,10 +1688,10 @@ i40e_dev_info_get(struct rte_eth_dev *dev, struct
> rte_eth_dev_info *dev_info)
>
>         if (i40e_is_40G_device(hw->device_id))
>                 /* For XL710 */
> -               dev_info->speed_capa = ETH_SPEED_CAP_1G |
> ETH_SPEED_CAP_10G;
> +               dev_info->speed_capa = ETH_LINK_SPEED_1G |
> ETH_LINK_SPEED_10G;
>         else
>                 /* For X710 */
> -               dev_info->speed_capa = ETH_SPEED_CAP_10G |
> ETH_SPEED_CAP_40G;
> +               dev_info->speed_capa = ETH_LINK_SPEED_10G |
> ETH_LINK_SPEED_40G;
>
>  }
>
> @@ -6195,15 +6196,15 @@ i40e_timesync_enable(struct rte_eth_dev *dev)
>         uint32_t tsync_inc_h;
>
>         switch (link->link_speed) {
> -       case ETH_LINK_SPEED_40G:
> +       case ETH_SPEED_NUM_40G:
>                 tsync_inc_l = I40E_PTP_40GB_INCVAL & 0xFFFFFFFF;
>                 tsync_inc_h = I40E_PTP_40GB_INCVAL >> 32;
>                 break;
> -       case ETH_LINK_SPEED_10G:
> +       case ETH_SPEED_NUM_10G:
>                 tsync_inc_l = I40E_PTP_10GB_INCVAL & 0xFFFFFFFF;
>                 tsync_inc_h = I40E_PTP_10GB_INCVAL >> 32;
>                 break;
> -       case ETH_LINK_SPEED_1000:
> +       case ETH_SPEED_NUM_1G:
>                 tsync_inc_l = I40E_PTP_1GB_INCVAL & 0xFFFFFFFF;
>                 tsync_inc_h = I40E_PTP_1GB_INCVAL >> 32;
>                 break;
> diff --git a/drivers/net/i40e/i40e_ethdev_vf.c
> b/drivers/net/i40e/i40e_ethdev_vf.c
> index b694400..8d3acae 100644
> --- a/drivers/net/i40e/i40e_ethdev_vf.c
> +++ b/drivers/net/i40e/i40e_ethdev_vf.c
> @@ -1635,13 +1635,14 @@ i40evf_dev_link_update(struct rte_eth_dev *dev,
>          * DPDK pf host provide interfacet to acquire link status
>          * while Linux driver does not
>          */
> -       if (vf->version_major == I40E_DPDK_VERSION_MAJOR)
> +       if (vf->version_major == I40E_DPDK_VERSION_MAJOR) {
>                 i40evf_get_link_status(dev, &new_link);
> -       else {
> +       } else {
>                 /* Always assume it's up, for Linux driver PF host */
> -               new_link.link_duplex = ETH_LINK_AUTONEG_DUPLEX;
> -               new_link.link_speed  = ETH_LINK_SPEED_10000;
> -               new_link.link_status = 1;
> +               new_link.link_speed  = ETH_SPEED_NUM_10G;
> +               new_link.link_duplex = ETH_LINK_FULL_DUPLEX;
> +               new_link.link_autoneg = ETH_LINK_SPEED_NEG;
> +               new_link.link_status = ETH_LINK_UP;
>         }
>         i40evf_dev_atomic_write_link_status(dev, &new_link);
>
> diff --git a/drivers/net/ixgbe/ixgbe_ethdev.c
> b/drivers/net/ixgbe/ixgbe_ethdev.c
> index 3be84aa..f4dd1d2 100644
> --- a/drivers/net/ixgbe/ixgbe_ethdev.c
> +++ b/drivers/net/ixgbe/ixgbe_ethdev.c
> @@ -1676,14 +1676,13 @@ ixgbe_dev_start(struct rte_eth_dev *dev)
>         int mask = 0;
>         int status;
>         uint16_t vf, idx;
> +       uint32_t *link_speeds;
>
>         PMD_INIT_FUNC_TRACE();
>
>         /* IXGBE devices don't support half duplex */
> -       if ((dev->data->dev_conf.link_duplex != ETH_LINK_AUTONEG_DUPLEX) &&
> -                       (dev->data->dev_conf.link_duplex !=
> ETH_LINK_FULL_DUPLEX)) {
> -               PMD_INIT_LOG(ERR, "Invalid link_duplex (%hu) for port
> %hhu",
> -                            dev->data->dev_conf.link_duplex,
> +       if (dev->data->dev_conf.link_speeds & ETH_LINK_SPEED_NO_AUTONEG) {
> +               PMD_INIT_LOG(ERR, "Invalid link_speeds for port %hhu;
> autonegociation disabled",
>                              dev->data->port_id);
>                 return -EINVAL;
>         }
> @@ -1769,32 +1768,22 @@ ixgbe_dev_start(struct rte_eth_dev *dev)
>         if (err)
>                 goto error;
>
> -       switch(dev->data->dev_conf.link_speed) {
> -       case ETH_LINK_SPEED_AUTONEG:
> -               speed = (hw->mac.type != ixgbe_mac_82598EB) ?
> -                               IXGBE_LINK_SPEED_82599_AUTONEG :
> -                               IXGBE_LINK_SPEED_82598_AUTONEG;
> -               break;
> -       case ETH_LINK_SPEED_100:
> -               /*
> -                * Invalid for 82598 but error will be detected by
> -                * ixgbe_setup_link()
> -                */
> -               speed = IXGBE_LINK_SPEED_100_FULL;
> -               break;
> -       case ETH_LINK_SPEED_1000:
> -               speed = IXGBE_LINK_SPEED_1GB_FULL;
> -               break;
> -       case ETH_LINK_SPEED_10000:
> -               speed = IXGBE_LINK_SPEED_10GB_FULL;
> -               break;
> -       default:
> -               PMD_INIT_LOG(ERR, "Invalid link_speed (%hu) for port %hhu",
> -                            dev->data->dev_conf.link_speed,
> -                            dev->data->port_id);
> +       link_speeds = &dev->data->dev_conf.link_speeds;
> +       if (*link_speeds & ~(ETH_LINK_SPEED_100M | ETH_LINK_SPEED_1G |
> +
>  ETH_LINK_SPEED_10G)) {
> +               PMD_INIT_LOG(ERR, "Invalid link setting");
>                 goto error;
>         }
>
> +       speed = 0x0;
> +
> +       if (*link_speeds & ETH_LINK_SPEED_10G)
> +               speed |= IXGBE_LINK_SPEED_10GB_FULL;
> +       if (*link_speeds & ETH_LINK_SPEED_1G)
> +               speed |= IXGBE_LINK_SPEED_1GB_FULL;
> +       if (*link_speeds & ETH_LINK_SPEED_100M)
> +               speed |= IXGBE_LINK_SPEED_100_FULL;
> +
>         err = ixgbe_setup_link(hw, speed, link_up);
>         if (err)
>                 goto error;
> @@ -2400,15 +2389,16 @@ ixgbe_dev_info_get(struct rte_eth_dev *dev, struct
> rte_eth_dev_info *dev_info)
>         dev_info->reta_size = ETH_RSS_RETA_SIZE_128;
>         dev_info->flow_type_rss_offloads = IXGBE_RSS_OFFLOAD_ALL;
>
> -       dev_info->speed_capa = ETH_SPEED_CAP_1G | ETH_SPEED_CAP_10G;
> +       dev_info->speed_capa = ETH_LINK_SPEED_1G | ETH_LINK_SPEED_10G;
>
>         if (hw->mac.type == ixgbe_mac_X540 ||
>             hw->mac.type == ixgbe_mac_X540_vf ||
>             hw->mac.type == ixgbe_mac_X550 ||
> -           hw->mac.type == ixgbe_mac_X550_vf)
> +           hw->mac.type == ixgbe_mac_X550_vf) {
>
> -               dev_info->speed_capa |= ETH_SPEED_CAP_100M_FD /*|
> -                                       ETH_SPEED_CAP_100M_HD*/;
> +               dev_info->speed_capa |= ETH_LINK_SPEED_100M /*|
> +                                       ETH_LINK_SPEED_100M_HD*/;
> +       }
>  }
>
>  static void
> @@ -2471,9 +2461,9 @@ ixgbe_dev_link_update(struct rte_eth_dev *dev, int
> wait_to_complete)
>         int link_up;
>         int diag;
>
> -       link.link_status = 0;
> +       link.link_status = ETH_LINK_DOWN;
>         link.link_speed = 0;
> -       link.link_duplex = 0;
> +       link.link_duplex = ETH_LINK_HALF_DUPLEX;
>         memset(&old, 0, sizeof(old));
>         rte_ixgbe_dev_atomic_read_link_status(dev, &old);
>
> @@ -2486,8 +2476,8 @@ ixgbe_dev_link_update(struct rte_eth_dev *dev, int
> wait_to_complete)
>                 diag = ixgbe_check_link(hw, &link_speed, &link_up, 1);
>
>         if (diag != 0) {
> -               link.link_speed = ETH_LINK_SPEED_100;
> -               link.link_duplex = ETH_LINK_HALF_DUPLEX;
> +               link.link_speed = ETH_SPEED_NUM_100M;
> +               link.link_duplex = ETH_LINK_FULL_DUPLEX;
>                 rte_ixgbe_dev_atomic_write_link_status(dev, &link);
>                 if (link.link_status == old.link_status)
>                         return -1;
> @@ -2500,26 +2490,26 @@ ixgbe_dev_link_update(struct rte_eth_dev *dev, int
> wait_to_complete)
>                         return -1;
>                 return 0;
>         }
> -       link.link_status = 1;
> +       link.link_status = ETH_LINK_UP;
>         link.link_duplex = ETH_LINK_FULL_DUPLEX;
>
>         switch (link_speed) {
>         default:
>         case IXGBE_LINK_SPEED_UNKNOWN:
> -               link.link_duplex = ETH_LINK_HALF_DUPLEX;
> -               link.link_speed = ETH_LINK_SPEED_100;
> +               link.link_duplex = ETH_LINK_FULL_DUPLEX;
> +               link.link_speed = ETH_SPEED_NUM_100M;
>                 break;
>
>         case IXGBE_LINK_SPEED_100_FULL:
> -               link.link_speed = ETH_LINK_SPEED_100;
> +               link.link_speed = ETH_SPEED_NUM_100M;
>                 break;
>
>         case IXGBE_LINK_SPEED_1GB_FULL:
> -               link.link_speed = ETH_LINK_SPEED_1000;
> +               link.link_speed = ETH_SPEED_NUM_1G;
>                 break;
>
>         case IXGBE_LINK_SPEED_10GB_FULL:
> -               link.link_speed = ETH_LINK_SPEED_10000;
> +               link.link_speed = ETH_SPEED_NUM_10G;
>                 break;
>         }
>         rte_ixgbe_dev_atomic_write_link_status(dev, &link);
> diff --git a/drivers/net/mlx4/mlx4.c b/drivers/net/mlx4/mlx4.c
> index b45e21a..96fe4b6 100644
> --- a/drivers/net/mlx4/mlx4.c
> +++ b/drivers/net/mlx4/mlx4.c
> @@ -4207,6 +4207,8 @@ mlx4_link_update_unlocked(struct rte_eth_dev *dev,
> int wait_to_complete)
>                 dev_link.link_speed = link_speed;
>         dev_link.link_duplex = ((edata.duplex == DUPLEX_HALF) ?
>                                 ETH_LINK_HALF_DUPLEX :
> ETH_LINK_FULL_DUPLEX);
> +       dev_link.link_autoneg = ~(dev->data->dev_conf.link_speeds &
> +                                               ETH_LINK_SPEED_NO_AUTONEG);
>         if (memcmp(&dev_link, &dev->data->dev_link, sizeof(dev_link))) {
>                 /* Link status changed. */
>                 dev->data->dev_link = dev_link;
> diff --git a/drivers/net/mpipe/mpipe_tilegx.c
> b/drivers/net/mpipe/mpipe_tilegx.c
> index 743feef..5875371 100644
> --- a/drivers/net/mpipe/mpipe_tilegx.c
> +++ b/drivers/net/mpipe/mpipe_tilegx.c
> @@ -388,14 +388,16 @@ mpipe_link_update(struct rte_eth_dev *dev, int
> wait_to_complete)
>
>                 speed = state & GXIO_MPIPE_LINK_SPEED_MASK;
>
> +               new.link_autoneg = ~(dev->data->dev_conf.link_speeds &
> +                                               ETH_LINK_SPEED_NO_AUTONEG);
>                 if (speed == GXIO_MPIPE_LINK_1G) {
>                         new.link_speed = ETH_LINK_SPEED_1000;
>                         new.link_duplex = ETH_LINK_FULL_DUPLEX;
> -                       new.link_status = 1;
> +                       new.link_status = ETH_LINK_UP;
>                 } else if (speed == GXIO_MPIPE_LINK_10G) {
>                         new.link_speed = ETH_LINK_SPEED_10000;
>                         new.link_duplex = ETH_LINK_FULL_DUPLEX;
> -                       new.link_status = 1;
> +                       new.link_status = ETH_LINK_UP;
>                 }
>
>                 rc = mpipe_link_compare(&old, &new);
> diff --git a/drivers/net/null/rte_eth_null.c
> b/drivers/net/null/rte_eth_null.c
> index e244595..7704fa6 100644
> --- a/drivers/net/null/rte_eth_null.c
> +++ b/drivers/net/null/rte_eth_null.c
> @@ -79,9 +79,10 @@ struct pmd_internals {
>  static struct ether_addr eth_addr = { .addr_bytes = {0} };
>  static const char *drivername = "Null PMD";
>  static struct rte_eth_link pmd_link = {
> -       .link_speed = 10000,
> +       .link_speed = ETH_SPEED_NUM_10G,
>         .link_duplex = ETH_LINK_FULL_DUPLEX,
> -       .link_status = 0
> +       .link_status = ETH_LINK_DOWN,
> +       .link_autoneg = ETH_LINK_SPEED_NEG,
>  };
>
>  static uint16_t
> diff --git a/drivers/net/pcap/rte_eth_pcap.c
> b/drivers/net/pcap/rte_eth_pcap.c
> index f2e4634..ea7a28f 100644
> --- a/drivers/net/pcap/rte_eth_pcap.c
> +++ b/drivers/net/pcap/rte_eth_pcap.c
> @@ -125,9 +125,10 @@ static int open_single_iface(const char *iface,
> pcap_t **pcap);
>  static struct ether_addr eth_addr = { .addr_bytes = { 0, 0, 0, 0x1, 0x2,
> 0x3 } };
>  static const char *drivername = "Pcap PMD";
>  static struct rte_eth_link pmd_link = {
> -               .link_speed = 10000,
> +               .link_speed = ETH_SPEED_NUM_10G,
>                 .link_duplex = ETH_LINK_FULL_DUPLEX,
> -               .link_status = 0
> +               .link_status = ETH_LINK_DOWN,
> +               .link_autoneg = ETH_LINK_SPEED_FIXED,
>  };
>
>  static int
> @@ -430,7 +431,7 @@ eth_dev_start(struct rte_eth_dev *dev)
>
>  status_up:
>
> -       dev->data->dev_link.link_status = 1;
> +       dev->data->dev_link.link_status = ETH_LINK_UP;
>         return 0;
>  }
>
> @@ -481,7 +482,7 @@ eth_dev_stop(struct rte_eth_dev *dev)
>         }
>
>  status_down:
> -       dev->data->dev_link.link_status = 0;
> +       dev->data->dev_link.link_status = ETH_LINK_DOWN;
>  }
>
>  static int
> diff --git a/drivers/net/ring/rte_eth_ring.c
> b/drivers/net/ring/rte_eth_ring.c
> index 0ba36d5..626c381 100644
> --- a/drivers/net/ring/rte_eth_ring.c
> +++ b/drivers/net/ring/rte_eth_ring.c
> @@ -71,9 +71,10 @@ struct pmd_internals {
>
>  static const char *drivername = "Rings PMD";
>  static struct rte_eth_link pmd_link = {
> -               .link_speed = 10000,
> +               .link_speed = ETH_SPEED_NUM_10G,
>                 .link_duplex = ETH_LINK_FULL_DUPLEX,
> -               .link_status = 0
> +               .link_status = ETH_LINK_DOWN,
> +               .link_autoneg = ETH_LINK_SPEED_NEG
>  };
>
>  static uint16_t
> diff --git a/drivers/net/virtio/virtio_ethdev.c
> b/drivers/net/virtio/virtio_ethdev.c
> index 465d3cd..ecbf9f2 100644
> --- a/drivers/net/virtio/virtio_ethdev.c
> +++ b/drivers/net/virtio/virtio_ethdev.c
> @@ -1517,7 +1517,7 @@ virtio_dev_link_update(struct rte_eth_dev *dev,
> __rte_unused int wait_to_complet
>         memset(&link, 0, sizeof(link));
>         virtio_dev_atomic_read_link_status(dev, &link);
>         old = link;
> -       link.link_duplex = FULL_DUPLEX;
> +       link.link_duplex = ETH_LINK_FULL_DUPLEX;
>         link.link_speed  = SPEED_10G;
>
>         if (vtpci_with_feature(hw, VIRTIO_NET_F_STATUS)) {
> diff --git a/drivers/net/virtio/virtio_ethdev.h
> b/drivers/net/virtio/virtio_ethdev.h
> index 9026d42..424d650 100644
> --- a/drivers/net/virtio/virtio_ethdev.h
> +++ b/drivers/net/virtio/virtio_ethdev.h
> @@ -42,8 +42,6 @@
>  #define SPEED_100      100
>  #define SPEED_1000     1000
>  #define SPEED_10G      10000
> -#define HALF_DUPLEX    1
> -#define FULL_DUPLEX    2
>
>  #ifndef PAGE_SIZE
>  #define PAGE_SIZE 4096
> diff --git a/drivers/net/vmxnet3/vmxnet3_ethdev.c
> b/drivers/net/vmxnet3/vmxnet3_ethdev.c
> index a70be5c..6860360 100644
> --- a/drivers/net/vmxnet3/vmxnet3_ethdev.c
> +++ b/drivers/net/vmxnet3/vmxnet3_ethdev.c
> @@ -697,9 +697,10 @@ vmxnet3_dev_link_update(struct rte_eth_dev *dev,
> __attribute__((unused)) int wai
>         ret = VMXNET3_READ_BAR1_REG(hw, VMXNET3_REG_CMD);
>
>         if (ret & 0x1) {
> -               link.link_status = 1;
> +               link.link_status = ETH_LINK_UP;
>                 link.link_duplex = ETH_LINK_FULL_DUPLEX;
> -               link.link_speed = ETH_LINK_SPEED_10000;
> +               link.link_speed = ETH_SPEED_NUM_10G;
> +               link.link_autoneg = ETH_LINK_SPEED_FIXED;
>         }
>
>         vmxnet3_dev_atomic_write_link_status(dev, &link);
> diff --git a/drivers/net/xenvirt/rte_eth_xenvirt.c
> b/drivers/net/xenvirt/rte_eth_xenvirt.c
> index 73e8bce..fb492ee 100644
> --- a/drivers/net/xenvirt/rte_eth_xenvirt.c
> +++ b/drivers/net/xenvirt/rte_eth_xenvirt.c
> @@ -70,9 +70,10 @@ static int virtio_idx = 0;
>  static const char *drivername = "xen dummy virtio PMD";
>
>  static struct rte_eth_link pmd_link = {
> -               .link_speed = 10000,
> +               .link_speed = ETH_SPEED_NUM_10G,
>                 .link_duplex = ETH_LINK_FULL_DUPLEX,
> -               .link_status = 0
> +               .link_status = ETH_LINK_DOWN,
> +               .link_autoneg = ETH_LINK_SPEED_FIXED
>  };
>
>  static inline struct rte_mbuf *
> diff --git a/examples/ip_pipeline/config_parse.c
> b/examples/ip_pipeline/config_parse.c
> index c9b78f9..92e6a18 100644
> --- a/examples/ip_pipeline/config_parse.c
> +++ b/examples/ip_pipeline/config_parse.c
> @@ -83,8 +83,7 @@ static const struct app_link_params link_params_default
> = {
>         .mac_addr = 0,
>
>         .conf = {
> -               .link_speed = 0,
> -               .link_duplex = 0,
> +               .link_speeds = 0,
>                 .rxmode = {
>                         .mq_mode = ETH_MQ_RX_NONE,
>
> diff --git a/lib/librte_ether/rte_ethdev.c b/lib/librte_ether/rte_ethdev.c
> index f593f6e..29b2960 100644
> --- a/lib/librte_ether/rte_ethdev.c
> +++ b/lib/librte_ether/rte_ethdev.c
> @@ -1072,6 +1072,55 @@ rte_eth_dev_check_mq_mode(uint8_t port_id, uint16_t
> nb_rx_q, uint16_t nb_tx_q,
>  }
>
>  int
> +rte_eth_speed_to_bm_flag(uint32_t speed, int duplex, uint32_t *flag)
> +{
> +       switch (speed) {
> +       case ETH_SPEED_NUM_10M:
> +               *flag = (duplex) ? ETH_LINK_SPEED_10M :
> +
>  ETH_LINK_SPEED_10M_HD;
> +               break;
> +       case ETH_SPEED_NUM_100M:
> +               *flag = (duplex) ? ETH_LINK_SPEED_100M :
> +
>  ETH_LINK_SPEED_100M_HD;
> +               break;
> +       case ETH_SPEED_NUM_1G:
> +               *flag = ETH_LINK_SPEED_1G;
> +               break;
> +       case ETH_SPEED_NUM_2_5G:
> +               *flag = ETH_LINK_SPEED_2_5G;
> +               break;
> +       case ETH_SPEED_NUM_5G:
> +               *flag = ETH_LINK_SPEED_5G;
> +               break;
> +       case ETH_SPEED_NUM_10G:
> +               *flag = ETH_LINK_SPEED_10G;
> +               break;
> +       case ETH_SPEED_NUM_20G:
> +               *flag = ETH_LINK_SPEED_20G;
> +               break;
> +       case ETH_SPEED_NUM_25G:
> +               *flag = ETH_LINK_SPEED_25G;
> +               break;
> +       case ETH_SPEED_NUM_40G:
> +               *flag = ETH_LINK_SPEED_40G;
> +               break;
> +       case ETH_SPEED_NUM_50G:
> +               *flag = ETH_LINK_SPEED_50G;
> +               break;
> +       case ETH_SPEED_NUM_56G:
> +               *flag = ETH_LINK_SPEED_56G;
> +               break;
> +       case ETH_SPEED_NUM_100G:
> +               *flag = ETH_LINK_SPEED_100G;
> +               break;
> +       default:
> +               return -EINVAL;
> +       }
> +
> +       return 0;
> +}
> +
> +int
>  rte_eth_dev_configure(uint8_t port_id, uint16_t nb_rx_q, uint16_t nb_tx_q,
>                       const struct rte_eth_conf *dev_conf)
>  {
> diff --git a/lib/librte_ether/rte_ethdev.h b/lib/librte_ether/rte_ethdev.h
> index 951a423..54ee6f9 100644
> --- a/lib/librte_ether/rte_ethdev.h
> +++ b/lib/librte_ether/rte_ethdev.h
> @@ -238,26 +238,59 @@ struct rte_eth_stats {
>  };
>
>  /**
> + * Device supported speeds bitmap flags
> + */
> +#define ETH_LINK_SPEED_AUTONEG         (0 << 0)  /*< Autonegociate (all
> speeds)  */
> +#define ETH_LINK_SPEED_NO_AUTONEG      (1 << 0)  /*< Disable autoneg
> (fixed speed)  */
> +#define ETH_LINK_SPEED_10M_HD          (1 << 1)  /*< 10 Mbps half-duplex
> */
> +#define ETH_LINK_SPEED_10M             (1 << 2)  /*< 10 Mbps full-duplex
> */
> +#define ETH_LINK_SPEED_100M_HD         (1 << 3)  /*< 100 Mbps half-duplex
> */
> +#define ETH_LINK_SPEED_100M            (1 << 4)  /*< 100 Mbps full-duplex
> */
> +#define ETH_LINK_SPEED_1G              (1 << 5)  /*< 1 Gbps */
> +#define ETH_LINK_SPEED_2_5G            (1 << 6)  /*< 2.5 Gbps */
> +#define ETH_LINK_SPEED_5G              (1 << 7)  /*< 5 Gbps */
> +#define ETH_LINK_SPEED_10G             (1 << 8)  /*< 10 Mbps */
> +#define ETH_LINK_SPEED_20G             (1 << 9)  /*< 20 Gbps */
> +#define ETH_LINK_SPEED_25G             (1 << 10)  /*< 25 Gbps */
> +#define ETH_LINK_SPEED_40G             (1 << 11)  /*< 40 Gbps */
> +#define ETH_LINK_SPEED_50G             (1 << 12)  /*< 50 Gbps */
> +#define ETH_LINK_SPEED_56G             (1 << 13)  /*< 56 Gbps */
> +#define ETH_LINK_SPEED_100G            (1 << 14)  /*< 100 Gbps */
> +
> +/**
> + * 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 Mbps */
> +#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 */
> +
> +/**
>   * A structure used to retrieve link-level information of an Ethernet
> port.
>   */
>  struct rte_eth_link {
> -       uint16_t link_speed;      /**< ETH_LINK_SPEED_[10, 100, 1000,
> 10000] */
> -       uint16_t link_duplex;     /**< ETH_LINK_[HALF_DUPLEX, FULL_DUPLEX]
> */
> -       uint8_t  link_status : 1; /**< 1 -> link up, 0 -> link down */
> -}__attribute__((aligned(8)));     /**< aligned for atomic64 read/write */
> -
> -#define ETH_LINK_SPEED_AUTONEG  0       /**< Auto-negotiate link speed. */
> -#define ETH_LINK_SPEED_10       10      /**< 10 megabits/second. */
> -#define ETH_LINK_SPEED_100      100     /**< 100 megabits/second. */
> -#define ETH_LINK_SPEED_1000     1000    /**< 1 gigabits/second. */
> -#define ETH_LINK_SPEED_10000    10000   /**< 10 gigabits/second. */
> -#define ETH_LINK_SPEED_10G      10000   /**< alias of 10 gigabits/second.
> */
> -#define ETH_LINK_SPEED_20G      20000   /**< 20 gigabits/second. */
> -#define ETH_LINK_SPEED_40G      40000   /**< 40 gigabits/second. */
> +       uint32_t link_speed;        /**< Link speed (ETH_SPEED_NUM_) */
> +       uint16_t link_duplex  : 1;  /**< 1 -> full duplex, 0 -> half
> duplex */
> +       uint16_t link_autoneg : 1;  /**< 1 -> link speed has been autoneg
> */
> +       uint16_t link_status  : 1;  /**< 1 -> link up, 0 -> link down */
> +} __attribute__((aligned(8)));      /**< aligned for atomic64 read/write
> */
>
> -#define ETH_LINK_AUTONEG_DUPLEX 0       /**< Auto-negotiate duplex. */
> -#define ETH_LINK_HALF_DUPLEX    1       /**< Half-duplex connection. */
> -#define ETH_LINK_FULL_DUPLEX    2       /**< Full-duplex connection. */
> +/* Utility constants */
> +#define ETH_LINK_HALF_DUPLEX    0      /**< Half-duplex connection. */
> +#define ETH_LINK_FULL_DUPLEX    1      /**< Full-duplex connection. */
> +#define ETH_LINK_SPEED_FIXED    0      /**< Link speed was not
> autonegociated. */
> +#define ETH_LINK_SPEED_NEG      1      /**< Link speed was
> autonegociated. */
> +#define ETH_LINK_DOWN          0       /**< Link is down. */
> +#define ETH_LINK_UP            1       /**< Link is up. */
>
>  /**
>   * A structure used to configure the ring threshold registers of an RX/TX
> @@ -747,10 +780,14 @@ struct rte_intr_conf {
>   * configuration settings may be needed.
>   */
>  struct rte_eth_conf {
> -       uint16_t link_speed;
> -       /**< ETH_LINK_SPEED_10[0|00|000], or 0 for autonegotation */
> -       uint16_t link_duplex;
> -       /**< ETH_LINK_[HALF_DUPLEX|FULL_DUPLEX], or 0 for autonegotation */
> +       uint32_t link_speeds; /**< bitmap of ETH_LINK_SPEED_XXX of speeds
> to be
> +                               used. ETH_LINK_SPEED_NO_AUTONEG disables
> link
> +                               autonegociation, and a unique speed shall
> be
> +                               set. Otherwise, the bitmap defines the set
> of
> +                               speeds to be advertised. If the special
> value
> +                               ETH_LINK_SPEED_AUTONEG (0) is used, all
> speeds
> +                               supported are advertised.
> +                               */
>         struct rte_eth_rxmode rxmode; /**< Port RX configuration. */
>         struct rte_eth_txmode txmode; /**< Port TX configuration. */
>         uint32_t lpbk_mode; /**< Loopback operation mode. By default the
> value
> @@ -812,26 +849,6 @@ struct rte_eth_conf {
>  #define DEV_TX_OFFLOAD_QINQ_INSERT 0x00000100
>
>  /**
> - * Device supported speeds
> - */
> -#define ETH_SPEED_CAP_NOT_PHY  (0)  /*< No phy media > */
> -#define ETH_SPEED_CAP_10M_HD   (1 << 0)  /*< 10 Mbps half-duplex> */
> -#define ETH_SPEED_CAP_10M_FD   (1 << 1)  /*< 10 Mbps full-duplex> */
> -#define ETH_SPEED_CAP_100M_HD  (1 << 2)  /*< 100 Mbps half-duplex> */
> -#define ETH_SPEED_CAP_100M_FD  (1 << 3)  /*< 100 Mbps full-duplex> */
> -#define ETH_SPEED_CAP_1G       (1 << 4)  /*< 1 Gbps > */
> -#define ETH_SPEED_CAP_2_5G     (1 << 5)  /*< 2.5 Gbps > */
> -#define ETH_SPEED_CAP_5G       (1 << 6)  /*< 5 Gbps > */
> -#define ETH_SPEED_CAP_10G      (1 << 7)  /*< 10 Mbps > */
> -#define ETH_SPEED_CAP_20G      (1 << 8)  /*< 20 Gbps > */
> -#define ETH_SPEED_CAP_25G      (1 << 9)  /*< 25 Gbps > */
> -#define ETH_SPEED_CAP_40G      (1 << 10)  /*< 40 Gbps > */
> -#define ETH_SPEED_CAP_50G      (1 << 11)  /*< 50 Gbps > */
> -#define ETH_SPEED_CAP_56G      (1 << 12)  /*< 56 Gbps > */
> -#define ETH_SPEED_CAP_100G     (1 << 13)  /*< 100 Gbps > */
> -
> -
> -/**
>   * Ethernet device information
>   */
>  struct rte_eth_dev_info {
> @@ -1667,6 +1684,22 @@ struct eth_driver {
>  extern void rte_eth_driver_register(struct eth_driver *eth_drv);
>
>  /**
> + * Convert a numerical speed in Mbps to a bitmap flag that can be used in
> + * the bitmap link_speeds of the struct rte_eth_conf
> + *
> + * @param
> + *   Numerical speed value in Mbps
> + * @param
> + *   Boolean is duplex (only for 10/100 speeds)
> + * @param
> + *   On success, the converted speed into a bitmap flag
> + * @return
> + *   0 on success, -EINVAL if the speed cannot be mapped
> + */
> +extern int rte_eth_speed_to_bm_flag(uint32_t speed, int duplex,
> +                                                       uint32_t *flag);
> +
> +/**
>   * Configure an Ethernet device.
>   * This function must be invoked first before any other function in the
>   * Ethernet API. This function can also be re-invoked when a device is in
> the
> --
> 2.1.4
>
>

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

* Re: [PATCH v6 1/5] ethdev: Added ETH_SPEED_CAP bitmap for ports
  2015-10-25 21:59   ` [PATCH v6 1/5] ethdev: Added ETH_SPEED_CAP bitmap for ports Marc Sune
@ 2015-11-01 22:11     ` Thomas Monjalon
  2015-11-18 23:08       ` Marc Sune
  0 siblings, 1 reply; 167+ messages in thread
From: Thomas Monjalon @ 2015-11-01 22:11 UTC (permalink / raw)
  To: dev

2015-10-25 22:59, Marc Sune:
> +#define ETH_SPEED_CAP_NOT_PHY	(0)  /*< No phy media > */
> +#define ETH_SPEED_CAP_10M_HD	(1 << 0)  /*< 10 Mbps half-duplex> */
> +#define ETH_SPEED_CAP_10M_FD	(1 << 1)  /*< 10 Mbps full-duplex> */
> +#define ETH_SPEED_CAP_100M_HD	(1 << 2)  /*< 100 Mbps half-duplex> */
> +#define ETH_SPEED_CAP_100M_FD	(1 << 3)  /*< 100 Mbps full-duplex> */
> +#define ETH_SPEED_CAP_1G	(1 << 4)  /*< 1 Gbps > */
> +#define ETH_SPEED_CAP_2_5G	(1 << 5)  /*< 2.5 Gbps > */
> +#define ETH_SPEED_CAP_5G	(1 << 6)  /*< 5 Gbps > */
> +#define ETH_SPEED_CAP_10G	(1 << 7)  /*< 10 Mbps > */
> +#define ETH_SPEED_CAP_20G	(1 << 8)  /*< 20 Gbps > */
> +#define ETH_SPEED_CAP_25G	(1 << 9)  /*< 25 Gbps > */
> +#define ETH_SPEED_CAP_40G	(1 << 10)  /*< 40 Gbps > */
> +#define ETH_SPEED_CAP_50G	(1 << 11)  /*< 50 Gbps > */
> +#define ETH_SPEED_CAP_56G	(1 << 12)  /*< 56 Gbps > */
> +#define ETH_SPEED_CAP_100G	(1 << 13)  /*< 100 Gbps > */

In the patch 3, you rename this flags. It would be easier to understand if
the right names were used in the first patch.

> @@ -837,6 +860,7 @@ struct rte_eth_dev_info {
>  	uint16_t vmdq_queue_base; /**< First queue ID for VMDQ pools. */
>  	uint16_t vmdq_queue_num;  /**< Queue number for VMDQ pools. */
>  	uint16_t vmdq_pool_base;  /**< First ID of VMDQ pools. */
> +	uint32_t speed_capa;  /**< Supported speeds bitmap (ETH_SPEED_CAP_). */

When renaming ETH_SPEED_CAP, this line is not changed later.

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

* Re: [PATCH v6 3/5] ethdev: redesign link speed config API
  2015-10-25 21:59   ` [PATCH v6 3/5] ethdev: redesign link speed config API Marc Sune
  2015-10-25 22:03     ` Marc Sune
@ 2015-11-01 22:16     ` Thomas Monjalon
  2015-11-18 22:59       ` Marc Sune
  1 sibling, 1 reply; 167+ messages in thread
From: Thomas Monjalon @ 2015-11-01 22:16 UTC (permalink / raw)
  To: Marc Sune; +Cc: dev

2015-10-25 22:59, Marc Sune:
> This patch redesigns the API to set the link speed/s configure
> for an ethernet port. Specifically:
> 
> - it allows to define a set of advertised speeds for
>   auto-negociation.
> - it allows to disable link auto-negociation (single fixed speed).
> - default: auto-negociate all supported speeds.
> 
> Other changes:
> 
> * Added utility MACROs ETH_SPEED_NUM_XXX with the numeric
>   values of all supported link speeds, in Mbps.
> * Converted link_speed to uint32_t to accomodate 100G speeds
>   (bug).
> * Added autoneg flag in struct rte_eth_link to indicate if
>   link speed was a result of auto-negociation or was fixed
>   by configuration.
> * Added utility function to convert numeric speeds to bitmap
>   fields.

Having it split in several commits may help to understand the changes.
And it must be explained in the release notes in the "API changes".

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

* Re: [PATCH v6 3/5] ethdev: redesign link speed config API
  2015-11-01 22:16     ` Thomas Monjalon
@ 2015-11-18 22:59       ` Marc Sune
  0 siblings, 0 replies; 167+ messages in thread
From: Marc Sune @ 2015-11-18 22:59 UTC (permalink / raw)
  To: Thomas Monjalon; +Cc: dev

Hi Thomas,

2015-11-01 23:16 GMT+01:00 Thomas Monjalon <thomas.monjalon@6wind.com>:

> 2015-10-25 22:59, Marc Sune:
> > This patch redesigns the API to set the link speed/s configure
> > for an ethernet port. Specifically:
> >
> > - it allows to define a set of advertised speeds for
> >   auto-negociation.
> > - it allows to disable link auto-negociation (single fixed speed).
> > - default: auto-negociate all supported speeds.
> >
> > Other changes:
> >
> > * Added utility MACROs ETH_SPEED_NUM_XXX with the numeric
> >   values of all supported link speeds, in Mbps.
> > * Converted link_speed to uint32_t to accomodate 100G speeds
> >   (bug).
> > * Added autoneg flag in struct rte_eth_link to indicate if
> >   link speed was a result of auto-negociation or was fixed
> >   by configuration.
> > * Added utility function to convert numeric speeds to bitmap
> >   fields.
>
> Having it split in several commits may help to understand the changes.
>

Apologies for the late response... crazy days.

At least first and last point in the enumeration do not make sense alone. I
can split the link_speed bug for 100G in another patch if you consider is
necessary for the series to be merged in.


> And it must be explained in the release notes in the "API changes".
>

Patch 4/5 in the series attempts to cover this:

http://dpdk.org/dev/patchwork/patch/7996/

Isn't it enough?

Marc

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

* Re: [PATCH v6 1/5] ethdev: Added ETH_SPEED_CAP bitmap for ports
  2015-11-01 22:11     ` Thomas Monjalon
@ 2015-11-18 23:08       ` Marc Sune
  0 siblings, 0 replies; 167+ messages in thread
From: Marc Sune @ 2015-11-18 23:08 UTC (permalink / raw)
  To: Thomas Monjalon; +Cc: dev

Hi Thomas,

2015-11-01 23:11 GMT+01:00 Thomas Monjalon <thomas.monjalon@6wind.com>:

> 2015-10-25 22:59, Marc Sune:
> > +#define ETH_SPEED_CAP_NOT_PHY        (0)  /*< No phy media > */
> > +#define ETH_SPEED_CAP_10M_HD (1 << 0)  /*< 10 Mbps half-duplex> */
> > +#define ETH_SPEED_CAP_10M_FD (1 << 1)  /*< 10 Mbps full-duplex> */
> > +#define ETH_SPEED_CAP_100M_HD        (1 << 2)  /*< 100 Mbps
> half-duplex> */
> > +#define ETH_SPEED_CAP_100M_FD        (1 << 3)  /*< 100 Mbps
> full-duplex> */
> > +#define ETH_SPEED_CAP_1G     (1 << 4)  /*< 1 Gbps > */
> > +#define ETH_SPEED_CAP_2_5G   (1 << 5)  /*< 2.5 Gbps > */
> > +#define ETH_SPEED_CAP_5G     (1 << 6)  /*< 5 Gbps > */
> > +#define ETH_SPEED_CAP_10G    (1 << 7)  /*< 10 Mbps > */
> > +#define ETH_SPEED_CAP_20G    (1 << 8)  /*< 20 Gbps > */
> > +#define ETH_SPEED_CAP_25G    (1 << 9)  /*< 25 Gbps > */
> > +#define ETH_SPEED_CAP_40G    (1 << 10)  /*< 40 Gbps > */
> > +#define ETH_SPEED_CAP_50G    (1 << 11)  /*< 50 Gbps > */
> > +#define ETH_SPEED_CAP_56G    (1 << 12)  /*< 56 Gbps > */
> > +#define ETH_SPEED_CAP_100G   (1 << 13)  /*< 100 Gbps > */
>
> In the patch 3, you rename this flags. It would be easier to understand if
> the right names were used in the first patch.
>
> > @@ -837,6 +860,7 @@ struct rte_eth_dev_info {
> >       uint16_t vmdq_queue_base; /**< First queue ID for VMDQ pools. */
> >       uint16_t vmdq_queue_num;  /**< Queue number for VMDQ pools. */
> >       uint16_t vmdq_pool_base;  /**< First ID of VMDQ pools. */
> > +     uint32_t speed_capa;  /**< Supported speeds bitmap
> (ETH_SPEED_CAP_). */
>
> When renaming ETH_SPEED_CAP, this line is not changed later.
>

This is made in purpose.

In patch 3/5 the bitmap speeds are renamed to ETH_LINK_SPEED_XXX and
numeric values are moved ETH_SPEED_NUM_XXX, to make clear the difference. I
cannot, in this commit, rename them directly to ETH_LINK_SPEED_XXX since
they would collide with the current numeric speeds.

Thanks
Marc

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

* Re: [PATCH v6 0/5] ethdev: add speed capabilities and refactor link API
  2015-10-25 21:59 ` [PATCH v6 0/5] ethdev: add speed capabilities and refactor link API Marc Sune
                     ` (4 preceding siblings ...)
  2015-10-25 22:00   ` [PATCH v6 5/5] ethdev: add rte_eth_speed_to_bm_flag() to ver. map Marc Sune
@ 2015-12-16 20:37   ` Marc Sune
  2015-12-16 20:44     ` Olga Shern
  2016-01-29  0:42   ` [PATCH v7 " Marc Sune
  6 siblings, 1 reply; 167+ messages in thread
From: Marc Sune @ 2015-12-16 20:37 UTC (permalink / raw)
  To: dev

2015-10-25 22:59 GMT+01:00 Marc Sune <marcdevel@gmail.com>:

> The current rte_eth_dev_info abstraction does not provide any mechanism to
> get the supported speed(s) of an ethdev.
>
> For some drivers (e.g. ixgbe), an educated guess could be done based on the
> driver's name (driver_name in rte_eth_dev_info), see:
>
> http://dpdk.org/ml/archives/dev/2013-August/000412.html
>
> However, i) doing string comparisons is annoying, and can silently
> break existing applications if PMDs change their names ii) it does not
> provide all the supported capabilities of the ethdev iii) for some drivers
> it
> is impossible determine correctly the (max) speed by the application
> (e.g. in i40, distinguish between XL710 and X710).
>
> In addition, the link APIs do not allow to define a set of advertised link
> speeds for autonegociation.
>
> This series of patches adds the following capabilities:
>
> * speed_capa bitmap in rte_eth_dev_info, which is filled by the PMDs
>   according to the physical device capabilities.
> * refactors link API in ethdev to allow the definition of the advertised
>   link speeds, fix speed (no auto-negociation) or advertise all supported
>   speeds (default).
>
> WARNING: this patch series, specifically 3/4, is NOT tested for most of the
> PMDs, due to the lack of hardware. Only generic EM is tested (VM).
> Minor bugs expected.
>

I will respin this patch to current HEAD targeting 2.3, but note that
testing of PMDs other than i40 and e1000 (82540Em) is necessary for this
patch to be merged.

I do not have all the HW to test it, so I would like to ask for some help
here. Some (more) peer reviews would also help.

Regards
marc


>
> * * * * *
>
> v2: rebase, converted speed_capa into 32 bits bitmap, fixed alignment
> (checkpatch).
>
> v3: rebase to v2.1. unified ETH_LINK_SPEED and ETH_SPEED_CAP into
> ETH_SPEED.
>     Converted field speed in struct rte_eth_conf to speed, to allow a
> bitmap
>     for defining the announced speeds, as suggested M. Brorup. Fixed
> spelling
>     issues.
>
> v4: fixed errata in the documentation of field speeds of rte_eth_conf, and
>     commit 1/2 message. rebased to v2.1.0. v3 was incorrectly based on
>     ~2.1.0-rc1.
>
> v5: revert to v2 speed capabilities patch. Fixed MLX4 speed capabilities
>     (thanks N. Laranjeiro). Refactored link speed API to allow setting
>     advertised speeds (3/4). Added NO_AUTONEG option to explicitely disable
>     auto-negociation. Updated 2.2 rel. notes (4/4). Rebased to current
> HEAD.
>
> v6: Move link_duplex to be part of bitfield. Fixed i40 autoneg flag link
>     update code. Added rte_eth_speed_to_bm_flag() to .map file. Fixed other
>     spelling issues. Rebased to current HEAD.
>
> Marc Sune (5):
>   ethdev: Added ETH_SPEED_CAP bitmap for ports
>   ethdev: Fill speed capability bitmaps in the PMDs
>   ethdev: redesign link speed config API
>   doc: update with link changes
>   ethdev: add rte_eth_speed_to_bm_flag() to ver. map
>
>  app/test-pmd/cmdline.c                     | 124
> +++++++++++++++--------------
>  app/test/virtual_pmd.c                     |   4 +-
>  doc/guides/rel_notes/release_2_2.rst       |  23 ++++++
>  drivers/net/af_packet/rte_eth_af_packet.c  |   5 +-
>  drivers/net/bonding/rte_eth_bond_8023ad.c  |  14 ++--
>  drivers/net/cxgbe/base/t4_hw.c             |   8 +-
>  drivers/net/e1000/base/e1000_80003es2lan.c |   6 +-
>  drivers/net/e1000/base/e1000_82541.c       |   8 +-
>  drivers/net/e1000/base/e1000_82543.c       |   4 +-
>  drivers/net/e1000/base/e1000_82575.c       |  11 +--
>  drivers/net/e1000/base/e1000_api.c         |   2 +-
>  drivers/net/e1000/base/e1000_api.h         |   2 +-
>  drivers/net/e1000/base/e1000_defines.h     |   4 +-
>  drivers/net/e1000/base/e1000_hw.h          |   2 +-
>  drivers/net/e1000/base/e1000_ich8lan.c     |   4 +-
>  drivers/net/e1000/base/e1000_mac.c         |   9 ++-
>  drivers/net/e1000/base/e1000_mac.h         |   6 +-
>  drivers/net/e1000/base/e1000_vf.c          |   4 +-
>  drivers/net/e1000/base/e1000_vf.h          |   2 +-
>  drivers/net/e1000/em_ethdev.c              | 109 ++++++++++++-------------
>  drivers/net/e1000/igb_ethdev.c             | 104 +++++++++++++-----------
>  drivers/net/fm10k/fm10k_ethdev.c           |   5 +-
>  drivers/net/i40e/i40e_ethdev.c             |  78 ++++++++++--------
>  drivers/net/i40e/i40e_ethdev_vf.c          |  11 +--
>  drivers/net/ixgbe/ixgbe_ethdev.c           |  74 ++++++++---------
>  drivers/net/mlx4/mlx4.c                    |   6 ++
>  drivers/net/mpipe/mpipe_tilegx.c           |   6 +-
>  drivers/net/null/rte_eth_null.c            |   5 +-
>  drivers/net/pcap/rte_eth_pcap.c            |   9 ++-
>  drivers/net/ring/rte_eth_ring.c            |   5 +-
>  drivers/net/virtio/virtio_ethdev.c         |   2 +-
>  drivers/net/virtio/virtio_ethdev.h         |   2 -
>  drivers/net/vmxnet3/vmxnet3_ethdev.c       |   5 +-
>  drivers/net/xenvirt/rte_eth_xenvirt.c      |   5 +-
>  examples/ip_pipeline/config_parse.c        |   3 +-
>  lib/librte_ether/rte_ethdev.c              |  49 ++++++++++++
>  lib/librte_ether/rte_ethdev.h              |  97 +++++++++++++++++-----
>  lib/librte_ether/rte_ether_version.map     |   6 ++
>  38 files changed, 501 insertions(+), 322 deletions(-)
>
> --
> 2.1.4
>
>

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

* Re: [PATCH v6 0/5] ethdev: add speed capabilities and refactor link API
  2015-12-16 20:37   ` [PATCH v6 0/5] ethdev: add speed capabilities and refactor link API Marc Sune
@ 2015-12-16 20:44     ` Olga Shern
  0 siblings, 0 replies; 167+ messages in thread
From: Olga Shern @ 2015-12-16 20:44 UTC (permalink / raw)
  To: Marc Sune, dev

We will test on Mellanox NICs

-----Original Message-----
From: dev [mailto:dev-bounces@dpdk.org] On Behalf Of Marc Sune
Sent: Wednesday, December 16, 2015 10:38 PM
To: dev@dpdk.org
Subject: Re: [dpdk-dev] [PATCH v6 0/5] ethdev: add speed capabilities and refactor link API

2015-10-25 22:59 GMT+01:00 Marc Sune <marcdevel@gmail.com>:

> The current rte_eth_dev_info abstraction does not provide any 
> mechanism to get the supported speed(s) of an ethdev.
>
> For some drivers (e.g. ixgbe), an educated guess could be done based 
> on the driver's name (driver_name in rte_eth_dev_info), see:
>
> http://dpdk.org/ml/archives/dev/2013-August/000412.html
>
> However, i) doing string comparisons is annoying, and can silently 
> break existing applications if PMDs change their names ii) it does not 
> provide all the supported capabilities of the ethdev iii) for some 
> drivers it is impossible determine correctly the (max) speed by the 
> application (e.g. in i40, distinguish between XL710 and X710).
>
> In addition, the link APIs do not allow to define a set of advertised 
> link speeds for autonegociation.
>
> This series of patches adds the following capabilities:
>
> * speed_capa bitmap in rte_eth_dev_info, which is filled by the PMDs
>   according to the physical device capabilities.
> * refactors link API in ethdev to allow the definition of the advertised
>   link speeds, fix speed (no auto-negociation) or advertise all supported
>   speeds (default).
>
> WARNING: this patch series, specifically 3/4, is NOT tested for most 
> of the PMDs, due to the lack of hardware. Only generic EM is tested (VM).
> Minor bugs expected.
>

I will respin this patch to current HEAD targeting 2.3, but note that testing of PMDs other than i40 and e1000 (82540Em) is necessary for this patch to be merged.

I do not have all the HW to test it, so I would like to ask for some help here. Some (more) peer reviews would also help.

Regards
marc


>
> * * * * *
>
> v2: rebase, converted speed_capa into 32 bits bitmap, fixed alignment 
> (checkpatch).
>
> v3: rebase to v2.1. unified ETH_LINK_SPEED and ETH_SPEED_CAP into 
> ETH_SPEED.
>     Converted field speed in struct rte_eth_conf to speed, to allow a 
> bitmap
>     for defining the announced speeds, as suggested M. Brorup. Fixed 
> spelling
>     issues.
>
> v4: fixed errata in the documentation of field speeds of rte_eth_conf, and
>     commit 1/2 message. rebased to v2.1.0. v3 was incorrectly based on
>     ~2.1.0-rc1.
>
> v5: revert to v2 speed capabilities patch. Fixed MLX4 speed capabilities
>     (thanks N. Laranjeiro). Refactored link speed API to allow setting
>     advertised speeds (3/4). Added NO_AUTONEG option to explicitely disable
>     auto-negociation. Updated 2.2 rel. notes (4/4). Rebased to current 
> HEAD.
>
> v6: Move link_duplex to be part of bitfield. Fixed i40 autoneg flag link
>     update code. Added rte_eth_speed_to_bm_flag() to .map file. Fixed other
>     spelling issues. Rebased to current HEAD.
>
> Marc Sune (5):
>   ethdev: Added ETH_SPEED_CAP bitmap for ports
>   ethdev: Fill speed capability bitmaps in the PMDs
>   ethdev: redesign link speed config API
>   doc: update with link changes
>   ethdev: add rte_eth_speed_to_bm_flag() to ver. map
>
>  app/test-pmd/cmdline.c                     | 124
> +++++++++++++++--------------
>  app/test/virtual_pmd.c                     |   4 +-
>  doc/guides/rel_notes/release_2_2.rst       |  23 ++++++
>  drivers/net/af_packet/rte_eth_af_packet.c  |   5 +-
>  drivers/net/bonding/rte_eth_bond_8023ad.c  |  14 ++--
>  drivers/net/cxgbe/base/t4_hw.c             |   8 +-
>  drivers/net/e1000/base/e1000_80003es2lan.c |   6 +-
>  drivers/net/e1000/base/e1000_82541.c       |   8 +-
>  drivers/net/e1000/base/e1000_82543.c       |   4 +-
>  drivers/net/e1000/base/e1000_82575.c       |  11 +--
>  drivers/net/e1000/base/e1000_api.c         |   2 +-
>  drivers/net/e1000/base/e1000_api.h         |   2 +-
>  drivers/net/e1000/base/e1000_defines.h     |   4 +-
>  drivers/net/e1000/base/e1000_hw.h          |   2 +-
>  drivers/net/e1000/base/e1000_ich8lan.c     |   4 +-
>  drivers/net/e1000/base/e1000_mac.c         |   9 ++-
>  drivers/net/e1000/base/e1000_mac.h         |   6 +-
>  drivers/net/e1000/base/e1000_vf.c          |   4 +-
>  drivers/net/e1000/base/e1000_vf.h          |   2 +-
>  drivers/net/e1000/em_ethdev.c              | 109 ++++++++++++-------------
>  drivers/net/e1000/igb_ethdev.c             | 104 +++++++++++++-----------
>  drivers/net/fm10k/fm10k_ethdev.c           |   5 +-
>  drivers/net/i40e/i40e_ethdev.c             |  78 ++++++++++--------
>  drivers/net/i40e/i40e_ethdev_vf.c          |  11 +--
>  drivers/net/ixgbe/ixgbe_ethdev.c           |  74 ++++++++---------
>  drivers/net/mlx4/mlx4.c                    |   6 ++
>  drivers/net/mpipe/mpipe_tilegx.c           |   6 +-
>  drivers/net/null/rte_eth_null.c            |   5 +-
>  drivers/net/pcap/rte_eth_pcap.c            |   9 ++-
>  drivers/net/ring/rte_eth_ring.c            |   5 +-
>  drivers/net/virtio/virtio_ethdev.c         |   2 +-
>  drivers/net/virtio/virtio_ethdev.h         |   2 -
>  drivers/net/vmxnet3/vmxnet3_ethdev.c       |   5 +-
>  drivers/net/xenvirt/rte_eth_xenvirt.c      |   5 +-
>  examples/ip_pipeline/config_parse.c        |   3 +-
>  lib/librte_ether/rte_ethdev.c              |  49 ++++++++++++
>  lib/librte_ether/rte_ethdev.h              |  97 +++++++++++++++++-----
>  lib/librte_ether/rte_ether_version.map     |   6 ++
>  38 files changed, 501 insertions(+), 322 deletions(-)
>
> --
> 2.1.4
>
>

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

* [PATCH v7 0/5] ethdev: add speed capabilities and refactor link API
  2015-10-25 21:59 ` [PATCH v6 0/5] ethdev: add speed capabilities and refactor link API Marc Sune
                     ` (5 preceding siblings ...)
  2015-12-16 20:37   ` [PATCH v6 0/5] ethdev: add speed capabilities and refactor link API Marc Sune
@ 2016-01-29  0:42   ` Marc Sune
  2016-01-29  0:42     ` [PATCH v7 1/5] ethdev: Added ETH_SPEED_CAP bitmap for ports Marc Sune
                       ` (5 more replies)
  6 siblings, 6 replies; 167+ messages in thread
From: Marc Sune @ 2016-01-29  0:42 UTC (permalink / raw)
  To: dev, Wenzhuo Lu, Helin Zhang, Harish Patil, Jing Chen

The current rte_eth_dev_info abstraction does not provide any mechanism to
get the supported speed(s) of an ethdev.

For some drivers (e.g. ixgbe), an educated guess could be done based on the
driver's name (driver_name in rte_eth_dev_info), see:

http://dpdk.org/ml/archives/dev/2013-August/000412.html

However, i) doing string comparisons is annoying, and can silently
break existing applications if PMDs change their names ii) it does not
provide all the supported capabilities of the ethdev iii) for some drivers it
is impossible determine correctly the (max) speed by the application
(e.g. in i40, distinguish between XL710 and X710).

In addition, the link APIs do not allow to define a set of advertised link
speeds for autonegociation.

This series of patches adds the following capabilities:

* speed_capa bitmap in rte_eth_dev_info, which is filled by the PMDs
  according to the physical device capabilities.
* refactors link API in ethdev to allow the definition of the advertised
  link speeds, fix speed (no auto-negociation) or advertise all supported
  speeds (default).

WARNING: this patch series, specifically 3/4, is NOT tested for most of the
PMDs, due to the lack of hardware. Only generic EM is tested (VM). Reviewing
and testing required by PMD maintainers.

* * * * *

v2: rebase, converted speed_capa into 32 bits bitmap, fixed alignment
(checkpatch).

v3: rebase to v2.1. unified ETH_LINK_SPEED and ETH_SPEED_CAP into ETH_SPEED.
    Converted field speed in struct rte_eth_conf to speed, to allow a bitmap
    for defining the announced speeds, as suggested M. Brorup. Fixed spelling
    issues.

v4: fixed errata in the documentation of field speeds of rte_eth_conf, and
    commit 1/2 message. rebased to v2.1.0. v3 was incorrectly based on
    ~2.1.0-rc1.

v5: revert to v2 speed capabilities patch. Fixed MLX4 speed capabilities
    (thanks N. Laranjeiro). Refactored link speed API to allow setting
    advertised speeds (3/4). Added NO_AUTONEG option to explicitely disable
    auto-negociation. Updated 2.2 rel. notes (4/4). Rebased to current HEAD.

v6: Move link_duplex to be part of bitfield. Fixed i40 autoneg flag link
    update code. Added rte_eth_speed_to_bm_flag() to .map file. Fixed other
    spelling issues. Rebased to current HEAD.

v7: Rebased to current HEAD. Moved documentation to v2.3. Still needs testing
    from PMD maintainers.

Marc Sune (5):
  ethdev: Added ETH_SPEED_CAP bitmap for ports
  ethdev: Fill speed capability bitmaps in the PMDs
  ethdev: redesign link speed config API
  doc: update with link changes
  ethdev: add rte_eth_speed_to_bm_flag() to ver. map

 app/test-pmd/cmdline.c                     | 124 +++++++++++++++--------------
 app/test/virtual_pmd.c                     |   4 +-
 doc/guides/rel_notes/release_2_2.rst       |  23 ++++++
 drivers/net/af_packet/rte_eth_af_packet.c  |   5 +-
 drivers/net/bonding/rte_eth_bond_8023ad.c  |  14 ++--
 drivers/net/cxgbe/base/t4_hw.c             |   8 +-
 drivers/net/e1000/base/e1000_80003es2lan.c |   6 +-
 drivers/net/e1000/base/e1000_82541.c       |   8 +-
 drivers/net/e1000/base/e1000_82543.c       |   4 +-
 drivers/net/e1000/base/e1000_82575.c       |  11 +--
 drivers/net/e1000/base/e1000_api.c         |   2 +-
 drivers/net/e1000/base/e1000_api.h         |   2 +-
 drivers/net/e1000/base/e1000_defines.h     |   4 +-
 drivers/net/e1000/base/e1000_hw.h          |   2 +-
 drivers/net/e1000/base/e1000_ich8lan.c     |   4 +-
 drivers/net/e1000/base/e1000_mac.c         |   9 ++-
 drivers/net/e1000/base/e1000_mac.h         |   6 +-
 drivers/net/e1000/base/e1000_vf.c          |   4 +-
 drivers/net/e1000/base/e1000_vf.h          |   2 +-
 drivers/net/e1000/em_ethdev.c              | 109 ++++++++++++-------------
 drivers/net/e1000/igb_ethdev.c             | 104 +++++++++++++-----------
 drivers/net/fm10k/fm10k_ethdev.c           |   5 +-
 drivers/net/i40e/i40e_ethdev.c             |  78 ++++++++++--------
 drivers/net/i40e/i40e_ethdev_vf.c          |  11 +--
 drivers/net/ixgbe/ixgbe_ethdev.c           |  74 ++++++++---------
 drivers/net/mlx4/mlx4.c                    |   6 ++
 drivers/net/mpipe/mpipe_tilegx.c           |   6 +-
 drivers/net/null/rte_eth_null.c            |   5 +-
 drivers/net/pcap/rte_eth_pcap.c            |   9 ++-
 drivers/net/ring/rte_eth_ring.c            |   5 +-
 drivers/net/virtio/virtio_ethdev.c         |   2 +-
 drivers/net/virtio/virtio_ethdev.h         |   2 -
 drivers/net/vmxnet3/vmxnet3_ethdev.c       |   5 +-
 drivers/net/xenvirt/rte_eth_xenvirt.c      |   5 +-
 examples/ip_pipeline/config_parse.c        |   3 +-
 lib/librte_ether/rte_ethdev.c              |  49 ++++++++++++
 lib/librte_ether/rte_ethdev.h              |  97 +++++++++++++++++-----
 lib/librte_ether/rte_ether_version.map     |   6 ++
 38 files changed, 501 insertions(+), 322 deletions(-)

-- 
2.1.4

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

* [PATCH v7 1/5] ethdev: Added ETH_SPEED_CAP bitmap for ports
  2016-01-29  0:42   ` [PATCH v7 " Marc Sune
@ 2016-01-29  0:42     ` Marc Sune
  2016-01-29  0:42     ` [PATCH v7 2/5] ethdev: Fill speed capability bitmaps in the PMDs Marc Sune
                       ` (4 subsequent siblings)
  5 siblings, 0 replies; 167+ messages in thread
From: Marc Sune @ 2016-01-29  0:42 UTC (permalink / raw)
  To: dev, Wenzhuo Lu, Helin Zhang, Harish Patil, Jing Chen

Added constants and bitmap to struct rte_eth_dev_info to be used by PMDs.

Signed-off-by: Marc Sune <marcdevel@gmail.com>
---
 lib/librte_ether/rte_ethdev.h | 24 ++++++++++++++++++++++++
 1 file changed, 24 insertions(+)

diff --git a/lib/librte_ether/rte_ethdev.h b/lib/librte_ether/rte_ethdev.h
index 8710dd7..dbc1599 100644
--- a/lib/librte_ether/rte_ethdev.h
+++ b/lib/librte_ether/rte_ethdev.h
@@ -824,6 +824,29 @@ struct rte_eth_conf {
 #define DEV_TX_OFFLOAD_OUTER_IPV4_CKSUM 0x00000080 /**< Used for tunneling packet. */
 #define DEV_TX_OFFLOAD_QINQ_INSERT 0x00000100
 
+/**
+ * Device supported speeds
+ */
+#define ETH_SPEED_CAP_NOT_PHY	(0)  /*< No phy media > */
+#define ETH_SPEED_CAP_10M_HD	(1 << 0)  /*< 10 Mbps half-duplex> */
+#define ETH_SPEED_CAP_10M_FD	(1 << 1)  /*< 10 Mbps full-duplex> */
+#define ETH_SPEED_CAP_100M_HD	(1 << 2)  /*< 100 Mbps half-duplex> */
+#define ETH_SPEED_CAP_100M_FD	(1 << 3)  /*< 100 Mbps full-duplex> */
+#define ETH_SPEED_CAP_1G	(1 << 4)  /*< 1 Gbps > */
+#define ETH_SPEED_CAP_2_5G	(1 << 5)  /*< 2.5 Gbps > */
+#define ETH_SPEED_CAP_5G	(1 << 6)  /*< 5 Gbps > */
+#define ETH_SPEED_CAP_10G	(1 << 7)  /*< 10 Mbps > */
+#define ETH_SPEED_CAP_20G	(1 << 8)  /*< 20 Gbps > */
+#define ETH_SPEED_CAP_25G	(1 << 9)  /*< 25 Gbps > */
+#define ETH_SPEED_CAP_40G	(1 << 10)  /*< 40 Gbps > */
+#define ETH_SPEED_CAP_50G	(1 << 11)  /*< 50 Gbps > */
+#define ETH_SPEED_CAP_56G	(1 << 12)  /*< 56 Gbps > */
+#define ETH_SPEED_CAP_100G	(1 << 13)  /*< 100 Gbps > */
+
+
+/**
+ * Ethernet device information
+ */
 struct rte_eth_dev_info {
 	struct rte_pci_device *pci_dev; /**< Device PCI information. */
 	const char *driver_name; /**< Device Driver name. */
@@ -852,6 +875,7 @@ struct rte_eth_dev_info {
 	uint16_t vmdq_pool_base;  /**< First ID of VMDQ pools. */
 	struct rte_eth_desc_lim rx_desc_lim;  /**< RX descriptors limits */
 	struct rte_eth_desc_lim tx_desc_lim;  /**< TX descriptors limits */
+	uint32_t speed_capa;  /**< Supported speeds bitmap (ETH_SPEED_CAP_). */
 };
 
 /**
-- 
2.1.4

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

* [PATCH v7 2/5] ethdev: Fill speed capability bitmaps in the PMDs
  2016-01-29  0:42   ` [PATCH v7 " Marc Sune
  2016-01-29  0:42     ` [PATCH v7 1/5] ethdev: Added ETH_SPEED_CAP bitmap for ports Marc Sune
@ 2016-01-29  0:42     ` Marc Sune
  2016-01-29  0:42     ` [PATCH v7 3/5] ethdev: redesign link speed config API Marc Sune
                       ` (3 subsequent siblings)
  5 siblings, 0 replies; 167+ messages in thread
From: Marc Sune @ 2016-01-29  0:42 UTC (permalink / raw)
  To: dev, Wenzhuo Lu, Helin Zhang, Harish Patil, Jing Chen

Added speed capabilities to all pmds supporting physical NICs:

* e1000
* ixgbe
* i40
* mlx4
* fm10k

Signed-off-by: Marc Sune <marcdevel@gmail.com>
---
 drivers/net/e1000/em_ethdev.c    |  6 ++++++
 drivers/net/e1000/igb_ethdev.c   |  6 ++++++
 drivers/net/fm10k/fm10k_ethdev.c |  4 ++++
 drivers/net/i40e/i40e_ethdev.c   |  9 +++++++++
 drivers/net/ixgbe/ixgbe_ethdev.c | 10 ++++++++++
 drivers/net/mlx4/mlx4.c          |  4 ++++
 6 files changed, 39 insertions(+)

diff --git a/drivers/net/e1000/em_ethdev.c b/drivers/net/e1000/em_ethdev.c
index 66e8993..fd48bbf 100644
--- a/drivers/net/e1000/em_ethdev.c
+++ b/drivers/net/e1000/em_ethdev.c
@@ -1023,6 +1023,12 @@ eth_em_infos_get(struct rte_eth_dev *dev, struct rte_eth_dev_info *dev_info)
 		.nb_min = E1000_MIN_RING_DESC,
 		.nb_align = EM_TXD_ALIGN,
 	};
+
+	dev_info->speed_capa = ETH_SPEED_CAP_10M_HD |
+					ETH_SPEED_CAP_10M_FD |
+					ETH_SPEED_CAP_100M_HD |
+					ETH_SPEED_CAP_100M_FD |
+					ETH_SPEED_CAP_1G;
 }
 
 /* return 0 means link status changed, -1 means not changed */
diff --git a/drivers/net/e1000/igb_ethdev.c b/drivers/net/e1000/igb_ethdev.c
index d1bbcda..9c8dffa 100644
--- a/drivers/net/e1000/igb_ethdev.c
+++ b/drivers/net/e1000/igb_ethdev.c
@@ -1908,6 +1908,12 @@ eth_igb_infos_get(struct rte_eth_dev *dev, struct rte_eth_dev_info *dev_info)
 
 	dev_info->rx_desc_lim = rx_desc_lim;
 	dev_info->tx_desc_lim = tx_desc_lim;
+
+	dev_info->speed_capa = ETH_SPEED_CAP_10M_HD |
+					ETH_SPEED_CAP_10M_FD |
+					ETH_SPEED_CAP_100M_HD |
+					ETH_SPEED_CAP_100M_FD |
+					ETH_SPEED_CAP_1G;
 }
 
 static void
diff --git a/drivers/net/fm10k/fm10k_ethdev.c b/drivers/net/fm10k/fm10k_ethdev.c
index e4aed94..aeb2962 100644
--- a/drivers/net/fm10k/fm10k_ethdev.c
+++ b/drivers/net/fm10k/fm10k_ethdev.c
@@ -1333,6 +1333,10 @@ fm10k_dev_infos_get(struct rte_eth_dev *dev,
 		.nb_min = FM10K_MIN_TX_DESC,
 		.nb_align = FM10K_MULT_TX_DESC,
 	};
+
+	dev_info->speed_capa = ETH_SPEED_CAP_1G | ETH_SPEED_CAP_2_5G |
+					ETH_SPEED_CAP_10G | ETH_SPEED_CAP_25G |
+					ETH_SPEED_CAP_40G | ETH_SPEED_CAP_100G;
 }
 
 static int
diff --git a/drivers/net/i40e/i40e_ethdev.c b/drivers/net/i40e/i40e_ethdev.c
index bf6220d..d242973 100644
--- a/drivers/net/i40e/i40e_ethdev.c
+++ b/drivers/net/i40e/i40e_ethdev.c
@@ -2233,6 +2233,7 @@ static void
 i40e_dev_info_get(struct rte_eth_dev *dev, struct rte_eth_dev_info *dev_info)
 {
 	struct i40e_pf *pf = I40E_DEV_PRIVATE_TO_PF(dev->data->dev_private);
+	struct i40e_hw *hw = I40E_DEV_PRIVATE_TO_HW(dev->data->dev_private);
 	struct i40e_vsi *vsi = pf->main_vsi;
 
 	dev_info->max_rx_queues = vsi->nb_qps;
@@ -2304,6 +2305,14 @@ i40e_dev_info_get(struct rte_eth_dev *dev, struct rte_eth_dev_info *dev_info)
 		dev_info->max_rx_queues += dev_info->vmdq_queue_num;
 		dev_info->max_tx_queues += dev_info->vmdq_queue_num;
 	}
+
+	if (i40e_is_40G_device(hw->device_id))
+		/* For XL710 */
+		dev_info->speed_capa = ETH_SPEED_CAP_1G | ETH_SPEED_CAP_10G;
+	else
+		/* For X710 */
+		dev_info->speed_capa = ETH_SPEED_CAP_10G | ETH_SPEED_CAP_40G;
+
 }
 
 static int
diff --git a/drivers/net/ixgbe/ixgbe_ethdev.c b/drivers/net/ixgbe/ixgbe_ethdev.c
index 4c4c6df..4e3ab3d 100644
--- a/drivers/net/ixgbe/ixgbe_ethdev.c
+++ b/drivers/net/ixgbe/ixgbe_ethdev.c
@@ -2827,6 +2827,16 @@ ixgbe_dev_info_get(struct rte_eth_dev *dev, struct rte_eth_dev_info *dev_info)
 	dev_info->hash_key_size = IXGBE_HKEY_MAX_INDEX * sizeof(uint32_t);
 	dev_info->reta_size = ixgbe_reta_size_get(hw->mac.type);
 	dev_info->flow_type_rss_offloads = IXGBE_RSS_OFFLOAD_ALL;
+
+	dev_info->speed_capa = ETH_SPEED_CAP_1G | ETH_SPEED_CAP_10G;
+
+	if (hw->mac.type == ixgbe_mac_X540 ||
+	    hw->mac.type == ixgbe_mac_X540_vf ||
+	    hw->mac.type == ixgbe_mac_X550 ||
+	    hw->mac.type == ixgbe_mac_X550_vf)
+
+		dev_info->speed_capa |= ETH_SPEED_CAP_100M_FD /*|
+					ETH_SPEED_CAP_100M_HD*/;
 }
 
 static void
diff --git a/drivers/net/mlx4/mlx4.c b/drivers/net/mlx4/mlx4.c
index 207bfe2..1f3ed59 100644
--- a/drivers/net/mlx4/mlx4.c
+++ b/drivers/net/mlx4/mlx4.c
@@ -4265,6 +4265,10 @@ mlx4_dev_infos_get(struct rte_eth_dev *dev, struct rte_eth_dev_info *info)
 		 0);
 	if (priv_get_ifname(priv, &ifname) == 0)
 		info->if_index = if_nametoindex(ifname);
+
+	info->speed_capa = ETH_SPEED_CAP_10G |ETH_SPEED_CAP_40G |
+					ETH_SPEED_CAP_56G;
+
 	priv_unlock(priv);
 }
 
-- 
2.1.4

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

* [PATCH v7 3/5] ethdev: redesign link speed config API
  2016-01-29  0:42   ` [PATCH v7 " Marc Sune
  2016-01-29  0:42     ` [PATCH v7 1/5] ethdev: Added ETH_SPEED_CAP bitmap for ports Marc Sune
  2016-01-29  0:42     ` [PATCH v7 2/5] ethdev: Fill speed capability bitmaps in the PMDs Marc Sune
@ 2016-01-29  0:42     ` Marc Sune
  2016-01-29  9:24       ` Ananyev, Konstantin
  2016-01-29 16:16       ` Nélio Laranjeiro
  2016-01-29  0:42     ` [PATCH v7 4/5] doc: update with link changes Marc Sune
                       ` (2 subsequent siblings)
  5 siblings, 2 replies; 167+ messages in thread
From: Marc Sune @ 2016-01-29  0:42 UTC (permalink / raw)
  To: dev, Wenzhuo Lu, Helin Zhang, Harish Patil, Jing Chen

This patch redesigns the API to set the link speed/s configure
for an ethernet port. Specifically:

- it allows to define a set of advertised speeds for
  auto-negociation.
- it allows to disable link auto-negociation (single fixed speed).
- default: auto-negociate all supported speeds.

Other changes:

* Added utility MACROs ETH_SPEED_NUM_XXX with the numeric
  values of all supported link speeds, in Mbps.
* Converted link_speed to uint32_t to accomodate 100G speeds
  (bug).
* Added autoneg flag in struct rte_eth_link to indicate if
  link speed was a result of auto-negociation or was fixed
  by configuration.
* Added utility function to convert numeric speeds to bitmap
  fields.

Signed-off-by: Marc Sune <marcdevel@gmail.com>
---
 app/test-pmd/cmdline.c                     | 124 +++++++++++++++--------------
 app/test/virtual_pmd.c                     |   4 +-
 drivers/net/af_packet/rte_eth_af_packet.c  |   5 +-
 drivers/net/bonding/rte_eth_bond_8023ad.c  |  14 ++--
 drivers/net/cxgbe/base/t4_hw.c             |   8 +-
 drivers/net/e1000/base/e1000_80003es2lan.c |   6 +-
 drivers/net/e1000/base/e1000_82541.c       |   8 +-
 drivers/net/e1000/base/e1000_82543.c       |   4 +-
 drivers/net/e1000/base/e1000_82575.c       |  11 +--
 drivers/net/e1000/base/e1000_api.c         |   2 +-
 drivers/net/e1000/base/e1000_api.h         |   2 +-
 drivers/net/e1000/base/e1000_defines.h     |   4 +-
 drivers/net/e1000/base/e1000_hw.h          |   2 +-
 drivers/net/e1000/base/e1000_ich8lan.c     |   7 +-
 drivers/net/e1000/base/e1000_mac.c         |   9 ++-
 drivers/net/e1000/base/e1000_mac.h         |   6 +-
 drivers/net/e1000/base/e1000_vf.c          |   4 +-
 drivers/net/e1000/base/e1000_vf.h          |   2 +-
 drivers/net/e1000/em_ethdev.c              | 113 +++++++++++++-------------
 drivers/net/e1000/igb_ethdev.c             | 108 +++++++++++++------------
 drivers/net/fm10k/fm10k_ethdev.c           |   8 +-
 drivers/net/i40e/i40e_ethdev.c             |  73 ++++++++---------
 drivers/net/i40e/i40e_ethdev_vf.c          |  11 +--
 drivers/net/ixgbe/ixgbe_ethdev.c           |  78 ++++++++----------
 drivers/net/mlx4/mlx4.c                    |   2 +
 drivers/net/mpipe/mpipe_tilegx.c           |   6 +-
 drivers/net/null/rte_eth_null.c            |   5 +-
 drivers/net/pcap/rte_eth_pcap.c            |   9 ++-
 drivers/net/ring/rte_eth_ring.c            |   5 +-
 drivers/net/virtio/virtio_ethdev.c         |   2 +-
 drivers/net/virtio/virtio_ethdev.h         |   2 -
 drivers/net/vmxnet3/vmxnet3_ethdev.c       |   5 +-
 drivers/net/xenvirt/rte_eth_xenvirt.c      |   5 +-
 examples/ip_pipeline/config_parse.c        |   3 +-
 lib/librte_ether/rte_ethdev.c              |  49 ++++++++++++
 lib/librte_ether/rte_ethdev.h              | 113 ++++++++++++++++----------
 36 files changed, 454 insertions(+), 365 deletions(-)

diff --git a/app/test-pmd/cmdline.c b/app/test-pmd/cmdline.c
index 6d28c1b..00571bc 100644
--- a/app/test-pmd/cmdline.c
+++ b/app/test-pmd/cmdline.c
@@ -956,14 +956,65 @@ struct cmd_config_speed_all {
 	cmdline_fixed_string_t value2;
 };
 
+static int
+parse_and_check_speed_duplex(char *value1, char *value2, uint32_t *link_speed)
+{
+
+	int duplex;
+
+	if (!strcmp(value2, "half")) {
+		duplex = 0;
+	} else if (!strcmp(value2, "full")) {
+		duplex = 1;
+	} else if (!strcmp(value2, "auto")) {
+		duplex = 1;
+	} else {
+		printf("Unknown parameter\n");
+		return -1;
+	}
+
+	if (!strcmp(value1, "10")) {
+		*link_speed = (duplex) ? ETH_LINK_SPEED_10M :
+							ETH_LINK_SPEED_10M_HD;
+	} else if (!strcmp(value1, "100")) {
+		*link_speed = (duplex) ? ETH_LINK_SPEED_100M :
+							ETH_LINK_SPEED_100M_HD;
+	} else if (!strcmp(value1, "1000")) {
+		if (!duplex)
+			goto invalid_speed_param;
+		*link_speed = ETH_LINK_SPEED_1G;
+	} else if (!strcmp(value1, "10000")) {
+		if (!duplex)
+			goto invalid_speed_param;
+		*link_speed = ETH_LINK_SPEED_10G;
+	} else if (!strcmp(value1, "40000")) {
+		if (!duplex)
+			goto invalid_speed_param;
+		*link_speed = ETH_LINK_SPEED_40G;
+	} else if (!strcmp(value1, "auto")) {
+		if (!duplex)
+			goto invalid_speed_param;
+		*link_speed = ETH_LINK_SPEED_AUTONEG;
+	} else {
+		printf("Unknown parameter\n");
+		return -1;
+	}
+
+	return 0;
+
+invalid_speed_param:
+
+	printf("Invalid speed parameter\n");
+	return -1;
+}
+
 static void
 cmd_config_speed_all_parsed(void *parsed_result,
 			__attribute__((unused)) struct cmdline *cl,
 			__attribute__((unused)) void *data)
 {
 	struct cmd_config_speed_all *res = parsed_result;
-	uint16_t link_speed = ETH_LINK_SPEED_AUTONEG;
-	uint16_t link_duplex = 0;
+	uint32_t link_speed;
 	portid_t pid;
 
 	if (!all_ports_stopped()) {
@@ -971,40 +1022,18 @@ cmd_config_speed_all_parsed(void *parsed_result,
 		return;
 	}
 
-	if (!strcmp(res->value1, "10"))
-		link_speed = ETH_LINK_SPEED_10;
-	else if (!strcmp(res->value1, "100"))
-		link_speed = ETH_LINK_SPEED_100;
-	else if (!strcmp(res->value1, "1000"))
-		link_speed = ETH_LINK_SPEED_1000;
-	else if (!strcmp(res->value1, "10000"))
-		link_speed = ETH_LINK_SPEED_10G;
-	else if (!strcmp(res->value1, "40000"))
-		link_speed = ETH_LINK_SPEED_40G;
-	else if (!strcmp(res->value1, "auto"))
-		link_speed = ETH_LINK_SPEED_AUTONEG;
-	else {
-		printf("Unknown parameter\n");
+	if (parse_and_check_speed_duplex(res->value1,
+						res->value2,
+						&link_speed) < 0)
 		return;
-	}
-
-	if (!strcmp(res->value2, "half"))
-		link_duplex = ETH_LINK_HALF_DUPLEX;
-	else if (!strcmp(res->value2, "full"))
-		link_duplex = ETH_LINK_FULL_DUPLEX;
-	else if (!strcmp(res->value2, "auto"))
-		link_duplex = ETH_LINK_AUTONEG_DUPLEX;
-	else {
-		printf("Unknown parameter\n");
-		return;
-	}
 
 	FOREACH_PORT(pid, ports) {
-		ports[pid].dev_conf.link_speed = link_speed;
-		ports[pid].dev_conf.link_duplex = link_duplex;
+		ports[pid].dev_conf.link_speeds = link_speed;
 	}
 
 	cmd_reconfig_device_queue(RTE_PORT_ALL, 1, 1);
+
+	return;
 }
 
 cmdline_parse_token_string_t cmd_config_speed_all_port =
@@ -1059,8 +1088,7 @@ cmd_config_speed_specific_parsed(void *parsed_result,
 				__attribute__((unused)) void *data)
 {
 	struct cmd_config_speed_specific *res = parsed_result;
-	uint16_t link_speed = ETH_LINK_SPEED_AUTONEG;
-	uint16_t link_duplex = 0;
+	uint32_t link_speed;
 
 	if (!all_ports_stopped()) {
 		printf("Please stop all ports first\n");
@@ -1070,36 +1098,12 @@ cmd_config_speed_specific_parsed(void *parsed_result,
 	if (port_id_is_invalid(res->id, ENABLED_WARN))
 		return;
 
-	if (!strcmp(res->value1, "10"))
-		link_speed = ETH_LINK_SPEED_10;
-	else if (!strcmp(res->value1, "100"))
-		link_speed = ETH_LINK_SPEED_100;
-	else if (!strcmp(res->value1, "1000"))
-		link_speed = ETH_LINK_SPEED_1000;
-	else if (!strcmp(res->value1, "10000"))
-		link_speed = ETH_LINK_SPEED_10000;
-	else if (!strcmp(res->value1, "40000"))
-		link_speed = ETH_LINK_SPEED_40G;
-	else if (!strcmp(res->value1, "auto"))
-		link_speed = ETH_LINK_SPEED_AUTONEG;
-	else {
-		printf("Unknown parameter\n");
+	if (parse_and_check_speed_duplex(res->value1,
+						res->value2,
+						&link_speed) < 0)
 		return;
-	}
-
-	if (!strcmp(res->value2, "half"))
-		link_duplex = ETH_LINK_HALF_DUPLEX;
-	else if (!strcmp(res->value2, "full"))
-		link_duplex = ETH_LINK_FULL_DUPLEX;
-	else if (!strcmp(res->value2, "auto"))
-		link_duplex = ETH_LINK_AUTONEG_DUPLEX;
-	else {
-		printf("Unknown parameter\n");
-		return;
-	}
 
-	ports[res->id].dev_conf.link_speed = link_speed;
-	ports[res->id].dev_conf.link_duplex = link_duplex;
+	ports[res->id].dev_conf.link_speeds = link_speed;
 
 	cmd_reconfig_device_queue(RTE_PORT_ALL, 1, 1);
 }
diff --git a/app/test/virtual_pmd.c b/app/test/virtual_pmd.c
index a538c8a..3c4040b 100644
--- a/app/test/virtual_pmd.c
+++ b/app/test/virtual_pmd.c
@@ -603,8 +603,8 @@ virtual_ethdev_create(const char *name, struct ether_addr *mac_addr,
 
 	TAILQ_INIT(&(eth_dev->link_intr_cbs));
 
-	eth_dev->data->dev_link.link_status = 0;
-	eth_dev->data->dev_link.link_speed = ETH_LINK_SPEED_10000;
+	eth_dev->data->dev_link.link_status = ETH_LINK_DOWN;
+	eth_dev->data->dev_link.link_speed = ETH_SPEED_NUM_10G;
 	eth_dev->data->dev_link.link_duplex = ETH_LINK_FULL_DUPLEX;
 
 	eth_dev->data->mac_addrs = rte_zmalloc(name, ETHER_ADDR_LEN, 0);
diff --git a/drivers/net/af_packet/rte_eth_af_packet.c b/drivers/net/af_packet/rte_eth_af_packet.c
index 767f36b..5db1db2 100644
--- a/drivers/net/af_packet/rte_eth_af_packet.c
+++ b/drivers/net/af_packet/rte_eth_af_packet.c
@@ -116,9 +116,10 @@ static const char *valid_arguments[] = {
 static const char *drivername = "AF_PACKET PMD";
 
 static struct rte_eth_link pmd_link = {
-	.link_speed = 10000,
+	.link_speed = ETH_SPEED_NUM_10G,
 	.link_duplex = ETH_LINK_FULL_DUPLEX,
-	.link_status = 0
+	.link_status = ETH_LINK_DOWN,
+	.link_autoneg = ETH_LINK_SPEED_NEG
 };
 
 static uint16_t
diff --git a/drivers/net/bonding/rte_eth_bond_8023ad.c b/drivers/net/bonding/rte_eth_bond_8023ad.c
index b3b30f6..3b446e1 100644
--- a/drivers/net/bonding/rte_eth_bond_8023ad.c
+++ b/drivers/net/bonding/rte_eth_bond_8023ad.c
@@ -708,25 +708,25 @@ link_speed_key(uint16_t speed) {
 	uint16_t key_speed;
 
 	switch (speed) {
-	case ETH_LINK_SPEED_AUTONEG:
+	case ETH_SPEED_NUM_NONE:
 		key_speed = 0x00;
 		break;
-	case ETH_LINK_SPEED_10:
+	case ETH_SPEED_NUM_10M:
 		key_speed = BOND_LINK_SPEED_KEY_10M;
 		break;
-	case ETH_LINK_SPEED_100:
+	case ETH_SPEED_NUM_100M:
 		key_speed = BOND_LINK_SPEED_KEY_100M;
 		break;
-	case ETH_LINK_SPEED_1000:
+	case ETH_SPEED_NUM_1G:
 		key_speed = BOND_LINK_SPEED_KEY_1000M;
 		break;
-	case ETH_LINK_SPEED_10G:
+	case ETH_SPEED_NUM_10G:
 		key_speed = BOND_LINK_SPEED_KEY_10G;
 		break;
-	case ETH_LINK_SPEED_20G:
+	case ETH_SPEED_NUM_20G:
 		key_speed = BOND_LINK_SPEED_KEY_20G;
 		break;
-	case ETH_LINK_SPEED_40G:
+	case ETH_SPEED_NUM_40G:
 		key_speed = BOND_LINK_SPEED_KEY_40G;
 		break;
 	default:
diff --git a/drivers/net/cxgbe/base/t4_hw.c b/drivers/net/cxgbe/base/t4_hw.c
index 884d2cf..79af806 100644
--- a/drivers/net/cxgbe/base/t4_hw.c
+++ b/drivers/net/cxgbe/base/t4_hw.c
@@ -2159,13 +2159,13 @@ int t4_handle_fw_rpl(struct adapter *adap, const __be64 *rpl)
 		if (stat & F_FW_PORT_CMD_TXPAUSE)
 			fc |= PAUSE_TX;
 		if (stat & V_FW_PORT_CMD_LSPEED(FW_PORT_CAP_SPEED_100M))
-			speed = ETH_LINK_SPEED_100;
+			speed = ETH_SPEED_NUM_100M;
 		else if (stat & V_FW_PORT_CMD_LSPEED(FW_PORT_CAP_SPEED_1G))
-			speed = ETH_LINK_SPEED_1000;
+			speed = ETH_SPEED_NUM_1G;
 		else if (stat & V_FW_PORT_CMD_LSPEED(FW_PORT_CAP_SPEED_10G))
-			speed = ETH_LINK_SPEED_10000;
+			speed = ETH_SPEED_NUM_10G;
 		else if (stat & V_FW_PORT_CMD_LSPEED(FW_PORT_CAP_SPEED_40G))
-			speed = ETH_LINK_SPEED_40G;
+			speed = ETH_SPEED_NUM_40G;
 
 		for_each_port(adap, i) {
 			pi = adap2pinfo(adap, i);
diff --git a/drivers/net/e1000/base/e1000_80003es2lan.c b/drivers/net/e1000/base/e1000_80003es2lan.c
index 5ac925e..ae11cac 100644
--- a/drivers/net/e1000/base/e1000_80003es2lan.c
+++ b/drivers/net/e1000/base/e1000_80003es2lan.c
@@ -52,7 +52,7 @@ STATIC s32  e1000_write_nvm_80003es2lan(struct e1000_hw *hw, u16 offset,
 STATIC s32  e1000_get_cfg_done_80003es2lan(struct e1000_hw *hw);
 STATIC s32  e1000_phy_force_speed_duplex_80003es2lan(struct e1000_hw *hw);
 STATIC s32  e1000_get_cable_length_80003es2lan(struct e1000_hw *hw);
-STATIC s32  e1000_get_link_up_info_80003es2lan(struct e1000_hw *hw, u16 *speed,
+STATIC s32  e1000_get_link_up_info_80003es2lan(struct e1000_hw *hw, u32 *speed,
 					       u16 *duplex);
 STATIC s32  e1000_reset_hw_80003es2lan(struct e1000_hw *hw);
 STATIC s32  e1000_init_hw_80003es2lan(struct e1000_hw *hw);
@@ -789,7 +789,7 @@ STATIC s32 e1000_get_cable_length_80003es2lan(struct e1000_hw *hw)
  *
  *  Retrieve the current speed and duplex configuration.
  **/
-STATIC s32 e1000_get_link_up_info_80003es2lan(struct e1000_hw *hw, u16 *speed,
+STATIC s32 e1000_get_link_up_info_80003es2lan(struct e1000_hw *hw, u32 *speed,
 					      u16 *duplex)
 {
 	s32 ret_val;
@@ -1247,7 +1247,7 @@ STATIC s32 e1000_setup_copper_link_80003es2lan(struct e1000_hw *hw)
 STATIC s32 e1000_cfg_on_link_up_80003es2lan(struct e1000_hw *hw)
 {
 	s32 ret_val = E1000_SUCCESS;
-	u16 speed;
+	u32 speed;
 	u16 duplex;
 
 	DEBUGFUNC("e1000_configure_on_link_up");
diff --git a/drivers/net/e1000/base/e1000_82541.c b/drivers/net/e1000/base/e1000_82541.c
index 9cdb91c..73f9234 100644
--- a/drivers/net/e1000/base/e1000_82541.c
+++ b/drivers/net/e1000/base/e1000_82541.c
@@ -47,7 +47,7 @@ STATIC s32  e1000_init_nvm_params_82541(struct e1000_hw *hw);
 STATIC s32  e1000_init_mac_params_82541(struct e1000_hw *hw);
 STATIC s32  e1000_reset_hw_82541(struct e1000_hw *hw);
 STATIC s32  e1000_init_hw_82541(struct e1000_hw *hw);
-STATIC s32  e1000_get_link_up_info_82541(struct e1000_hw *hw, u16 *speed,
+STATIC s32  e1000_get_link_up_info_82541(struct e1000_hw *hw, u32 *speed,
 					 u16 *duplex);
 STATIC s32  e1000_phy_hw_reset_82541(struct e1000_hw *hw);
 STATIC s32  e1000_setup_copper_link_82541(struct e1000_hw *hw);
@@ -437,7 +437,7 @@ out:
  *
  * Retrieve the current speed and duplex configuration.
  **/
-STATIC s32 e1000_get_link_up_info_82541(struct e1000_hw *hw, u16 *speed,
+STATIC s32 e1000_get_link_up_info_82541(struct e1000_hw *hw, u32 *speed,
 					u16 *duplex)
 {
 	struct e1000_phy_info *phy = &hw->phy;
@@ -667,8 +667,8 @@ STATIC s32 e1000_config_dsp_after_link_change_82541(struct e1000_hw *hw,
 	struct e1000_phy_info *phy = &hw->phy;
 	struct e1000_dev_spec_82541 *dev_spec = &hw->dev_spec._82541;
 	s32 ret_val;
-	u32 idle_errs = 0;
-	u16 phy_data, phy_saved_data, speed, duplex, i;
+	u32 idle_errs = 0, speed;
+	u16 phy_data, phy_saved_data, duplex, i;
 	u16 ffe_idle_err_timeout = FFE_IDLE_ERR_COUNT_TIMEOUT_20;
 	u16 dsp_reg_array[IGP01E1000_PHY_CHANNEL_NUM] = {
 						IGP01E1000_PHY_AGC_PARAM_A,
diff --git a/drivers/net/e1000/base/e1000_82543.c b/drivers/net/e1000/base/e1000_82543.c
index fc96199..4402f63 100644
--- a/drivers/net/e1000/base/e1000_82543.c
+++ b/drivers/net/e1000/base/e1000_82543.c
@@ -1192,9 +1192,9 @@ out:
 STATIC s32 e1000_check_for_copper_link_82543(struct e1000_hw *hw)
 {
 	struct e1000_mac_info *mac = &hw->mac;
-	u32 icr, rctl;
+	u32 icr, rctl, speed;
 	s32 ret_val;
-	u16 speed, duplex;
+	u16 duplex;
 	bool link;
 
 	DEBUGFUNC("e1000_check_for_copper_link_82543");
diff --git a/drivers/net/e1000/base/e1000_82575.c b/drivers/net/e1000/base/e1000_82575.c
index 723885d..f8d61e4 100644
--- a/drivers/net/e1000/base/e1000_82575.c
+++ b/drivers/net/e1000/base/e1000_82575.c
@@ -53,7 +53,7 @@ STATIC void e1000_release_nvm_82575(struct e1000_hw *hw);
 STATIC s32  e1000_check_for_link_82575(struct e1000_hw *hw);
 STATIC s32  e1000_check_for_link_media_swap(struct e1000_hw *hw);
 STATIC s32  e1000_get_cfg_done_82575(struct e1000_hw *hw);
-STATIC s32  e1000_get_link_up_info_82575(struct e1000_hw *hw, u16 *speed,
+STATIC s32  e1000_get_link_up_info_82575(struct e1000_hw *hw, u32 *speed,
 					 u16 *duplex);
 STATIC s32  e1000_phy_hw_reset_sgmii_82575(struct e1000_hw *hw);
 STATIC s32  e1000_read_phy_reg_sgmii_82575(struct e1000_hw *hw, u32 offset,
@@ -80,7 +80,7 @@ STATIC s32  e1000_write_phy_reg_sgmii_82575(struct e1000_hw *hw,
 STATIC void e1000_clear_hw_cntrs_82575(struct e1000_hw *hw);
 STATIC s32  e1000_acquire_swfw_sync_82575(struct e1000_hw *hw, u16 mask);
 STATIC s32  e1000_get_pcs_speed_and_duplex_82575(struct e1000_hw *hw,
-						 u16 *speed, u16 *duplex);
+						 u32 *speed, u16 *duplex);
 STATIC s32  e1000_get_phy_id_82575(struct e1000_hw *hw);
 STATIC void e1000_release_swfw_sync_82575(struct e1000_hw *hw, u16 mask);
 STATIC bool e1000_sgmii_active_82575(struct e1000_hw *hw);
@@ -1167,7 +1167,7 @@ STATIC s32 e1000_get_cfg_done_82575(struct e1000_hw *hw)
  *  interface, use PCS to retrieve the link speed and duplex information.
  *  Otherwise, use the generic function to get the link speed and duplex info.
  **/
-STATIC s32 e1000_get_link_up_info_82575(struct e1000_hw *hw, u16 *speed,
+STATIC s32 e1000_get_link_up_info_82575(struct e1000_hw *hw, u32 *speed,
 					u16 *duplex)
 {
 	s32 ret_val;
@@ -1194,7 +1194,8 @@ STATIC s32 e1000_get_link_up_info_82575(struct e1000_hw *hw, u16 *speed,
 STATIC s32 e1000_check_for_link_82575(struct e1000_hw *hw)
 {
 	s32 ret_val;
-	u16 speed, duplex;
+	u32 speed;
+	u16 duplex;
 
 	DEBUGFUNC("e1000_check_for_link_82575");
 
@@ -1325,7 +1326,7 @@ STATIC void e1000_power_up_serdes_link_82575(struct e1000_hw *hw)
  *  duplex, then store the values in the pointers provided.
  **/
 STATIC s32 e1000_get_pcs_speed_and_duplex_82575(struct e1000_hw *hw,
-						u16 *speed, u16 *duplex)
+						u32 *speed, u16 *duplex)
 {
 	struct e1000_mac_info *mac = &hw->mac;
 	u32 pcs;
diff --git a/drivers/net/e1000/base/e1000_api.c b/drivers/net/e1000/base/e1000_api.c
index bbfcae8..3a066d5 100644
--- a/drivers/net/e1000/base/e1000_api.c
+++ b/drivers/net/e1000/base/e1000_api.c
@@ -673,7 +673,7 @@ s32 e1000_setup_link(struct e1000_hw *hw)
  *  variables passed in. This is a function pointer entry point called
  *  by drivers.
  **/
-s32 e1000_get_speed_and_duplex(struct e1000_hw *hw, u16 *speed, u16 *duplex)
+s32 e1000_get_speed_and_duplex(struct e1000_hw *hw, u32 *speed, u16 *duplex)
 {
 	if (hw->mac.ops.get_link_up_info)
 		return hw->mac.ops.get_link_up_info(hw, speed, duplex);
diff --git a/drivers/net/e1000/base/e1000_api.h b/drivers/net/e1000/base/e1000_api.h
index 0bc471d..7327750 100644
--- a/drivers/net/e1000/base/e1000_api.h
+++ b/drivers/net/e1000/base/e1000_api.h
@@ -65,7 +65,7 @@ s32 e1000_check_for_link(struct e1000_hw *hw);
 s32 e1000_reset_hw(struct e1000_hw *hw);
 s32 e1000_init_hw(struct e1000_hw *hw);
 s32 e1000_setup_link(struct e1000_hw *hw);
-s32 e1000_get_speed_and_duplex(struct e1000_hw *hw, u16 *speed, u16 *duplex);
+s32 e1000_get_speed_and_duplex(struct e1000_hw *hw, u32 *speed, u16 *duplex);
 s32 e1000_disable_pcie_master(struct e1000_hw *hw);
 void e1000_config_collision_dist(struct e1000_hw *hw);
 int e1000_rar_set(struct e1000_hw *hw, u8 *addr, u32 index);
diff --git a/drivers/net/e1000/base/e1000_defines.h b/drivers/net/e1000/base/e1000_defines.h
index 69aa1f2..692845d 100644
--- a/drivers/net/e1000/base/e1000_defines.h
+++ b/drivers/net/e1000/base/e1000_defines.h
@@ -348,8 +348,8 @@ POSSIBILITY OF SUCH DAMAGE.
 #define SPEED_100	100
 #define SPEED_1000	1000
 #define SPEED_2500	2500
-#define HALF_DUPLEX	1
-#define FULL_DUPLEX	2
+#define HALF_DUPLEX	0
+#define FULL_DUPLEX	1
 
 #define PHY_FORCE_TIME	20
 
diff --git a/drivers/net/e1000/base/e1000_hw.h b/drivers/net/e1000/base/e1000_hw.h
index e4e4f76..30e7f3b 100644
--- a/drivers/net/e1000/base/e1000_hw.h
+++ b/drivers/net/e1000/base/e1000_hw.h
@@ -686,7 +686,7 @@ struct e1000_mac_operations {
 	void (*clear_vfta)(struct e1000_hw *);
 	s32  (*get_bus_info)(struct e1000_hw *);
 	void (*set_lan_id)(struct e1000_hw *);
-	s32  (*get_link_up_info)(struct e1000_hw *, u16 *, u16 *);
+	s32  (*get_link_up_info)(struct e1000_hw *, u32 *, u16 *);
 	s32  (*led_on)(struct e1000_hw *);
 	s32  (*led_off)(struct e1000_hw *);
 	void (*update_mc_addr_list)(struct e1000_hw *, u8 *, u32);
diff --git a/drivers/net/e1000/base/e1000_ich8lan.c b/drivers/net/e1000/base/e1000_ich8lan.c
index 89d07e9..a6e01c7 100644
--- a/drivers/net/e1000/base/e1000_ich8lan.c
+++ b/drivers/net/e1000/base/e1000_ich8lan.c
@@ -108,7 +108,7 @@ STATIC s32  e1000_setup_link_ich8lan(struct e1000_hw *hw);
 STATIC s32  e1000_setup_copper_link_ich8lan(struct e1000_hw *hw);
 STATIC s32  e1000_setup_copper_link_pch_lpt(struct e1000_hw *hw);
 STATIC s32  e1000_get_link_up_info_ich8lan(struct e1000_hw *hw,
-					   u16 *speed, u16 *duplex);
+					   u32 *speed, u16 *duplex);
 STATIC s32  e1000_cleanup_led_ich8lan(struct e1000_hw *hw);
 STATIC s32  e1000_led_on_ich8lan(struct e1000_hw *hw);
 STATIC s32  e1000_led_off_ich8lan(struct e1000_hw *hw);
@@ -1458,7 +1458,8 @@ STATIC s32 e1000_check_for_copper_link_ich8lan(struct e1000_hw *hw)
 	 */
 	if (((hw->mac.type == e1000_pch2lan) ||
 	     (hw->mac.type == e1000_pch_lpt)) && link) {
-		u16 speed, duplex;
+		u16 duplex;
+		u32 speed;
 
 		e1000_get_speed_and_duplex_copper_generic(hw, &speed, &duplex);
 		tipg_reg = E1000_READ_REG(hw, E1000_TIPG);
@@ -4623,7 +4624,7 @@ STATIC s32 e1000_setup_copper_link_pch_lpt(struct e1000_hw *hw)
  *  information and then calls the Kumeran lock loss workaround for links at
  *  gigabit speeds.
  **/
-STATIC s32 e1000_get_link_up_info_ich8lan(struct e1000_hw *hw, u16 *speed,
+STATIC s32 e1000_get_link_up_info_ich8lan(struct e1000_hw *hw, u32 *speed,
 					  u16 *duplex)
 {
 	s32 ret_val;
diff --git a/drivers/net/e1000/base/e1000_mac.c b/drivers/net/e1000/base/e1000_mac.c
index a0f3a99..c66421c 100644
--- a/drivers/net/e1000/base/e1000_mac.c
+++ b/drivers/net/e1000/base/e1000_mac.c
@@ -106,7 +106,7 @@ void e1000_null_mac_generic(struct e1000_hw E1000_UNUSEDARG *hw)
  *  @hw: pointer to the HW structure
  **/
 s32 e1000_null_link_info(struct e1000_hw E1000_UNUSEDARG *hw,
-			 u16 E1000_UNUSEDARG *s, u16 E1000_UNUSEDARG *d)
+			 u32 E1000_UNUSEDARG *s, u16 E1000_UNUSEDARG *d)
 {
 	DEBUGFUNC("e1000_null_link_info");
 	UNREFERENCED_3PARAMETER(hw, s, d);
@@ -1348,7 +1348,8 @@ s32 e1000_config_fc_after_link_up_generic(struct e1000_hw *hw)
 	s32 ret_val = E1000_SUCCESS;
 	u32 pcs_status_reg, pcs_adv_reg, pcs_lp_ability_reg, pcs_ctrl_reg;
 	u16 mii_status_reg, mii_nway_adv_reg, mii_nway_lp_ability_reg;
-	u16 speed, duplex;
+	u32 speed;
+	u16 duplex;
 
 	DEBUGFUNC("e1000_config_fc_after_link_up_generic");
 
@@ -1650,7 +1651,7 @@ s32 e1000_config_fc_after_link_up_generic(struct e1000_hw *hw)
  *  Read the status register for the current speed/duplex and store the current
  *  speed and duplex for copper connections.
  **/
-s32 e1000_get_speed_and_duplex_copper_generic(struct e1000_hw *hw, u16 *speed,
+s32 e1000_get_speed_and_duplex_copper_generic(struct e1000_hw *hw, u32 *speed,
 					      u16 *duplex)
 {
 	u32 status;
@@ -1690,7 +1691,7 @@ s32 e1000_get_speed_and_duplex_copper_generic(struct e1000_hw *hw, u16 *speed,
  *  for fiber/serdes links.
  **/
 s32 e1000_get_speed_and_duplex_fiber_serdes_generic(struct e1000_hw E1000_UNUSEDARG *hw,
-						    u16 *speed, u16 *duplex)
+						    u32 *speed, u16 *duplex)
 {
 	DEBUGFUNC("e1000_get_speed_and_duplex_fiber_serdes_generic");
 	UNREFERENCED_1PARAMETER(hw);
diff --git a/drivers/net/e1000/base/e1000_mac.h b/drivers/net/e1000/base/e1000_mac.h
index 96a260c..fef862f 100644
--- a/drivers/net/e1000/base/e1000_mac.h
+++ b/drivers/net/e1000/base/e1000_mac.h
@@ -40,7 +40,7 @@ void e1000_init_mac_ops_generic(struct e1000_hw *hw);
 #endif /* E1000_REMOVED */
 void e1000_null_mac_generic(struct e1000_hw *hw);
 s32  e1000_null_ops_generic(struct e1000_hw *hw);
-s32  e1000_null_link_info(struct e1000_hw *hw, u16 *s, u16 *d);
+s32  e1000_null_link_info(struct e1000_hw *hw, u32 *s, u16 *d);
 bool e1000_null_mng_mode(struct e1000_hw *hw);
 void e1000_null_update_mc(struct e1000_hw *hw, u8 *h, u32 a);
 void e1000_null_write_vfta(struct e1000_hw *hw, u32 a, u32 b);
@@ -61,10 +61,10 @@ s32  e1000_get_bus_info_pcie_generic(struct e1000_hw *hw);
 void e1000_set_lan_id_single_port(struct e1000_hw *hw);
 void e1000_set_lan_id_multi_port_pci(struct e1000_hw *hw);
 s32  e1000_get_hw_semaphore_generic(struct e1000_hw *hw);
-s32  e1000_get_speed_and_duplex_copper_generic(struct e1000_hw *hw, u16 *speed,
+s32  e1000_get_speed_and_duplex_copper_generic(struct e1000_hw *hw, u32 *speed,
 					       u16 *duplex);
 s32  e1000_get_speed_and_duplex_fiber_serdes_generic(struct e1000_hw *hw,
-						     u16 *speed, u16 *duplex);
+						     u32 *speed, u16 *duplex);
 s32  e1000_id_led_init_generic(struct e1000_hw *hw);
 s32  e1000_led_on_generic(struct e1000_hw *hw);
 s32  e1000_led_off_generic(struct e1000_hw *hw);
diff --git a/drivers/net/e1000/base/e1000_vf.c b/drivers/net/e1000/base/e1000_vf.c
index 7845b48..c7fc80f 100644
--- a/drivers/net/e1000/base/e1000_vf.c
+++ b/drivers/net/e1000/base/e1000_vf.c
@@ -43,7 +43,7 @@ STATIC s32 e1000_setup_link_vf(struct e1000_hw *hw);
 STATIC s32 e1000_get_bus_info_pcie_vf(struct e1000_hw *hw);
 STATIC s32 e1000_init_mac_params_vf(struct e1000_hw *hw);
 STATIC s32 e1000_check_for_link_vf(struct e1000_hw *hw);
-STATIC s32 e1000_get_link_up_info_vf(struct e1000_hw *hw, u16 *speed,
+STATIC s32 e1000_get_link_up_info_vf(struct e1000_hw *hw, u32 *speed,
 				     u16 *duplex);
 STATIC s32 e1000_init_hw_vf(struct e1000_hw *hw);
 STATIC s32 e1000_reset_hw_vf(struct e1000_hw *hw);
@@ -220,7 +220,7 @@ STATIC s32 e1000_get_bus_info_pcie_vf(struct e1000_hw *hw)
  *  Since we cannot read the PHY and get accurate link info, we must rely upon
  *  the status register's data which is often stale and inaccurate.
  **/
-STATIC s32 e1000_get_link_up_info_vf(struct e1000_hw *hw, u16 *speed,
+STATIC s32 e1000_get_link_up_info_vf(struct e1000_hw *hw, u32 *speed,
 				     u16 *duplex)
 {
 	s32 status;
diff --git a/drivers/net/e1000/base/e1000_vf.h b/drivers/net/e1000/base/e1000_vf.h
index d6216de..f7b5ea8 100644
--- a/drivers/net/e1000/base/e1000_vf.h
+++ b/drivers/net/e1000/base/e1000_vf.h
@@ -201,7 +201,7 @@ struct e1000_mac_operations {
 	s32  (*check_for_link)(struct e1000_hw *);
 	void (*clear_vfta)(struct e1000_hw *);
 	s32  (*get_bus_info)(struct e1000_hw *);
-	s32  (*get_link_up_info)(struct e1000_hw *, u16 *, u16 *);
+	s32  (*get_link_up_info)(struct e1000_hw *, u32 *, u16 *);
 	void (*update_mc_addr_list)(struct e1000_hw *, u8 *, u32);
 	s32  (*reset_hw)(struct e1000_hw *);
 	s32  (*init_hw)(struct e1000_hw *);
diff --git a/drivers/net/e1000/em_ethdev.c b/drivers/net/e1000/em_ethdev.c
index fd48bbf..a041710 100644
--- a/drivers/net/e1000/em_ethdev.c
+++ b/drivers/net/e1000/em_ethdev.c
@@ -509,6 +509,9 @@ eth_em_start(struct rte_eth_dev *dev)
 	struct rte_intr_handle *intr_handle = &dev->pci_dev->intr_handle;
 	int ret, mask;
 	uint32_t intr_vector = 0;
+	uint32_t *speeds;
+	int num_speeds;
+	bool autoneg;
 
 	PMD_INIT_FUNC_TRACE();
 
@@ -583,56 +586,46 @@ eth_em_start(struct rte_eth_dev *dev)
 	E1000_WRITE_REG(hw, E1000_ITR, UINT16_MAX);
 
 	/* Setup link speed and duplex */
-	switch (dev->data->dev_conf.link_speed) {
-	case ETH_LINK_SPEED_AUTONEG:
-		if (dev->data->dev_conf.link_duplex == ETH_LINK_AUTONEG_DUPLEX)
-			hw->phy.autoneg_advertised = E1000_ALL_SPEED_DUPLEX;
-		else if (dev->data->dev_conf.link_duplex ==
-					ETH_LINK_HALF_DUPLEX)
-			hw->phy.autoneg_advertised = E1000_ALL_HALF_DUPLEX;
-		else if (dev->data->dev_conf.link_duplex ==
-					ETH_LINK_FULL_DUPLEX)
-			hw->phy.autoneg_advertised = E1000_ALL_FULL_DUPLEX;
-		else
-			goto error_invalid_config;
-		break;
-	case ETH_LINK_SPEED_10:
-		if (dev->data->dev_conf.link_duplex == ETH_LINK_AUTONEG_DUPLEX)
-			hw->phy.autoneg_advertised = E1000_ALL_10_SPEED;
-		else if (dev->data->dev_conf.link_duplex ==
-					ETH_LINK_HALF_DUPLEX)
-			hw->phy.autoneg_advertised = ADVERTISE_10_HALF;
-		else if (dev->data->dev_conf.link_duplex ==
-					ETH_LINK_FULL_DUPLEX)
-			hw->phy.autoneg_advertised = ADVERTISE_10_FULL;
-		else
-			goto error_invalid_config;
-		break;
-	case ETH_LINK_SPEED_100:
-		if (dev->data->dev_conf.link_duplex == ETH_LINK_AUTONEG_DUPLEX)
-			hw->phy.autoneg_advertised = E1000_ALL_100_SPEED;
-		else if (dev->data->dev_conf.link_duplex ==
-					ETH_LINK_HALF_DUPLEX)
-			hw->phy.autoneg_advertised = ADVERTISE_100_HALF;
-		else if (dev->data->dev_conf.link_duplex ==
-					ETH_LINK_FULL_DUPLEX)
-			hw->phy.autoneg_advertised = ADVERTISE_100_FULL;
-		else
+	speeds = &dev->data->dev_conf.link_speeds;
+	if (*speeds == ETH_LINK_SPEED_AUTONEG) {
+		hw->phy.autoneg_advertised = E1000_ALL_SPEED_DUPLEX;
+	} else {
+		num_speeds = 0;
+		autoneg = ~(*speeds & ETH_LINK_SPEED_NO_AUTONEG);
+
+		/* Reset */
+		hw->phy.autoneg_advertised = 0;
+
+		if (*speeds & ~(ETH_LINK_SPEED_10M_HD | ETH_LINK_SPEED_10M |
+				ETH_LINK_SPEED_100M_HD | ETH_LINK_SPEED_100M |
+				ETH_LINK_SPEED_1G)) {
+			num_speeds = -1;
 			goto error_invalid_config;
-		break;
-	case ETH_LINK_SPEED_1000:
-		if ((dev->data->dev_conf.link_duplex ==
-				ETH_LINK_AUTONEG_DUPLEX) ||
-			(dev->data->dev_conf.link_duplex ==
-					ETH_LINK_FULL_DUPLEX))
-			hw->phy.autoneg_advertised = ADVERTISE_1000_FULL;
-		else
+		}
+		if (*speeds & ETH_LINK_SPEED_10M_HD) {
+			hw->phy.autoneg_advertised |= ADVERTISE_10_HALF;
+			num_speeds++;
+		}
+		if (*speeds & ETH_LINK_SPEED_10M) {
+			hw->phy.autoneg_advertised |= ADVERTISE_10_FULL;
+			num_speeds++;
+		}
+		if (*speeds & ETH_LINK_SPEED_100M_HD) {
+			hw->phy.autoneg_advertised |= ADVERTISE_100_HALF;
+			num_speeds++;
+		}
+		if (*speeds & ETH_LINK_SPEED_100M) {
+			hw->phy.autoneg_advertised |= ADVERTISE_100_FULL;
+			num_speeds++;
+		}
+		if (*speeds & ETH_LINK_SPEED_1G) {
+			hw->phy.autoneg_advertised |= ADVERTISE_1000_FULL;
+			num_speeds++;
+		}
+		if (num_speeds == 0 || (!autoneg && (num_speeds > 2)))
 			goto error_invalid_config;
-		break;
-	case ETH_LINK_SPEED_10000:
-	default:
-		goto error_invalid_config;
 	}
+
 	e1000_setup_link(hw);
 
 	if (rte_intr_allow_others(intr_handle)) {
@@ -665,9 +658,8 @@ eth_em_start(struct rte_eth_dev *dev)
 	return (0);
 
 error_invalid_config:
-	PMD_INIT_LOG(ERR, "Invalid link_speed/link_duplex (%u/%u) for port %u",
-		     dev->data->dev_conf.link_speed,
-		     dev->data->dev_conf.link_duplex, dev->data->port_id);
+	PMD_INIT_LOG(ERR, "Invalid advertised speeds (%u) for port %u",
+		     dev->data->dev_conf.link_speeds, dev->data->port_id);
 	em_dev_clear_queues(dev);
 	return (-EINVAL);
 }
@@ -1024,11 +1016,11 @@ eth_em_infos_get(struct rte_eth_dev *dev, struct rte_eth_dev_info *dev_info)
 		.nb_align = EM_TXD_ALIGN,
 	};
 
-	dev_info->speed_capa = ETH_SPEED_CAP_10M_HD |
-					ETH_SPEED_CAP_10M_FD |
-					ETH_SPEED_CAP_100M_HD |
-					ETH_SPEED_CAP_100M_FD |
-					ETH_SPEED_CAP_1G;
+	dev_info->speed_capa = ETH_LINK_SPEED_10M_HD |
+					ETH_LINK_SPEED_10M |
+					ETH_LINK_SPEED_100M_HD |
+					ETH_LINK_SPEED_100M |
+					ETH_LINK_SPEED_1G;
 }
 
 /* return 0 means link status changed, -1 means not changed */
@@ -1077,13 +1069,16 @@ eth_em_link_update(struct rte_eth_dev *dev, int wait_to_complete)
 
 	/* Now we check if a transition has happened */
 	if (link_check && (link.link_status == 0)) {
+		uint16_t duplex;
 		hw->mac.ops.get_link_up_info(hw, &link.link_speed,
-			&link.link_duplex);
-		link.link_status = 1;
+			&duplex);
+		link.link_duplex = (duplex) ? ETH_LINK_FULL_DUPLEX :
+						ETH_LINK_HALF_DUPLEX;
+		link.link_status = ETH_LINK_UP;
 	} else if (!link_check && (link.link_status == 1)) {
 		link.link_speed = 0;
-		link.link_duplex = 0;
-		link.link_status = 0;
+		link.link_duplex = ETH_LINK_HALF_DUPLEX;
+		link.link_status = ETH_LINK_DOWN;
 	}
 	rte_em_dev_atomic_write_link_status(dev, &link);
 
diff --git a/drivers/net/e1000/igb_ethdev.c b/drivers/net/e1000/igb_ethdev.c
index 9c8dffa..c1c41b3 100644
--- a/drivers/net/e1000/igb_ethdev.c
+++ b/drivers/net/e1000/igb_ethdev.c
@@ -1119,6 +1119,9 @@ eth_igb_start(struct rte_eth_dev *dev)
 	int ret, mask;
 	uint32_t intr_vector = 0;
 	uint32_t ctrl_ext;
+	uint32_t *speeds;
+	int num_speeds;
+	bool autoneg;
 
 	PMD_INIT_FUNC_TRACE();
 
@@ -1219,48 +1222,46 @@ eth_igb_start(struct rte_eth_dev *dev)
 	}
 
 	/* Setup link speed and duplex */
-	switch (dev->data->dev_conf.link_speed) {
-	case ETH_LINK_SPEED_AUTONEG:
-		if (dev->data->dev_conf.link_duplex == ETH_LINK_AUTONEG_DUPLEX)
-			hw->phy.autoneg_advertised = E1000_ALL_SPEED_DUPLEX;
-		else if (dev->data->dev_conf.link_duplex == ETH_LINK_HALF_DUPLEX)
-			hw->phy.autoneg_advertised = E1000_ALL_HALF_DUPLEX;
-		else if (dev->data->dev_conf.link_duplex == ETH_LINK_FULL_DUPLEX)
-			hw->phy.autoneg_advertised = E1000_ALL_FULL_DUPLEX;
-		else
-			goto error_invalid_config;
-		break;
-	case ETH_LINK_SPEED_10:
-		if (dev->data->dev_conf.link_duplex == ETH_LINK_AUTONEG_DUPLEX)
-			hw->phy.autoneg_advertised = E1000_ALL_10_SPEED;
-		else if (dev->data->dev_conf.link_duplex == ETH_LINK_HALF_DUPLEX)
-			hw->phy.autoneg_advertised = ADVERTISE_10_HALF;
-		else if (dev->data->dev_conf.link_duplex == ETH_LINK_FULL_DUPLEX)
-			hw->phy.autoneg_advertised = ADVERTISE_10_FULL;
-		else
-			goto error_invalid_config;
-		break;
-	case ETH_LINK_SPEED_100:
-		if (dev->data->dev_conf.link_duplex == ETH_LINK_AUTONEG_DUPLEX)
-			hw->phy.autoneg_advertised = E1000_ALL_100_SPEED;
-		else if (dev->data->dev_conf.link_duplex == ETH_LINK_HALF_DUPLEX)
-			hw->phy.autoneg_advertised = ADVERTISE_100_HALF;
-		else if (dev->data->dev_conf.link_duplex == ETH_LINK_FULL_DUPLEX)
-			hw->phy.autoneg_advertised = ADVERTISE_100_FULL;
-		else
+	speeds = &dev->data->dev_conf.link_speeds;
+	if (*speeds == ETH_LINK_SPEED_AUTONEG) {
+		hw->phy.autoneg_advertised = E1000_ALL_SPEED_DUPLEX;
+	} else {
+		num_speeds = 0;
+		autoneg = ~(*speeds & ETH_LINK_SPEED_NO_AUTONEG);
+
+		/* Reset */
+		hw->phy.autoneg_advertised = 0;
+
+		if (*speeds & ~(ETH_LINK_SPEED_10M_HD | ETH_LINK_SPEED_10M |
+				ETH_LINK_SPEED_100M_HD | ETH_LINK_SPEED_100M |
+				ETH_LINK_SPEED_1G)) {
+			num_speeds = -1;
 			goto error_invalid_config;
-		break;
-	case ETH_LINK_SPEED_1000:
-		if ((dev->data->dev_conf.link_duplex == ETH_LINK_AUTONEG_DUPLEX) ||
-				(dev->data->dev_conf.link_duplex == ETH_LINK_FULL_DUPLEX))
-			hw->phy.autoneg_advertised = ADVERTISE_1000_FULL;
-		else
+		}
+		if (*speeds & ETH_LINK_SPEED_10M_HD) {
+			hw->phy.autoneg_advertised |= ADVERTISE_10_HALF;
+			num_speeds++;
+		}
+		if (*speeds & ETH_LINK_SPEED_10M) {
+			hw->phy.autoneg_advertised |= ADVERTISE_10_FULL;
+			num_speeds++;
+		}
+		if (*speeds & ETH_LINK_SPEED_100M_HD) {
+			hw->phy.autoneg_advertised |= ADVERTISE_100_HALF;
+			num_speeds++;
+		}
+		if (*speeds & ETH_LINK_SPEED_100M) {
+			hw->phy.autoneg_advertised |= ADVERTISE_100_FULL;
+			num_speeds++;
+		}
+		if (*speeds & ETH_LINK_SPEED_1G) {
+			hw->phy.autoneg_advertised |= ADVERTISE_1000_FULL;
+			num_speeds++;
+		}
+		if (num_speeds == 0 || (!autoneg && (num_speeds > 2)))
 			goto error_invalid_config;
-		break;
-	case ETH_LINK_SPEED_10000:
-	default:
-		goto error_invalid_config;
 	}
+
 	e1000_setup_link(hw);
 
 	if (rte_intr_allow_others(intr_handle)) {
@@ -1292,9 +1293,8 @@ eth_igb_start(struct rte_eth_dev *dev)
 	return (0);
 
 error_invalid_config:
-	PMD_INIT_LOG(ERR, "Invalid link_speed/link_duplex (%u/%u) for port %u",
-		     dev->data->dev_conf.link_speed,
-		     dev->data->dev_conf.link_duplex, dev->data->port_id);
+	PMD_INIT_LOG(ERR, "Invalid advertised speeds (%u) for port %u",
+		     dev->data->dev_conf.link_speeds, dev->data->port_id);
 	igb_dev_clear_queues(dev);
 	return (-EINVAL);
 }
@@ -1909,11 +1909,11 @@ eth_igb_infos_get(struct rte_eth_dev *dev, struct rte_eth_dev_info *dev_info)
 	dev_info->rx_desc_lim = rx_desc_lim;
 	dev_info->tx_desc_lim = tx_desc_lim;
 
-	dev_info->speed_capa = ETH_SPEED_CAP_10M_HD |
-					ETH_SPEED_CAP_10M_FD |
-					ETH_SPEED_CAP_100M_HD |
-					ETH_SPEED_CAP_100M_FD |
-					ETH_SPEED_CAP_1G;
+	dev_info->speed_capa = ETH_LINK_SPEED_10M_HD |
+					ETH_LINK_SPEED_10M |
+					ETH_LINK_SPEED_100M_HD |
+					ETH_LINK_SPEED_100M |
+					ETH_LINK_SPEED_1G;
 }
 
 static void
@@ -2023,13 +2023,19 @@ eth_igb_link_update(struct rte_eth_dev *dev, int wait_to_complete)
 
 	/* Now we check if a transition has happened */
 	if (link_check) {
+		uint16_t duplex;
 		hw->mac.ops.get_link_up_info(hw, &link.link_speed,
-					  &link.link_duplex);
-		link.link_status = 1;
+					  &duplex);
+		link.link_duplex = (duplex) ? ETH_LINK_FULL_DUPLEX :
+							ETH_LINK_HALF_DUPLEX ;
+		link.link_status = ETH_LINK_UP;
+		link.link_autoneg = ~(dev->data->dev_conf.link_speeds &
+						ETH_LINK_SPEED_NO_AUTONEG);
 	} else if (!link_check) {
 		link.link_speed = 0;
-		link.link_duplex = 0;
-		link.link_status = 0;
+		link.link_duplex = ETH_LINK_HALF_DUPLEX;
+		link.link_status = ETH_LINK_DOWN;
+		link.link_autoneg = ETH_LINK_SPEED_FIXED;
 	}
 	rte_igb_dev_atomic_write_link_status(dev, &link);
 
diff --git a/drivers/net/fm10k/fm10k_ethdev.c b/drivers/net/fm10k/fm10k_ethdev.c
index aeb2962..702eb97 100644
--- a/drivers/net/fm10k/fm10k_ethdev.c
+++ b/drivers/net/fm10k/fm10k_ethdev.c
@@ -1172,7 +1172,7 @@ fm10k_link_update(struct rte_eth_dev *dev,
 	 * is no 50Gbps Ethernet. */
 	dev->data->dev_link.link_speed  = 0;
 	dev->data->dev_link.link_duplex = ETH_LINK_FULL_DUPLEX;
-	dev->data->dev_link.link_status = 1;
+	dev->data->dev_link.link_status = ETH_LINK_UP;
 
 	return 0;
 }
@@ -1334,9 +1334,9 @@ fm10k_dev_infos_get(struct rte_eth_dev *dev,
 		.nb_align = FM10K_MULT_TX_DESC,
 	};
 
-	dev_info->speed_capa = ETH_SPEED_CAP_1G | ETH_SPEED_CAP_2_5G |
-					ETH_SPEED_CAP_10G | ETH_SPEED_CAP_25G |
-					ETH_SPEED_CAP_40G | ETH_SPEED_CAP_100G;
+	dev_info->speed_capa = ETH_LINK_SPEED_1G | ETH_LINK_SPEED_2_5G |
+				ETH_LINK_SPEED_10G | ETH_LINK_SPEED_25G |
+				ETH_LINK_SPEED_40G | ETH_LINK_SPEED_100G;
 }
 
 static int
diff --git a/drivers/net/i40e/i40e_ethdev.c b/drivers/net/i40e/i40e_ethdev.c
index d242973..34bc2c9 100644
--- a/drivers/net/i40e/i40e_ethdev.c
+++ b/drivers/net/i40e/i40e_ethdev.c
@@ -1326,27 +1326,20 @@ i40e_vsi_disable_queues_intr(struct i40e_vsi *vsi)
 }
 
 static inline uint8_t
-i40e_parse_link_speed(uint16_t eth_link_speed)
+i40e_parse_link_speeds(uint16_t link_speeds)
 {
 	uint8_t link_speed = I40E_LINK_SPEED_UNKNOWN;
 
-	switch (eth_link_speed) {
-	case ETH_LINK_SPEED_40G:
-		link_speed = I40E_LINK_SPEED_40GB;
-		break;
-	case ETH_LINK_SPEED_20G:
-		link_speed = I40E_LINK_SPEED_20GB;
-		break;
-	case ETH_LINK_SPEED_10G:
-		link_speed = I40E_LINK_SPEED_10GB;
-		break;
-	case ETH_LINK_SPEED_1000:
-		link_speed = I40E_LINK_SPEED_1GB;
-		break;
-	case ETH_LINK_SPEED_100:
-		link_speed = I40E_LINK_SPEED_100MB;
-		break;
-	}
+	if (link_speeds & ETH_LINK_SPEED_40G)
+		link_speed |= I40E_LINK_SPEED_40GB;
+	if (link_speeds & ETH_LINK_SPEED_20G)
+		link_speed |= I40E_LINK_SPEED_20GB;
+	if (link_speeds & ETH_LINK_SPEED_10G)
+		link_speed |= I40E_LINK_SPEED_10GB;
+	if (link_speeds & ETH_LINK_SPEED_1G)
+		link_speed |= I40E_LINK_SPEED_1GB;
+	if (link_speeds & ETH_LINK_SPEED_100M)
+		link_speed |= I40E_LINK_SPEED_100MB;
 
 	return link_speed;
 }
@@ -1372,9 +1365,9 @@ i40e_apply_link_speed(struct rte_eth_dev *dev)
 	struct i40e_hw *hw = I40E_DEV_PRIVATE_TO_HW(dev->data->dev_private);
 	struct rte_eth_conf *conf = &dev->data->dev_conf;
 
-	speed = i40e_parse_link_speed(conf->link_speed);
+	speed = i40e_parse_link_speeds(conf->link_speeds);
 	abilities |= I40E_AQ_PHY_ENABLE_ATOMIC_LINK;
-	if (conf->link_speed == ETH_LINK_SPEED_AUTONEG)
+	if (conf->link_speeds & ETH_LINK_SPEED_AUTONEG)
 		abilities |= I40E_AQ_PHY_AN_ENABLED;
 	else
 		abilities |= I40E_AQ_PHY_LINK_ENABLED;
@@ -1394,10 +1387,8 @@ i40e_dev_start(struct rte_eth_dev *dev)
 
 	hw->adapter_stopped = 0;
 
-	if ((dev->data->dev_conf.link_duplex != ETH_LINK_AUTONEG_DUPLEX) &&
-		(dev->data->dev_conf.link_duplex != ETH_LINK_FULL_DUPLEX)) {
-		PMD_INIT_LOG(ERR, "Invalid link_duplex (%hu) for port %hhu",
-			     dev->data->dev_conf.link_duplex,
+	if (dev->data->dev_conf.link_speeds & ETH_LINK_SPEED_NO_AUTONEG) {
+		PMD_INIT_LOG(ERR, "Invalid link_speeds for port %hhu; autonegociation disabled",
 			     dev->data->port_id);
 		return -EINVAL;
 	}
@@ -1470,6 +1461,13 @@ i40e_dev_start(struct rte_eth_dev *dev)
 	}
 
 	/* Apply link configure */
+	if (dev->data->dev_conf.link_speeds & ~(ETH_LINK_SPEED_100M |
+				ETH_LINK_SPEED_1G | ETH_LINK_SPEED_10G |
+				ETH_LINK_SPEED_20G | ETH_LINK_SPEED_40G)) {
+		PMD_DRV_LOG(ERR, "Invalid link setting");
+		goto err_up;
+	}
+
 	ret = i40e_apply_link_speed(dev);
 	if (I40E_SUCCESS != ret) {
 		PMD_DRV_LOG(ERR, "Fail to apply link setting");
@@ -1713,7 +1711,7 @@ i40e_dev_link_update(struct rte_eth_dev *dev,
 		/* Get link status information from hardware */
 		status = i40e_aq_get_link_info(hw, false, &link_status, NULL);
 		if (status != I40E_SUCCESS) {
-			link.link_speed = ETH_LINK_SPEED_100;
+			link.link_speed = ETH_SPEED_NUM_100M;
 			link.link_duplex = ETH_LINK_FULL_DUPLEX;
 			PMD_DRV_LOG(ERR, "Failed to get link info");
 			goto out;
@@ -1735,25 +1733,28 @@ i40e_dev_link_update(struct rte_eth_dev *dev,
 	/* Parse the link status */
 	switch (link_status.link_speed) {
 	case I40E_LINK_SPEED_100MB:
-		link.link_speed = ETH_LINK_SPEED_100;
+		link.link_speed = ETH_SPEED_NUM_100M;
 		break;
 	case I40E_LINK_SPEED_1GB:
-		link.link_speed = ETH_LINK_SPEED_1000;
+		link.link_speed = ETH_SPEED_NUM_1G;
 		break;
 	case I40E_LINK_SPEED_10GB:
-		link.link_speed = ETH_LINK_SPEED_10G;
+		link.link_speed = ETH_SPEED_NUM_10G;
 		break;
 	case I40E_LINK_SPEED_20GB:
-		link.link_speed = ETH_LINK_SPEED_20G;
+		link.link_speed = ETH_SPEED_NUM_20G;
 		break;
 	case I40E_LINK_SPEED_40GB:
-		link.link_speed = ETH_LINK_SPEED_40G;
+		link.link_speed = ETH_SPEED_NUM_40G;
 		break;
 	default:
-		link.link_speed = ETH_LINK_SPEED_100;
+		link.link_speed = ETH_SPEED_NUM_100M;
 		break;
 	}
 
+	link.link_autoneg = ~(dev->data->dev_conf.link_speeds &
+						ETH_LINK_SPEED_NO_AUTONEG);
+
 out:
 	rte_i40e_dev_atomic_write_link_status(dev, &link);
 	if (link.link_status == old.link_status)
@@ -2308,10 +2309,10 @@ i40e_dev_info_get(struct rte_eth_dev *dev, struct rte_eth_dev_info *dev_info)
 
 	if (i40e_is_40G_device(hw->device_id))
 		/* For XL710 */
-		dev_info->speed_capa = ETH_SPEED_CAP_1G | ETH_SPEED_CAP_10G;
+		dev_info->speed_capa = ETH_LINK_SPEED_1G | ETH_LINK_SPEED_10G;
 	else
 		/* For X710 */
-		dev_info->speed_capa = ETH_SPEED_CAP_10G | ETH_SPEED_CAP_40G;
+		dev_info->speed_capa = ETH_LINK_SPEED_10G | ETH_LINK_SPEED_40G;
 
 }
 
@@ -7835,15 +7836,15 @@ i40e_start_timecounters(struct rte_eth_dev *dev)
 	rte_i40e_dev_atomic_read_link_status(dev, &link);
 
 	switch (link.link_speed) {
-	case ETH_LINK_SPEED_40G:
+	case ETH_SPEED_NUM_40G:
 		tsync_inc_l = I40E_PTP_40GB_INCVAL & 0xFFFFFFFF;
 		tsync_inc_h = I40E_PTP_40GB_INCVAL >> 32;
 		break;
-	case ETH_LINK_SPEED_10G:
+	case ETH_SPEED_NUM_10G:
 		tsync_inc_l = I40E_PTP_10GB_INCVAL & 0xFFFFFFFF;
 		tsync_inc_h = I40E_PTP_10GB_INCVAL >> 32;
 		break;
-	case ETH_LINK_SPEED_1000:
+	case ETH_SPEED_NUM_1G:
 		tsync_inc_l = I40E_PTP_1GB_INCVAL & 0xFFFFFFFF;
 		tsync_inc_h = I40E_PTP_1GB_INCVAL >> 32;
 		break;
diff --git a/drivers/net/i40e/i40e_ethdev_vf.c b/drivers/net/i40e/i40e_ethdev_vf.c
index 14d2a50..f06f828 100644
--- a/drivers/net/i40e/i40e_ethdev_vf.c
+++ b/drivers/net/i40e/i40e_ethdev_vf.c
@@ -1911,13 +1911,14 @@ i40evf_dev_link_update(struct rte_eth_dev *dev,
 	 * DPDK pf host provide interfacet to acquire link status
 	 * while Linux driver does not
 	 */
-	if (vf->version_major == I40E_DPDK_VERSION_MAJOR)
+	if (vf->version_major == I40E_DPDK_VERSION_MAJOR) {
 		i40evf_get_link_status(dev, &new_link);
-	else {
+	} else {
 		/* Always assume it's up, for Linux driver PF host */
-		new_link.link_duplex = ETH_LINK_AUTONEG_DUPLEX;
-		new_link.link_speed  = ETH_LINK_SPEED_10000;
-		new_link.link_status = 1;
+		new_link.link_speed  = ETH_SPEED_NUM_10G;
+		new_link.link_duplex = ETH_LINK_FULL_DUPLEX;
+		new_link.link_autoneg = ETH_LINK_SPEED_NEG;
+		new_link.link_status = ETH_LINK_UP;
 	}
 	i40evf_dev_atomic_write_link_status(dev, &new_link);
 
diff --git a/drivers/net/ixgbe/ixgbe_ethdev.c b/drivers/net/ixgbe/ixgbe_ethdev.c
index 4e3ab3d..14a03e1 100644
--- a/drivers/net/ixgbe/ixgbe_ethdev.c
+++ b/drivers/net/ixgbe/ixgbe_ethdev.c
@@ -1979,14 +1979,13 @@ ixgbe_dev_start(struct rte_eth_dev *dev)
 	int mask = 0;
 	int status;
 	uint16_t vf, idx;
+	uint32_t *link_speeds;
 
 	PMD_INIT_FUNC_TRACE();
 
 	/* IXGBE devices don't support half duplex */
-	if ((dev->data->dev_conf.link_duplex != ETH_LINK_AUTONEG_DUPLEX) &&
-			(dev->data->dev_conf.link_duplex != ETH_LINK_FULL_DUPLEX)) {
-		PMD_INIT_LOG(ERR, "Invalid link_duplex (%hu) for port %hhu",
-			     dev->data->dev_conf.link_duplex,
+	if (dev->data->dev_conf.link_speeds & ETH_LINK_SPEED_NO_AUTONEG) {
+		PMD_INIT_LOG(ERR, "Invalid link_speeds for port %hhu; autonegociation disabled",
 			     dev->data->port_id);
 		return -EINVAL;
 	}
@@ -2076,32 +2075,22 @@ ixgbe_dev_start(struct rte_eth_dev *dev)
 	if (err)
 		goto error;
 
-	switch(dev->data->dev_conf.link_speed) {
-	case ETH_LINK_SPEED_AUTONEG:
-		speed = (hw->mac.type != ixgbe_mac_82598EB) ?
-				IXGBE_LINK_SPEED_82599_AUTONEG :
-				IXGBE_LINK_SPEED_82598_AUTONEG;
-		break;
-	case ETH_LINK_SPEED_100:
-		/*
-		 * Invalid for 82598 but error will be detected by
-		 * ixgbe_setup_link()
-		 */
-		speed = IXGBE_LINK_SPEED_100_FULL;
-		break;
-	case ETH_LINK_SPEED_1000:
-		speed = IXGBE_LINK_SPEED_1GB_FULL;
-		break;
-	case ETH_LINK_SPEED_10000:
-		speed = IXGBE_LINK_SPEED_10GB_FULL;
-		break;
-	default:
-		PMD_INIT_LOG(ERR, "Invalid link_speed (%hu) for port %hhu",
-			     dev->data->dev_conf.link_speed,
-			     dev->data->port_id);
+	link_speeds = &dev->data->dev_conf.link_speeds;
+	if (*link_speeds & ~(ETH_LINK_SPEED_100M | ETH_LINK_SPEED_1G |
+							ETH_LINK_SPEED_10G)) {
+		PMD_INIT_LOG(ERR, "Invalid link setting");
 		goto error;
 	}
 
+	speed = 0x0;
+
+	if (*link_speeds & ETH_LINK_SPEED_10G)
+		speed |= IXGBE_LINK_SPEED_10GB_FULL;
+	if (*link_speeds & ETH_LINK_SPEED_1G)
+		speed |= IXGBE_LINK_SPEED_1GB_FULL;
+	if (*link_speeds & ETH_LINK_SPEED_100M)
+		speed |= IXGBE_LINK_SPEED_100_FULL;
+
 	err = ixgbe_setup_link(hw, speed, link_up);
 	if (err)
 		goto error;
@@ -2828,15 +2817,16 @@ ixgbe_dev_info_get(struct rte_eth_dev *dev, struct rte_eth_dev_info *dev_info)
 	dev_info->reta_size = ixgbe_reta_size_get(hw->mac.type);
 	dev_info->flow_type_rss_offloads = IXGBE_RSS_OFFLOAD_ALL;
 
-	dev_info->speed_capa = ETH_SPEED_CAP_1G | ETH_SPEED_CAP_10G;
+	dev_info->speed_capa = ETH_LINK_SPEED_1G | ETH_LINK_SPEED_10G;
 
 	if (hw->mac.type == ixgbe_mac_X540 ||
 	    hw->mac.type == ixgbe_mac_X540_vf ||
 	    hw->mac.type == ixgbe_mac_X550 ||
-	    hw->mac.type == ixgbe_mac_X550_vf)
+	    hw->mac.type == ixgbe_mac_X550_vf) {
 
-		dev_info->speed_capa |= ETH_SPEED_CAP_100M_FD /*|
-					ETH_SPEED_CAP_100M_HD*/;
+		dev_info->speed_capa |= ETH_LINK_SPEED_100M /*|
+					ETH_LINK_SPEED_100M_HD*/;
+	}
 }
 
 static void
@@ -2903,9 +2893,9 @@ ixgbe_dev_link_update(struct rte_eth_dev *dev, int wait_to_complete)
 	int link_up;
 	int diag;
 
-	link.link_status = 0;
+	link.link_status = ETH_LINK_DOWN;
 	link.link_speed = 0;
-	link.link_duplex = 0;
+	link.link_duplex = ETH_LINK_HALF_DUPLEX;
 	memset(&old, 0, sizeof(old));
 	rte_ixgbe_dev_atomic_read_link_status(dev, &old);
 
@@ -2918,8 +2908,8 @@ ixgbe_dev_link_update(struct rte_eth_dev *dev, int wait_to_complete)
 		diag = ixgbe_check_link(hw, &link_speed, &link_up, 1);
 
 	if (diag != 0) {
-		link.link_speed = ETH_LINK_SPEED_100;
-		link.link_duplex = ETH_LINK_HALF_DUPLEX;
+		link.link_speed = ETH_SPEED_NUM_100M;
+		link.link_duplex = ETH_LINK_FULL_DUPLEX;
 		rte_ixgbe_dev_atomic_write_link_status(dev, &link);
 		if (link.link_status == old.link_status)
 			return -1;
@@ -2932,26 +2922,26 @@ ixgbe_dev_link_update(struct rte_eth_dev *dev, int wait_to_complete)
 			return -1;
 		return 0;
 	}
-	link.link_status = 1;
+	link.link_status = ETH_LINK_UP;
 	link.link_duplex = ETH_LINK_FULL_DUPLEX;
 
 	switch (link_speed) {
 	default:
 	case IXGBE_LINK_SPEED_UNKNOWN:
-		link.link_duplex = ETH_LINK_HALF_DUPLEX;
-		link.link_speed = ETH_LINK_SPEED_100;
+		link.link_duplex = ETH_LINK_FULL_DUPLEX;
+		link.link_speed = ETH_SPEED_NUM_100M;
 		break;
 
 	case IXGBE_LINK_SPEED_100_FULL:
-		link.link_speed = ETH_LINK_SPEED_100;
+		link.link_speed = ETH_SPEED_NUM_100M;
 		break;
 
 	case IXGBE_LINK_SPEED_1GB_FULL:
-		link.link_speed = ETH_LINK_SPEED_1000;
+		link.link_speed = ETH_SPEED_NUM_1G;
 		break;
 
 	case IXGBE_LINK_SPEED_10GB_FULL:
-		link.link_speed = ETH_LINK_SPEED_10000;
+		link.link_speed = ETH_SPEED_NUM_10G;
 		break;
 	}
 	rte_ixgbe_dev_atomic_write_link_status(dev, &link);
@@ -5725,15 +5715,15 @@ ixgbe_start_timecounters(struct rte_eth_dev *dev)
 	rte_ixgbe_dev_atomic_read_link_status(dev, &link);
 
 	switch (link.link_speed) {
-	case ETH_LINK_SPEED_100:
+	case ETH_SPEED_NUM_100M:
 		incval = IXGBE_INCVAL_100;
 		shift = IXGBE_INCVAL_SHIFT_100;
 		break;
-	case ETH_LINK_SPEED_1000:
+	case ETH_SPEED_NUM_1G:
 		incval = IXGBE_INCVAL_1GB;
 		shift = IXGBE_INCVAL_SHIFT_1GB;
 		break;
-	case ETH_LINK_SPEED_10000:
+	case ETH_SPEED_NUM_10G:
 	default:
 		incval = IXGBE_INCVAL_10GB;
 		shift = IXGBE_INCVAL_SHIFT_10GB;
diff --git a/drivers/net/mlx4/mlx4.c b/drivers/net/mlx4/mlx4.c
index 1f3ed59..4dbc8a9 100644
--- a/drivers/net/mlx4/mlx4.c
+++ b/drivers/net/mlx4/mlx4.c
@@ -4637,6 +4637,8 @@ mlx4_link_update_unlocked(struct rte_eth_dev *dev, int wait_to_complete)
 		dev_link.link_speed = link_speed;
 	dev_link.link_duplex = ((edata.duplex == DUPLEX_HALF) ?
 				ETH_LINK_HALF_DUPLEX : ETH_LINK_FULL_DUPLEX);
+	dev_link.link_autoneg = ~(dev->data->dev_conf.link_speeds &
+						ETH_LINK_SPEED_NO_AUTONEG);
 	if (memcmp(&dev_link, &dev->data->dev_link, sizeof(dev_link))) {
 		/* Link status changed. */
 		dev->data->dev_link = dev_link;
diff --git a/drivers/net/mpipe/mpipe_tilegx.c b/drivers/net/mpipe/mpipe_tilegx.c
index 35134ba..f42c1d4 100644
--- a/drivers/net/mpipe/mpipe_tilegx.c
+++ b/drivers/net/mpipe/mpipe_tilegx.c
@@ -388,14 +388,16 @@ mpipe_link_update(struct rte_eth_dev *dev, int wait_to_complete)
 
 		speed = state & GXIO_MPIPE_LINK_SPEED_MASK;
 
+		new.link_autoneg = ~(dev->data->dev_conf.link_speeds &
+						ETH_LINK_SPEED_NO_AUTONEG);
 		if (speed == GXIO_MPIPE_LINK_1G) {
 			new.link_speed = ETH_LINK_SPEED_1000;
 			new.link_duplex = ETH_LINK_FULL_DUPLEX;
-			new.link_status = 1;
+			new.link_status = ETH_LINK_UP;
 		} else if (speed == GXIO_MPIPE_LINK_10G) {
 			new.link_speed = ETH_LINK_SPEED_10000;
 			new.link_duplex = ETH_LINK_FULL_DUPLEX;
-			new.link_status = 1;
+			new.link_status = ETH_LINK_UP;
 		}
 
 		rc = mpipe_link_compare(&old, &new);
diff --git a/drivers/net/null/rte_eth_null.c b/drivers/net/null/rte_eth_null.c
index 77fc988..55e1fc8 100644
--- a/drivers/net/null/rte_eth_null.c
+++ b/drivers/net/null/rte_eth_null.c
@@ -93,9 +93,10 @@ struct pmd_internals {
 static struct ether_addr eth_addr = { .addr_bytes = {0} };
 static const char *drivername = "Null PMD";
 static struct rte_eth_link pmd_link = {
-	.link_speed = 10000,
+	.link_speed = ETH_SPEED_NUM_10G,
 	.link_duplex = ETH_LINK_FULL_DUPLEX,
-	.link_status = 0
+	.link_status = ETH_LINK_DOWN,
+	.link_autoneg = ETH_LINK_SPEED_NEG,
 };
 
 static uint16_t
diff --git a/drivers/net/pcap/rte_eth_pcap.c b/drivers/net/pcap/rte_eth_pcap.c
index f9230eb..650b521 100644
--- a/drivers/net/pcap/rte_eth_pcap.c
+++ b/drivers/net/pcap/rte_eth_pcap.c
@@ -125,9 +125,10 @@ static int open_single_iface(const char *iface, pcap_t **pcap);
 static struct ether_addr eth_addr = { .addr_bytes = { 0, 0, 0, 0x1, 0x2, 0x3 } };
 static const char *drivername = "Pcap PMD";
 static struct rte_eth_link pmd_link = {
-		.link_speed = 10000,
+		.link_speed = ETH_SPEED_NUM_10G,
 		.link_duplex = ETH_LINK_FULL_DUPLEX,
-		.link_status = 0
+		.link_status = ETH_LINK_DOWN,
+		.link_autoneg = ETH_LINK_SPEED_FIXED,
 };
 
 static int
@@ -430,7 +431,7 @@ eth_dev_start(struct rte_eth_dev *dev)
 
 status_up:
 
-	dev->data->dev_link.link_status = 1;
+	dev->data->dev_link.link_status = ETH_LINK_UP;
 	return 0;
 }
 
@@ -481,7 +482,7 @@ eth_dev_stop(struct rte_eth_dev *dev)
 	}
 
 status_down:
-	dev->data->dev_link.link_status = 0;
+	dev->data->dev_link.link_status = ETH_LINK_DOWN;
 }
 
 static int
diff --git a/drivers/net/ring/rte_eth_ring.c b/drivers/net/ring/rte_eth_ring.c
index d92b088..043175a 100644
--- a/drivers/net/ring/rte_eth_ring.c
+++ b/drivers/net/ring/rte_eth_ring.c
@@ -71,9 +71,10 @@ struct pmd_internals {
 
 static const char *drivername = "Rings PMD";
 static struct rte_eth_link pmd_link = {
-		.link_speed = 10000,
+		.link_speed = ETH_SPEED_NUM_10G,
 		.link_duplex = ETH_LINK_FULL_DUPLEX,
-		.link_status = 0
+		.link_status = ETH_LINK_DOWN,
+		.link_autoneg = ETH_LINK_SPEED_NEG
 };
 
 static uint16_t
diff --git a/drivers/net/virtio/virtio_ethdev.c b/drivers/net/virtio/virtio_ethdev.c
index d928339..83a2ffe 100644
--- a/drivers/net/virtio/virtio_ethdev.c
+++ b/drivers/net/virtio/virtio_ethdev.c
@@ -1631,7 +1631,7 @@ virtio_dev_link_update(struct rte_eth_dev *dev, __rte_unused int wait_to_complet
 	memset(&link, 0, sizeof(link));
 	virtio_dev_atomic_read_link_status(dev, &link);
 	old = link;
-	link.link_duplex = FULL_DUPLEX;
+	link.link_duplex = ETH_LINK_FULL_DUPLEX;
 	link.link_speed  = SPEED_10G;
 
 	if (vtpci_with_feature(hw, VIRTIO_NET_F_STATUS)) {
diff --git a/drivers/net/virtio/virtio_ethdev.h b/drivers/net/virtio/virtio_ethdev.h
index ae2d47d..8598815 100644
--- a/drivers/net/virtio/virtio_ethdev.h
+++ b/drivers/net/virtio/virtio_ethdev.h
@@ -42,8 +42,6 @@
 #define SPEED_100	100
 #define SPEED_1000	1000
 #define SPEED_10G	10000
-#define HALF_DUPLEX	1
-#define FULL_DUPLEX	2
 
 #ifndef PAGE_SIZE
 #define PAGE_SIZE 4096
diff --git a/drivers/net/vmxnet3/vmxnet3_ethdev.c b/drivers/net/vmxnet3/vmxnet3_ethdev.c
index c363bf6..2bb6ee9 100644
--- a/drivers/net/vmxnet3/vmxnet3_ethdev.c
+++ b/drivers/net/vmxnet3/vmxnet3_ethdev.c
@@ -736,9 +736,10 @@ vmxnet3_dev_link_update(struct rte_eth_dev *dev, __attribute__((unused)) int wai
 	ret = VMXNET3_READ_BAR1_REG(hw, VMXNET3_REG_CMD);
 
 	if (ret & 0x1) {
-		link.link_status = 1;
+		link.link_status = ETH_LINK_UP;
 		link.link_duplex = ETH_LINK_FULL_DUPLEX;
-		link.link_speed = ETH_LINK_SPEED_10000;
+		link.link_speed = ETH_SPEED_NUM_10G;
+		link.link_autoneg = ETH_LINK_SPEED_FIXED;
 	}
 
 	vmxnet3_dev_atomic_write_link_status(dev, &link);
diff --git a/drivers/net/xenvirt/rte_eth_xenvirt.c b/drivers/net/xenvirt/rte_eth_xenvirt.c
index 3f31806..0fcf5d3 100644
--- a/drivers/net/xenvirt/rte_eth_xenvirt.c
+++ b/drivers/net/xenvirt/rte_eth_xenvirt.c
@@ -70,9 +70,10 @@ static int virtio_idx = 0;
 static const char *drivername = "xen virtio PMD";
 
 static struct rte_eth_link pmd_link = {
-		.link_speed = 10000,
+		.link_speed = ETH_SPEED_NUM_10G,
 		.link_duplex = ETH_LINK_FULL_DUPLEX,
-		.link_status = 0
+		.link_status = ETH_LINK_DOWN,
+		.link_autoneg = ETH_LINK_SPEED_FIXED
 };
 
 static void
diff --git a/examples/ip_pipeline/config_parse.c b/examples/ip_pipeline/config_parse.c
index 1bedbe4..c581d41 100644
--- a/examples/ip_pipeline/config_parse.c
+++ b/examples/ip_pipeline/config_parse.c
@@ -84,8 +84,7 @@ static const struct app_link_params link_params_default = {
 	.mac_addr = 0,
 
 	.conf = {
-		.link_speed = 0,
-		.link_duplex = 0,
+		.link_speeds = 0,
 		.rxmode = {
 			.mq_mode = ETH_MQ_RX_NONE,
 
diff --git a/lib/librte_ether/rte_ethdev.c b/lib/librte_ether/rte_ethdev.c
index 756b234..7b0214d 100644
--- a/lib/librte_ether/rte_ethdev.c
+++ b/lib/librte_ether/rte_ethdev.c
@@ -865,6 +865,55 @@ rte_eth_dev_tx_queue_config(struct rte_eth_dev *dev, uint16_t nb_queues)
 }
 
 int
+rte_eth_speed_to_bm_flag(uint32_t speed, int duplex, uint32_t *flag)
+{
+	switch (speed) {
+	case ETH_SPEED_NUM_10M:
+		*flag = (duplex) ? ETH_LINK_SPEED_10M :
+							ETH_LINK_SPEED_10M_HD;
+		break;
+	case ETH_SPEED_NUM_100M:
+		*flag = (duplex) ? ETH_LINK_SPEED_100M :
+							ETH_LINK_SPEED_100M_HD;
+		break;
+	case ETH_SPEED_NUM_1G:
+		*flag = ETH_LINK_SPEED_1G;
+		break;
+	case ETH_SPEED_NUM_2_5G:
+		*flag = ETH_LINK_SPEED_2_5G;
+		break;
+	case ETH_SPEED_NUM_5G:
+		*flag = ETH_LINK_SPEED_5G;
+		break;
+	case ETH_SPEED_NUM_10G:
+		*flag = ETH_LINK_SPEED_10G;
+		break;
+	case ETH_SPEED_NUM_20G:
+		*flag = ETH_LINK_SPEED_20G;
+		break;
+	case ETH_SPEED_NUM_25G:
+		*flag = ETH_LINK_SPEED_25G;
+		break;
+	case ETH_SPEED_NUM_40G:
+		*flag = ETH_LINK_SPEED_40G;
+		break;
+	case ETH_SPEED_NUM_50G:
+		*flag = ETH_LINK_SPEED_50G;
+		break;
+	case ETH_SPEED_NUM_56G:
+		*flag = ETH_LINK_SPEED_56G;
+		break;
+	case ETH_SPEED_NUM_100G:
+		*flag = ETH_LINK_SPEED_100G;
+		break;
+	default:
+		return -EINVAL;
+	}
+
+	return 0;
+}
+
+int
 rte_eth_dev_configure(uint8_t port_id, uint16_t nb_rx_q, uint16_t nb_tx_q,
 		      const struct rte_eth_conf *dev_conf)
 {
diff --git a/lib/librte_ether/rte_ethdev.h b/lib/librte_ether/rte_ethdev.h
index dbc1599..9b32de5 100644
--- a/lib/librte_ether/rte_ethdev.h
+++ b/lib/librte_ether/rte_ethdev.h
@@ -242,26 +242,59 @@ struct rte_eth_stats {
 };
 
 /**
+ * Device supported speeds bitmap flags
+ */
+#define ETH_LINK_SPEED_AUTONEG		(0 << 0)  /*< Autonegociate (all speeds)  */
+#define ETH_LINK_SPEED_NO_AUTONEG	(1 << 0)  /*< Disable autoneg (fixed speed)  */
+#define ETH_LINK_SPEED_10M_HD		(1 << 1)  /*< 10 Mbps half-duplex */
+#define ETH_LINK_SPEED_10M		(1 << 2)  /*< 10 Mbps full-duplex */
+#define ETH_LINK_SPEED_100M_HD		(1 << 3)  /*< 100 Mbps half-duplex */
+#define ETH_LINK_SPEED_100M		(1 << 4)  /*< 100 Mbps full-duplex */
+#define ETH_LINK_SPEED_1G		(1 << 5)  /*< 1 Gbps */
+#define ETH_LINK_SPEED_2_5G		(1 << 6)  /*< 2.5 Gbps */
+#define ETH_LINK_SPEED_5G		(1 << 7)  /*< 5 Gbps */
+#define ETH_LINK_SPEED_10G		(1 << 8)  /*< 10 Mbps */
+#define ETH_LINK_SPEED_20G		(1 << 9)  /*< 20 Gbps */
+#define ETH_LINK_SPEED_25G		(1 << 10)  /*< 25 Gbps */
+#define ETH_LINK_SPEED_40G		(1 << 11)  /*< 40 Gbps */
+#define ETH_LINK_SPEED_50G		(1 << 12)  /*< 50 Gbps */
+#define ETH_LINK_SPEED_56G		(1 << 13)  /*< 56 Gbps */
+#define ETH_LINK_SPEED_100G		(1 << 14)  /*< 100 Gbps */
+
+/**
+ * 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 Mbps */
+#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 */
+
+/**
  * A structure used to retrieve link-level information of an Ethernet port.
  */
 struct rte_eth_link {
-	uint16_t link_speed;      /**< ETH_LINK_SPEED_[10, 100, 1000, 10000] */
-	uint16_t link_duplex;     /**< ETH_LINK_[HALF_DUPLEX, FULL_DUPLEX] */
-	uint8_t  link_status : 1; /**< 1 -> link up, 0 -> link down */
-}__attribute__((aligned(8)));     /**< aligned for atomic64 read/write */
-
-#define ETH_LINK_SPEED_AUTONEG  0       /**< Auto-negotiate link speed. */
-#define ETH_LINK_SPEED_10       10      /**< 10 megabits/second. */
-#define ETH_LINK_SPEED_100      100     /**< 100 megabits/second. */
-#define ETH_LINK_SPEED_1000     1000    /**< 1 gigabits/second. */
-#define ETH_LINK_SPEED_10000    10000   /**< 10 gigabits/second. */
-#define ETH_LINK_SPEED_10G      10000   /**< alias of 10 gigabits/second. */
-#define ETH_LINK_SPEED_20G      20000   /**< 20 gigabits/second. */
-#define ETH_LINK_SPEED_40G      40000   /**< 40 gigabits/second. */
+	uint32_t link_speed;        /**< Link speed (ETH_SPEED_NUM_) */
+	uint16_t link_duplex  : 1;  /**< 1 -> full duplex, 0 -> half duplex */
+	uint16_t link_autoneg : 1;  /**< 1 -> link speed has been autoneg */
+	uint16_t link_status  : 1;  /**< 1 -> link up, 0 -> link down */
+} __attribute__((aligned(8)));      /**< aligned for atomic64 read/write */
 
-#define ETH_LINK_AUTONEG_DUPLEX 0       /**< Auto-negotiate duplex. */
-#define ETH_LINK_HALF_DUPLEX    1       /**< Half-duplex connection. */
-#define ETH_LINK_FULL_DUPLEX    2       /**< Full-duplex connection. */
+/* Utility constants */
+#define ETH_LINK_HALF_DUPLEX    0	/**< Half-duplex connection. */
+#define ETH_LINK_FULL_DUPLEX    1	/**< Full-duplex connection. */
+#define ETH_LINK_SPEED_FIXED    0	/**< Link speed was not autonegociated. */
+#define ETH_LINK_SPEED_NEG      1	/**< Link speed was autonegociated. */
+#define ETH_LINK_DOWN		0	/**< Link is down. */
+#define ETH_LINK_UP		1	/**< Link is up. */
 
 /**
  * A structure used to configure the ring threshold registers of an RX/TX
@@ -760,10 +793,14 @@ struct rte_intr_conf {
  * configuration settings may be needed.
  */
 struct rte_eth_conf {
-	uint16_t link_speed;
-	/**< ETH_LINK_SPEED_10[0|00|000], or 0 for autonegotation */
-	uint16_t link_duplex;
-	/**< ETH_LINK_[HALF_DUPLEX|FULL_DUPLEX], or 0 for autonegotation */
+	uint32_t link_speeds; /**< bitmap of ETH_LINK_SPEED_XXX of speeds to be
+				used. ETH_LINK_SPEED_NO_AUTONEG disables link
+				autonegociation, and a unique speed shall be
+				set. Otherwise, the bitmap defines the set of
+				speeds to be advertised. If the special value
+				ETH_LINK_SPEED_AUTONEG (0) is used, all speeds
+				supported are advertised.
+				*/
 	struct rte_eth_rxmode rxmode; /**< Port RX configuration. */
 	struct rte_eth_txmode txmode; /**< Port TX configuration. */
 	uint32_t lpbk_mode; /**< Loopback operation mode. By default the value
@@ -825,26 +862,6 @@ struct rte_eth_conf {
 #define DEV_TX_OFFLOAD_QINQ_INSERT 0x00000100
 
 /**
- * Device supported speeds
- */
-#define ETH_SPEED_CAP_NOT_PHY	(0)  /*< No phy media > */
-#define ETH_SPEED_CAP_10M_HD	(1 << 0)  /*< 10 Mbps half-duplex> */
-#define ETH_SPEED_CAP_10M_FD	(1 << 1)  /*< 10 Mbps full-duplex> */
-#define ETH_SPEED_CAP_100M_HD	(1 << 2)  /*< 100 Mbps half-duplex> */
-#define ETH_SPEED_CAP_100M_FD	(1 << 3)  /*< 100 Mbps full-duplex> */
-#define ETH_SPEED_CAP_1G	(1 << 4)  /*< 1 Gbps > */
-#define ETH_SPEED_CAP_2_5G	(1 << 5)  /*< 2.5 Gbps > */
-#define ETH_SPEED_CAP_5G	(1 << 6)  /*< 5 Gbps > */
-#define ETH_SPEED_CAP_10G	(1 << 7)  /*< 10 Mbps > */
-#define ETH_SPEED_CAP_20G	(1 << 8)  /*< 20 Gbps > */
-#define ETH_SPEED_CAP_25G	(1 << 9)  /*< 25 Gbps > */
-#define ETH_SPEED_CAP_40G	(1 << 10)  /*< 40 Gbps > */
-#define ETH_SPEED_CAP_50G	(1 << 11)  /*< 50 Gbps > */
-#define ETH_SPEED_CAP_56G	(1 << 12)  /*< 56 Gbps > */
-#define ETH_SPEED_CAP_100G	(1 << 13)  /*< 100 Gbps > */
-
-
-/**
  * Ethernet device information
  */
 struct rte_eth_dev_info {
@@ -1811,6 +1828,22 @@ struct eth_driver {
 void rte_eth_driver_register(struct eth_driver *eth_drv);
 
 /**
+ * Convert a numerical speed in Mbps to a bitmap flag that can be used in
+ * the bitmap link_speeds of the struct rte_eth_conf
+ *
+ * @param
+ *   Numerical speed value in Mbps
+ * @param
+ *   Boolean is duplex (only for 10/100 speeds)
+ * @param
+ *   On success, the converted speed into a bitmap flag
+ * @return
+ *   0 on success, -EINVAL if the speed cannot be mapped
+ */
+extern int rte_eth_speed_to_bm_flag(uint32_t speed, int duplex,
+							uint32_t *flag);
+
+/**
  * Configure an Ethernet device.
  * This function must be invoked first before any other function in the
  * Ethernet API. This function can also be re-invoked when a device is in the
-- 
2.1.4

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

* [PATCH v7 4/5] doc: update with link changes
  2016-01-29  0:42   ` [PATCH v7 " Marc Sune
                       ` (2 preceding siblings ...)
  2016-01-29  0:42     ` [PATCH v7 3/5] ethdev: redesign link speed config API Marc Sune
@ 2016-01-29  0:42     ` Marc Sune
  2016-01-29  0:42     ` [PATCH v7 5/5] ethdev: add rte_eth_speed_to_bm_flag() to ver. map Marc Sune
  2016-02-14 22:17     ` [PATCH v8 0/4] ethdev: add speed capabilities and refactor link API Marc Sune
  5 siblings, 0 replies; 167+ messages in thread
From: Marc Sune @ 2016-01-29  0:42 UTC (permalink / raw)
  To: dev, Wenzhuo Lu, Helin Zhang, Harish Patil, Jing Chen

Add new features, ABI changes and resolved issues notice for
the refactored link patch.

Signed-off-by: Marc Sune <marcdevel@gmail.com>
---
 doc/guides/rel_notes/release_2_3.rst | 26 ++++++++++++++++++++++++++
 1 file changed, 26 insertions(+)

diff --git a/doc/guides/rel_notes/release_2_3.rst b/doc/guides/rel_notes/release_2_3.rst
index 99de186..b10c3bb 100644
--- a/doc/guides/rel_notes/release_2_3.rst
+++ b/doc/guides/rel_notes/release_2_3.rst
@@ -4,10 +4,28 @@ DPDK Release 2.3
 New Features
 ------------
 
+* **ethdev: define a set of advertised link speeds.**
+
+  Allowing to define a set of advertised speeds for auto-negociation,
+  explicitely disable link auto-negociation (single speed) and full
+  auto-negociation.
+
+* **ethdev: add speed_cap bitmap to recover eth device link speed capabilities
+  define a set of advertised link speeds.**
+
+  ``struct rte_eth_dev_info`` has now speed_cap bitmap, which allows the
+  application to recover the supported speeds for that ethernet device.
+
 
 Resolved Issues
 ---------------
 
+* **ethdev: Fixed link_speed overflow in rte_eth_link for 100Gbps.**
+
+  100Gbps in Mbps (100000) exceeds 16 bit max value of ``link_speed`` in
+  ``rte_eth_link``.
+
+
 EAL
 ~~~
 
@@ -23,6 +41,9 @@ Libraries
 Examples
 ~~~~~~~~
 
+* New API call, rte_eth_speed_to_bm_flag(), in ethdev to map numerical speeds
+  to bitmap fields.
+
 
 Other
 ~~~~~
@@ -39,6 +60,11 @@ API Changes
 ABI Changes
 -----------
 
+* The ethdev rte_eth_link and rte_eth_conf structures were changed to
+  support the new link API, as well as ETH_LINK_HALF/FULL_DUPLEX.
+
+* The ethdev rte_eth_dev_info was changed to support device speed capabilities.
+
 
 Shared Library Versions
 -----------------------
-- 
2.1.4

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

* [PATCH v7 5/5] ethdev: add rte_eth_speed_to_bm_flag() to ver. map
  2016-01-29  0:42   ` [PATCH v7 " Marc Sune
                       ` (3 preceding siblings ...)
  2016-01-29  0:42     ` [PATCH v7 4/5] doc: update with link changes Marc Sune
@ 2016-01-29  0:42     ` Marc Sune
  2016-01-29 13:05       ` Panu Matilainen
  2016-02-14 22:17     ` [PATCH v8 0/4] ethdev: add speed capabilities and refactor link API Marc Sune
  5 siblings, 1 reply; 167+ messages in thread
From: Marc Sune @ 2016-01-29  0:42 UTC (permalink / raw)
  To: dev, Wenzhuo Lu, Helin Zhang, Harish Patil, Jing Chen

Added rte_eth_speed_to_bm_flag() to DPDK2.2 version map.

Signed-off-by: Marc Sune <marcdevel@gmail.com>
---
 lib/librte_ether/rte_ether_version.map | 6 ++++++
 1 file changed, 6 insertions(+)

diff --git a/lib/librte_ether/rte_ether_version.map b/lib/librte_ether/rte_ether_version.map
index d8db24d..2c14ad7 100644
--- a/lib/librte_ether/rte_ether_version.map
+++ b/lib/librte_ether/rte_ether_version.map
@@ -117,3 +117,9 @@ DPDK_2.2 {
 
 	local: *;
 };
+
+DPDK_2.3 {
+	global:
+
+	rte_eth_speed_to_bm_flag;
+}DPDK_2.2;
-- 
2.1.4

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

* Re: [PATCH v7 3/5] ethdev: redesign link speed config API
  2016-01-29  0:42     ` [PATCH v7 3/5] ethdev: redesign link speed config API Marc Sune
@ 2016-01-29  9:24       ` Ananyev, Konstantin
  2016-01-29  9:37         ` Thomas Monjalon
  2016-01-29 16:16       ` Nélio Laranjeiro
  1 sibling, 1 reply; 167+ messages in thread
From: Ananyev, Konstantin @ 2016-01-29  9:24 UTC (permalink / raw)
  To: Marc Sune, dev, Lu, Wenzhuo, Zhang, Helin, Harish Patil, Chen, Jing D

Hi Marc,

> -----Original Message-----
> From: dev [mailto:dev-bounces@dpdk.org] On Behalf Of Marc Sune
> Sent: Friday, January 29, 2016 12:42 AM
> To: dev@dpdk.org; Lu, Wenzhuo; Zhang, Helin; Harish Patil; Chen, Jing D
> Subject: [dpdk-dev] [PATCH v7 3/5] ethdev: redesign link speed config API
> 
> This patch redesigns the API to set the link speed/s configure
> for an ethernet port. Specifically:
> 
> - it allows to define a set of advertised speeds for
>   auto-negociation.
> - it allows to disable link auto-negociation (single fixed speed).
> - default: auto-negociate all supported speeds.
> 
> Other changes:
> 
> * Added utility MACROs ETH_SPEED_NUM_XXX with the numeric
>   values of all supported link speeds, in Mbps.
> * Converted link_speed to uint32_t to accomodate 100G speeds
>   (bug).
> * Added autoneg flag in struct rte_eth_link to indicate if
>   link speed was a result of auto-negociation or was fixed
>   by configuration.
> * Added utility function to convert numeric speeds to bitmap
>   fields.

Can you avoid modifications in the e1000/base code?
We do not modify (and maintain) that part on our own.
Instead we take it straight from Intel ND.  
So if you feel like these changes are really necessary - please submit a patch
to ND first, and if your changes will be applied, will pick it up from them. 
Thanks
Konstantin

> 
> Signed-off-by: Marc Sune <marcdevel@gmail.com>
> ---
>  app/test-pmd/cmdline.c                     | 124 +++++++++++++++--------------
>  app/test/virtual_pmd.c                     |   4 +-
>  drivers/net/af_packet/rte_eth_af_packet.c  |   5 +-
>  drivers/net/bonding/rte_eth_bond_8023ad.c  |  14 ++--
>  drivers/net/cxgbe/base/t4_hw.c             |   8 +-
>  drivers/net/e1000/base/e1000_80003es2lan.c |   6 +-
>  drivers/net/e1000/base/e1000_82541.c       |   8 +-
>  drivers/net/e1000/base/e1000_82543.c       |   4 +-
>  drivers/net/e1000/base/e1000_82575.c       |  11 +--
>  drivers/net/e1000/base/e1000_api.c         |   2 +-
>  drivers/net/e1000/base/e1000_api.h         |   2 +-
>  drivers/net/e1000/base/e1000_defines.h     |   4 +-
>  drivers/net/e1000/base/e1000_hw.h          |   2 +-
>  drivers/net/e1000/base/e1000_ich8lan.c     |   7 +-
>  drivers/net/e1000/base/e1000_mac.c         |   9 ++-
>  drivers/net/e1000/base/e1000_mac.h         |   6 +-
>  drivers/net/e1000/base/e1000_vf.c          |   4 +-
>  drivers/net/e1000/base/e1000_vf.h          |   2 +-
>  drivers/net/e1000/em_ethdev.c              | 113 +++++++++++++-------------
>  drivers/net/e1000/igb_ethdev.c             | 108 +++++++++++++------------
>  drivers/net/fm10k/fm10k_ethdev.c           |   8 +-
>  drivers/net/i40e/i40e_ethdev.c             |  73 ++++++++---------
>  drivers/net/i40e/i40e_ethdev_vf.c          |  11 +--
>  drivers/net/ixgbe/ixgbe_ethdev.c           |  78 ++++++++----------
>  drivers/net/mlx4/mlx4.c                    |   2 +
>  drivers/net/mpipe/mpipe_tilegx.c           |   6 +-
>  drivers/net/null/rte_eth_null.c            |   5 +-
>  drivers/net/pcap/rte_eth_pcap.c            |   9 ++-
>  drivers/net/ring/rte_eth_ring.c            |   5 +-
>  drivers/net/virtio/virtio_ethdev.c         |   2 +-
>  drivers/net/virtio/virtio_ethdev.h         |   2 -
>  drivers/net/vmxnet3/vmxnet3_ethdev.c       |   5 +-
>  drivers/net/xenvirt/rte_eth_xenvirt.c      |   5 +-
>  examples/ip_pipeline/config_parse.c        |   3 +-
>  lib/librte_ether/rte_ethdev.c              |  49 ++++++++++++
>  lib/librte_ether/rte_ethdev.h              | 113 ++++++++++++++++----------
>  36 files changed, 454 insertions(+), 365 deletions(-)
> 
> diff --git a/app/test-pmd/cmdline.c b/app/test-pmd/cmdline.c
> index 6d28c1b..00571bc 100644
> --- a/app/test-pmd/cmdline.c
> +++ b/app/test-pmd/cmdline.c
> @@ -956,14 +956,65 @@ struct cmd_config_speed_all {
>  	cmdline_fixed_string_t value2;
>  };
> 
> +static int
> +parse_and_check_speed_duplex(char *value1, char *value2, uint32_t *link_speed)
> +{
> +
> +	int duplex;
> +
> +	if (!strcmp(value2, "half")) {
> +		duplex = 0;
> +	} else if (!strcmp(value2, "full")) {
> +		duplex = 1;
> +	} else if (!strcmp(value2, "auto")) {
> +		duplex = 1;
> +	} else {
> +		printf("Unknown parameter\n");
> +		return -1;
> +	}
> +
> +	if (!strcmp(value1, "10")) {
> +		*link_speed = (duplex) ? ETH_LINK_SPEED_10M :
> +							ETH_LINK_SPEED_10M_HD;
> +	} else if (!strcmp(value1, "100")) {
> +		*link_speed = (duplex) ? ETH_LINK_SPEED_100M :
> +							ETH_LINK_SPEED_100M_HD;
> +	} else if (!strcmp(value1, "1000")) {
> +		if (!duplex)
> +			goto invalid_speed_param;
> +		*link_speed = ETH_LINK_SPEED_1G;
> +	} else if (!strcmp(value1, "10000")) {
> +		if (!duplex)
> +			goto invalid_speed_param;
> +		*link_speed = ETH_LINK_SPEED_10G;
> +	} else if (!strcmp(value1, "40000")) {
> +		if (!duplex)
> +			goto invalid_speed_param;
> +		*link_speed = ETH_LINK_SPEED_40G;
> +	} else if (!strcmp(value1, "auto")) {
> +		if (!duplex)
> +			goto invalid_speed_param;
> +		*link_speed = ETH_LINK_SPEED_AUTONEG;
> +	} else {
> +		printf("Unknown parameter\n");
> +		return -1;
> +	}
> +
> +	return 0;
> +
> +invalid_speed_param:
> +
> +	printf("Invalid speed parameter\n");
> +	return -1;
> +}
> +
>  static void
>  cmd_config_speed_all_parsed(void *parsed_result,
>  			__attribute__((unused)) struct cmdline *cl,
>  			__attribute__((unused)) void *data)
>  {
>  	struct cmd_config_speed_all *res = parsed_result;
> -	uint16_t link_speed = ETH_LINK_SPEED_AUTONEG;
> -	uint16_t link_duplex = 0;
> +	uint32_t link_speed;
>  	portid_t pid;
> 
>  	if (!all_ports_stopped()) {
> @@ -971,40 +1022,18 @@ cmd_config_speed_all_parsed(void *parsed_result,
>  		return;
>  	}
> 
> -	if (!strcmp(res->value1, "10"))
> -		link_speed = ETH_LINK_SPEED_10;
> -	else if (!strcmp(res->value1, "100"))
> -		link_speed = ETH_LINK_SPEED_100;
> -	else if (!strcmp(res->value1, "1000"))
> -		link_speed = ETH_LINK_SPEED_1000;
> -	else if (!strcmp(res->value1, "10000"))
> -		link_speed = ETH_LINK_SPEED_10G;
> -	else if (!strcmp(res->value1, "40000"))
> -		link_speed = ETH_LINK_SPEED_40G;
> -	else if (!strcmp(res->value1, "auto"))
> -		link_speed = ETH_LINK_SPEED_AUTONEG;
> -	else {
> -		printf("Unknown parameter\n");
> +	if (parse_and_check_speed_duplex(res->value1,
> +						res->value2,
> +						&link_speed) < 0)
>  		return;
> -	}
> -
> -	if (!strcmp(res->value2, "half"))
> -		link_duplex = ETH_LINK_HALF_DUPLEX;
> -	else if (!strcmp(res->value2, "full"))
> -		link_duplex = ETH_LINK_FULL_DUPLEX;
> -	else if (!strcmp(res->value2, "auto"))
> -		link_duplex = ETH_LINK_AUTONEG_DUPLEX;
> -	else {
> -		printf("Unknown parameter\n");
> -		return;
> -	}
> 
>  	FOREACH_PORT(pid, ports) {
> -		ports[pid].dev_conf.link_speed = link_speed;
> -		ports[pid].dev_conf.link_duplex = link_duplex;
> +		ports[pid].dev_conf.link_speeds = link_speed;
>  	}
> 
>  	cmd_reconfig_device_queue(RTE_PORT_ALL, 1, 1);
> +
> +	return;
>  }
> 
>  cmdline_parse_token_string_t cmd_config_speed_all_port =
> @@ -1059,8 +1088,7 @@ cmd_config_speed_specific_parsed(void *parsed_result,
>  				__attribute__((unused)) void *data)
>  {
>  	struct cmd_config_speed_specific *res = parsed_result;
> -	uint16_t link_speed = ETH_LINK_SPEED_AUTONEG;
> -	uint16_t link_duplex = 0;
> +	uint32_t link_speed;
> 
>  	if (!all_ports_stopped()) {
>  		printf("Please stop all ports first\n");
> @@ -1070,36 +1098,12 @@ cmd_config_speed_specific_parsed(void *parsed_result,
>  	if (port_id_is_invalid(res->id, ENABLED_WARN))
>  		return;
> 
> -	if (!strcmp(res->value1, "10"))
> -		link_speed = ETH_LINK_SPEED_10;
> -	else if (!strcmp(res->value1, "100"))
> -		link_speed = ETH_LINK_SPEED_100;
> -	else if (!strcmp(res->value1, "1000"))
> -		link_speed = ETH_LINK_SPEED_1000;
> -	else if (!strcmp(res->value1, "10000"))
> -		link_speed = ETH_LINK_SPEED_10000;
> -	else if (!strcmp(res->value1, "40000"))
> -		link_speed = ETH_LINK_SPEED_40G;
> -	else if (!strcmp(res->value1, "auto"))
> -		link_speed = ETH_LINK_SPEED_AUTONEG;
> -	else {
> -		printf("Unknown parameter\n");
> +	if (parse_and_check_speed_duplex(res->value1,
> +						res->value2,
> +						&link_speed) < 0)
>  		return;
> -	}
> -
> -	if (!strcmp(res->value2, "half"))
> -		link_duplex = ETH_LINK_HALF_DUPLEX;
> -	else if (!strcmp(res->value2, "full"))
> -		link_duplex = ETH_LINK_FULL_DUPLEX;
> -	else if (!strcmp(res->value2, "auto"))
> -		link_duplex = ETH_LINK_AUTONEG_DUPLEX;
> -	else {
> -		printf("Unknown parameter\n");
> -		return;
> -	}
> 
> -	ports[res->id].dev_conf.link_speed = link_speed;
> -	ports[res->id].dev_conf.link_duplex = link_duplex;
> +	ports[res->id].dev_conf.link_speeds = link_speed;
> 
>  	cmd_reconfig_device_queue(RTE_PORT_ALL, 1, 1);
>  }
> diff --git a/app/test/virtual_pmd.c b/app/test/virtual_pmd.c
> index a538c8a..3c4040b 100644
> --- a/app/test/virtual_pmd.c
> +++ b/app/test/virtual_pmd.c
> @@ -603,8 +603,8 @@ virtual_ethdev_create(const char *name, struct ether_addr *mac_addr,
> 
>  	TAILQ_INIT(&(eth_dev->link_intr_cbs));
> 
> -	eth_dev->data->dev_link.link_status = 0;
> -	eth_dev->data->dev_link.link_speed = ETH_LINK_SPEED_10000;
> +	eth_dev->data->dev_link.link_status = ETH_LINK_DOWN;
> +	eth_dev->data->dev_link.link_speed = ETH_SPEED_NUM_10G;
>  	eth_dev->data->dev_link.link_duplex = ETH_LINK_FULL_DUPLEX;
> 
>  	eth_dev->data->mac_addrs = rte_zmalloc(name, ETHER_ADDR_LEN, 0);
> diff --git a/drivers/net/af_packet/rte_eth_af_packet.c b/drivers/net/af_packet/rte_eth_af_packet.c
> index 767f36b..5db1db2 100644
> --- a/drivers/net/af_packet/rte_eth_af_packet.c
> +++ b/drivers/net/af_packet/rte_eth_af_packet.c
> @@ -116,9 +116,10 @@ static const char *valid_arguments[] = {
>  static const char *drivername = "AF_PACKET PMD";
> 
>  static struct rte_eth_link pmd_link = {
> -	.link_speed = 10000,
> +	.link_speed = ETH_SPEED_NUM_10G,
>  	.link_duplex = ETH_LINK_FULL_DUPLEX,
> -	.link_status = 0
> +	.link_status = ETH_LINK_DOWN,
> +	.link_autoneg = ETH_LINK_SPEED_NEG
>  };
> 
>  static uint16_t
> diff --git a/drivers/net/bonding/rte_eth_bond_8023ad.c b/drivers/net/bonding/rte_eth_bond_8023ad.c
> index b3b30f6..3b446e1 100644
> --- a/drivers/net/bonding/rte_eth_bond_8023ad.c
> +++ b/drivers/net/bonding/rte_eth_bond_8023ad.c
> @@ -708,25 +708,25 @@ link_speed_key(uint16_t speed) {
>  	uint16_t key_speed;
> 
>  	switch (speed) {
> -	case ETH_LINK_SPEED_AUTONEG:
> +	case ETH_SPEED_NUM_NONE:
>  		key_speed = 0x00;
>  		break;
> -	case ETH_LINK_SPEED_10:
> +	case ETH_SPEED_NUM_10M:
>  		key_speed = BOND_LINK_SPEED_KEY_10M;
>  		break;
> -	case ETH_LINK_SPEED_100:
> +	case ETH_SPEED_NUM_100M:
>  		key_speed = BOND_LINK_SPEED_KEY_100M;
>  		break;
> -	case ETH_LINK_SPEED_1000:
> +	case ETH_SPEED_NUM_1G:
>  		key_speed = BOND_LINK_SPEED_KEY_1000M;
>  		break;
> -	case ETH_LINK_SPEED_10G:
> +	case ETH_SPEED_NUM_10G:
>  		key_speed = BOND_LINK_SPEED_KEY_10G;
>  		break;
> -	case ETH_LINK_SPEED_20G:
> +	case ETH_SPEED_NUM_20G:
>  		key_speed = BOND_LINK_SPEED_KEY_20G;
>  		break;
> -	case ETH_LINK_SPEED_40G:
> +	case ETH_SPEED_NUM_40G:
>  		key_speed = BOND_LINK_SPEED_KEY_40G;
>  		break;
>  	default:
> diff --git a/drivers/net/cxgbe/base/t4_hw.c b/drivers/net/cxgbe/base/t4_hw.c
> index 884d2cf..79af806 100644
> --- a/drivers/net/cxgbe/base/t4_hw.c
> +++ b/drivers/net/cxgbe/base/t4_hw.c
> @@ -2159,13 +2159,13 @@ int t4_handle_fw_rpl(struct adapter *adap, const __be64 *rpl)
>  		if (stat & F_FW_PORT_CMD_TXPAUSE)
>  			fc |= PAUSE_TX;
>  		if (stat & V_FW_PORT_CMD_LSPEED(FW_PORT_CAP_SPEED_100M))
> -			speed = ETH_LINK_SPEED_100;
> +			speed = ETH_SPEED_NUM_100M;
>  		else if (stat & V_FW_PORT_CMD_LSPEED(FW_PORT_CAP_SPEED_1G))
> -			speed = ETH_LINK_SPEED_1000;
> +			speed = ETH_SPEED_NUM_1G;
>  		else if (stat & V_FW_PORT_CMD_LSPEED(FW_PORT_CAP_SPEED_10G))
> -			speed = ETH_LINK_SPEED_10000;
> +			speed = ETH_SPEED_NUM_10G;
>  		else if (stat & V_FW_PORT_CMD_LSPEED(FW_PORT_CAP_SPEED_40G))
> -			speed = ETH_LINK_SPEED_40G;
> +			speed = ETH_SPEED_NUM_40G;
> 
>  		for_each_port(adap, i) {
>  			pi = adap2pinfo(adap, i);
> diff --git a/drivers/net/e1000/base/e1000_80003es2lan.c b/drivers/net/e1000/base/e1000_80003es2lan.c
> index 5ac925e..ae11cac 100644
> --- a/drivers/net/e1000/base/e1000_80003es2lan.c
> +++ b/drivers/net/e1000/base/e1000_80003es2lan.c
> @@ -52,7 +52,7 @@ STATIC s32  e1000_write_nvm_80003es2lan(struct e1000_hw *hw, u16 offset,
>  STATIC s32  e1000_get_cfg_done_80003es2lan(struct e1000_hw *hw);
>  STATIC s32  e1000_phy_force_speed_duplex_80003es2lan(struct e1000_hw *hw);
>  STATIC s32  e1000_get_cable_length_80003es2lan(struct e1000_hw *hw);
> -STATIC s32  e1000_get_link_up_info_80003es2lan(struct e1000_hw *hw, u16 *speed,
> +STATIC s32  e1000_get_link_up_info_80003es2lan(struct e1000_hw *hw, u32 *speed,
>  					       u16 *duplex);
>  STATIC s32  e1000_reset_hw_80003es2lan(struct e1000_hw *hw);
>  STATIC s32  e1000_init_hw_80003es2lan(struct e1000_hw *hw);
> @@ -789,7 +789,7 @@ STATIC s32 e1000_get_cable_length_80003es2lan(struct e1000_hw *hw)
>   *
>   *  Retrieve the current speed and duplex configuration.
>   **/
> -STATIC s32 e1000_get_link_up_info_80003es2lan(struct e1000_hw *hw, u16 *speed,
> +STATIC s32 e1000_get_link_up_info_80003es2lan(struct e1000_hw *hw, u32 *speed,
>  					      u16 *duplex)
>  {
>  	s32 ret_val;
> @@ -1247,7 +1247,7 @@ STATIC s32 e1000_setup_copper_link_80003es2lan(struct e1000_hw *hw)
>  STATIC s32 e1000_cfg_on_link_up_80003es2lan(struct e1000_hw *hw)
>  {
>  	s32 ret_val = E1000_SUCCESS;
> -	u16 speed;
> +	u32 speed;
>  	u16 duplex;
> 
>  	DEBUGFUNC("e1000_configure_on_link_up");
> diff --git a/drivers/net/e1000/base/e1000_82541.c b/drivers/net/e1000/base/e1000_82541.c
> index 9cdb91c..73f9234 100644
> --- a/drivers/net/e1000/base/e1000_82541.c
> +++ b/drivers/net/e1000/base/e1000_82541.c
> @@ -47,7 +47,7 @@ STATIC s32  e1000_init_nvm_params_82541(struct e1000_hw *hw);
>  STATIC s32  e1000_init_mac_params_82541(struct e1000_hw *hw);
>  STATIC s32  e1000_reset_hw_82541(struct e1000_hw *hw);
>  STATIC s32  e1000_init_hw_82541(struct e1000_hw *hw);
> -STATIC s32  e1000_get_link_up_info_82541(struct e1000_hw *hw, u16 *speed,
> +STATIC s32  e1000_get_link_up_info_82541(struct e1000_hw *hw, u32 *speed,
>  					 u16 *duplex);
>  STATIC s32  e1000_phy_hw_reset_82541(struct e1000_hw *hw);
>  STATIC s32  e1000_setup_copper_link_82541(struct e1000_hw *hw);
> @@ -437,7 +437,7 @@ out:
>   *
>   * Retrieve the current speed and duplex configuration.
>   **/
> -STATIC s32 e1000_get_link_up_info_82541(struct e1000_hw *hw, u16 *speed,
> +STATIC s32 e1000_get_link_up_info_82541(struct e1000_hw *hw, u32 *speed,
>  					u16 *duplex)
>  {
>  	struct e1000_phy_info *phy = &hw->phy;
> @@ -667,8 +667,8 @@ STATIC s32 e1000_config_dsp_after_link_change_82541(struct e1000_hw *hw,
>  	struct e1000_phy_info *phy = &hw->phy;
>  	struct e1000_dev_spec_82541 *dev_spec = &hw->dev_spec._82541;
>  	s32 ret_val;
> -	u32 idle_errs = 0;
> -	u16 phy_data, phy_saved_data, speed, duplex, i;
> +	u32 idle_errs = 0, speed;
> +	u16 phy_data, phy_saved_data, duplex, i;
>  	u16 ffe_idle_err_timeout = FFE_IDLE_ERR_COUNT_TIMEOUT_20;
>  	u16 dsp_reg_array[IGP01E1000_PHY_CHANNEL_NUM] = {
>  						IGP01E1000_PHY_AGC_PARAM_A,
> diff --git a/drivers/net/e1000/base/e1000_82543.c b/drivers/net/e1000/base/e1000_82543.c
> index fc96199..4402f63 100644
> --- a/drivers/net/e1000/base/e1000_82543.c
> +++ b/drivers/net/e1000/base/e1000_82543.c
> @@ -1192,9 +1192,9 @@ out:
>  STATIC s32 e1000_check_for_copper_link_82543(struct e1000_hw *hw)
>  {
>  	struct e1000_mac_info *mac = &hw->mac;
> -	u32 icr, rctl;
> +	u32 icr, rctl, speed;
>  	s32 ret_val;
> -	u16 speed, duplex;
> +	u16 duplex;
>  	bool link;
> 
>  	DEBUGFUNC("e1000_check_for_copper_link_82543");
> diff --git a/drivers/net/e1000/base/e1000_82575.c b/drivers/net/e1000/base/e1000_82575.c
> index 723885d..f8d61e4 100644
> --- a/drivers/net/e1000/base/e1000_82575.c
> +++ b/drivers/net/e1000/base/e1000_82575.c
> @@ -53,7 +53,7 @@ STATIC void e1000_release_nvm_82575(struct e1000_hw *hw);
>  STATIC s32  e1000_check_for_link_82575(struct e1000_hw *hw);
>  STATIC s32  e1000_check_for_link_media_swap(struct e1000_hw *hw);
>  STATIC s32  e1000_get_cfg_done_82575(struct e1000_hw *hw);
> -STATIC s32  e1000_get_link_up_info_82575(struct e1000_hw *hw, u16 *speed,
> +STATIC s32  e1000_get_link_up_info_82575(struct e1000_hw *hw, u32 *speed,
>  					 u16 *duplex);
>  STATIC s32  e1000_phy_hw_reset_sgmii_82575(struct e1000_hw *hw);
>  STATIC s32  e1000_read_phy_reg_sgmii_82575(struct e1000_hw *hw, u32 offset,
> @@ -80,7 +80,7 @@ STATIC s32  e1000_write_phy_reg_sgmii_82575(struct e1000_hw *hw,
>  STATIC void e1000_clear_hw_cntrs_82575(struct e1000_hw *hw);
>  STATIC s32  e1000_acquire_swfw_sync_82575(struct e1000_hw *hw, u16 mask);
>  STATIC s32  e1000_get_pcs_speed_and_duplex_82575(struct e1000_hw *hw,
> -						 u16 *speed, u16 *duplex);
> +						 u32 *speed, u16 *duplex);
>  STATIC s32  e1000_get_phy_id_82575(struct e1000_hw *hw);
>  STATIC void e1000_release_swfw_sync_82575(struct e1000_hw *hw, u16 mask);
>  STATIC bool e1000_sgmii_active_82575(struct e1000_hw *hw);
> @@ -1167,7 +1167,7 @@ STATIC s32 e1000_get_cfg_done_82575(struct e1000_hw *hw)
>   *  interface, use PCS to retrieve the link speed and duplex information.
>   *  Otherwise, use the generic function to get the link speed and duplex info.
>   **/
> -STATIC s32 e1000_get_link_up_info_82575(struct e1000_hw *hw, u16 *speed,
> +STATIC s32 e1000_get_link_up_info_82575(struct e1000_hw *hw, u32 *speed,
>  					u16 *duplex)
>  {
>  	s32 ret_val;
> @@ -1194,7 +1194,8 @@ STATIC s32 e1000_get_link_up_info_82575(struct e1000_hw *hw, u16 *speed,
>  STATIC s32 e1000_check_for_link_82575(struct e1000_hw *hw)
>  {
>  	s32 ret_val;
> -	u16 speed, duplex;
> +	u32 speed;
> +	u16 duplex;
> 
>  	DEBUGFUNC("e1000_check_for_link_82575");
> 
> @@ -1325,7 +1326,7 @@ STATIC void e1000_power_up_serdes_link_82575(struct e1000_hw *hw)
>   *  duplex, then store the values in the pointers provided.
>   **/
>  STATIC s32 e1000_get_pcs_speed_and_duplex_82575(struct e1000_hw *hw,
> -						u16 *speed, u16 *duplex)
> +						u32 *speed, u16 *duplex)
>  {
>  	struct e1000_mac_info *mac = &hw->mac;
>  	u32 pcs;
> diff --git a/drivers/net/e1000/base/e1000_api.c b/drivers/net/e1000/base/e1000_api.c
> index bbfcae8..3a066d5 100644
> --- a/drivers/net/e1000/base/e1000_api.c
> +++ b/drivers/net/e1000/base/e1000_api.c
> @@ -673,7 +673,7 @@ s32 e1000_setup_link(struct e1000_hw *hw)
>   *  variables passed in. This is a function pointer entry point called
>   *  by drivers.
>   **/
> -s32 e1000_get_speed_and_duplex(struct e1000_hw *hw, u16 *speed, u16 *duplex)
> +s32 e1000_get_speed_and_duplex(struct e1000_hw *hw, u32 *speed, u16 *duplex)
>  {
>  	if (hw->mac.ops.get_link_up_info)
>  		return hw->mac.ops.get_link_up_info(hw, speed, duplex);
> diff --git a/drivers/net/e1000/base/e1000_api.h b/drivers/net/e1000/base/e1000_api.h
> index 0bc471d..7327750 100644
> --- a/drivers/net/e1000/base/e1000_api.h
> +++ b/drivers/net/e1000/base/e1000_api.h
> @@ -65,7 +65,7 @@ s32 e1000_check_for_link(struct e1000_hw *hw);
>  s32 e1000_reset_hw(struct e1000_hw *hw);
>  s32 e1000_init_hw(struct e1000_hw *hw);
>  s32 e1000_setup_link(struct e1000_hw *hw);
> -s32 e1000_get_speed_and_duplex(struct e1000_hw *hw, u16 *speed, u16 *duplex);
> +s32 e1000_get_speed_and_duplex(struct e1000_hw *hw, u32 *speed, u16 *duplex);
>  s32 e1000_disable_pcie_master(struct e1000_hw *hw);
>  void e1000_config_collision_dist(struct e1000_hw *hw);
>  int e1000_rar_set(struct e1000_hw *hw, u8 *addr, u32 index);
> diff --git a/drivers/net/e1000/base/e1000_defines.h b/drivers/net/e1000/base/e1000_defines.h
> index 69aa1f2..692845d 100644
> --- a/drivers/net/e1000/base/e1000_defines.h
> +++ b/drivers/net/e1000/base/e1000_defines.h
> @@ -348,8 +348,8 @@ POSSIBILITY OF SUCH DAMAGE.
>  #define SPEED_100	100
>  #define SPEED_1000	1000
>  #define SPEED_2500	2500
> -#define HALF_DUPLEX	1
> -#define FULL_DUPLEX	2
> +#define HALF_DUPLEX	0
> +#define FULL_DUPLEX	1
> 
>  #define PHY_FORCE_TIME	20
> 
> diff --git a/drivers/net/e1000/base/e1000_hw.h b/drivers/net/e1000/base/e1000_hw.h
> index e4e4f76..30e7f3b 100644
> --- a/drivers/net/e1000/base/e1000_hw.h
> +++ b/drivers/net/e1000/base/e1000_hw.h
> @@ -686,7 +686,7 @@ struct e1000_mac_operations {
>  	void (*clear_vfta)(struct e1000_hw *);
>  	s32  (*get_bus_info)(struct e1000_hw *);
>  	void (*set_lan_id)(struct e1000_hw *);
> -	s32  (*get_link_up_info)(struct e1000_hw *, u16 *, u16 *);
> +	s32  (*get_link_up_info)(struct e1000_hw *, u32 *, u16 *);
>  	s32  (*led_on)(struct e1000_hw *);
>  	s32  (*led_off)(struct e1000_hw *);
>  	void (*update_mc_addr_list)(struct e1000_hw *, u8 *, u32);
> diff --git a/drivers/net/e1000/base/e1000_ich8lan.c b/drivers/net/e1000/base/e1000_ich8lan.c
> index 89d07e9..a6e01c7 100644
> --- a/drivers/net/e1000/base/e1000_ich8lan.c
> +++ b/drivers/net/e1000/base/e1000_ich8lan.c
> @@ -108,7 +108,7 @@ STATIC s32  e1000_setup_link_ich8lan(struct e1000_hw *hw);
>  STATIC s32  e1000_setup_copper_link_ich8lan(struct e1000_hw *hw);
>  STATIC s32  e1000_setup_copper_link_pch_lpt(struct e1000_hw *hw);
>  STATIC s32  e1000_get_link_up_info_ich8lan(struct e1000_hw *hw,
> -					   u16 *speed, u16 *duplex);
> +					   u32 *speed, u16 *duplex);
>  STATIC s32  e1000_cleanup_led_ich8lan(struct e1000_hw *hw);
>  STATIC s32  e1000_led_on_ich8lan(struct e1000_hw *hw);
>  STATIC s32  e1000_led_off_ich8lan(struct e1000_hw *hw);
> @@ -1458,7 +1458,8 @@ STATIC s32 e1000_check_for_copper_link_ich8lan(struct e1000_hw *hw)
>  	 */
>  	if (((hw->mac.type == e1000_pch2lan) ||
>  	     (hw->mac.type == e1000_pch_lpt)) && link) {
> -		u16 speed, duplex;
> +		u16 duplex;
> +		u32 speed;
> 
>  		e1000_get_speed_and_duplex_copper_generic(hw, &speed, &duplex);
>  		tipg_reg = E1000_READ_REG(hw, E1000_TIPG);
> @@ -4623,7 +4624,7 @@ STATIC s32 e1000_setup_copper_link_pch_lpt(struct e1000_hw *hw)
>   *  information and then calls the Kumeran lock loss workaround for links at
>   *  gigabit speeds.
>   **/
> -STATIC s32 e1000_get_link_up_info_ich8lan(struct e1000_hw *hw, u16 *speed,
> +STATIC s32 e1000_get_link_up_info_ich8lan(struct e1000_hw *hw, u32 *speed,
>  					  u16 *duplex)
>  {
>  	s32 ret_val;
> diff --git a/drivers/net/e1000/base/e1000_mac.c b/drivers/net/e1000/base/e1000_mac.c
> index a0f3a99..c66421c 100644
> --- a/drivers/net/e1000/base/e1000_mac.c
> +++ b/drivers/net/e1000/base/e1000_mac.c
> @@ -106,7 +106,7 @@ void e1000_null_mac_generic(struct e1000_hw E1000_UNUSEDARG *hw)
>   *  @hw: pointer to the HW structure
>   **/
>  s32 e1000_null_link_info(struct e1000_hw E1000_UNUSEDARG *hw,
> -			 u16 E1000_UNUSEDARG *s, u16 E1000_UNUSEDARG *d)
> +			 u32 E1000_UNUSEDARG *s, u16 E1000_UNUSEDARG *d)
>  {
>  	DEBUGFUNC("e1000_null_link_info");
>  	UNREFERENCED_3PARAMETER(hw, s, d);
> @@ -1348,7 +1348,8 @@ s32 e1000_config_fc_after_link_up_generic(struct e1000_hw *hw)
>  	s32 ret_val = E1000_SUCCESS;
>  	u32 pcs_status_reg, pcs_adv_reg, pcs_lp_ability_reg, pcs_ctrl_reg;
>  	u16 mii_status_reg, mii_nway_adv_reg, mii_nway_lp_ability_reg;
> -	u16 speed, duplex;
> +	u32 speed;
> +	u16 duplex;
> 
>  	DEBUGFUNC("e1000_config_fc_after_link_up_generic");
> 
> @@ -1650,7 +1651,7 @@ s32 e1000_config_fc_after_link_up_generic(struct e1000_hw *hw)
>   *  Read the status register for the current speed/duplex and store the current
>   *  speed and duplex for copper connections.
>   **/
> -s32 e1000_get_speed_and_duplex_copper_generic(struct e1000_hw *hw, u16 *speed,
> +s32 e1000_get_speed_and_duplex_copper_generic(struct e1000_hw *hw, u32 *speed,
>  					      u16 *duplex)
>  {
>  	u32 status;
> @@ -1690,7 +1691,7 @@ s32 e1000_get_speed_and_duplex_copper_generic(struct e1000_hw *hw, u16 *speed,
>   *  for fiber/serdes links.
>   **/
>  s32 e1000_get_speed_and_duplex_fiber_serdes_generic(struct e1000_hw E1000_UNUSEDARG *hw,
> -						    u16 *speed, u16 *duplex)
> +						    u32 *speed, u16 *duplex)
>  {
>  	DEBUGFUNC("e1000_get_speed_and_duplex_fiber_serdes_generic");
>  	UNREFERENCED_1PARAMETER(hw);
> diff --git a/drivers/net/e1000/base/e1000_mac.h b/drivers/net/e1000/base/e1000_mac.h
> index 96a260c..fef862f 100644
> --- a/drivers/net/e1000/base/e1000_mac.h
> +++ b/drivers/net/e1000/base/e1000_mac.h
> @@ -40,7 +40,7 @@ void e1000_init_mac_ops_generic(struct e1000_hw *hw);
>  #endif /* E1000_REMOVED */
>  void e1000_null_mac_generic(struct e1000_hw *hw);
>  s32  e1000_null_ops_generic(struct e1000_hw *hw);
> -s32  e1000_null_link_info(struct e1000_hw *hw, u16 *s, u16 *d);
> +s32  e1000_null_link_info(struct e1000_hw *hw, u32 *s, u16 *d);
>  bool e1000_null_mng_mode(struct e1000_hw *hw);
>  void e1000_null_update_mc(struct e1000_hw *hw, u8 *h, u32 a);
>  void e1000_null_write_vfta(struct e1000_hw *hw, u32 a, u32 b);
> @@ -61,10 +61,10 @@ s32  e1000_get_bus_info_pcie_generic(struct e1000_hw *hw);
>  void e1000_set_lan_id_single_port(struct e1000_hw *hw);
>  void e1000_set_lan_id_multi_port_pci(struct e1000_hw *hw);
>  s32  e1000_get_hw_semaphore_generic(struct e1000_hw *hw);
> -s32  e1000_get_speed_and_duplex_copper_generic(struct e1000_hw *hw, u16 *speed,
> +s32  e1000_get_speed_and_duplex_copper_generic(struct e1000_hw *hw, u32 *speed,
>  					       u16 *duplex);
>  s32  e1000_get_speed_and_duplex_fiber_serdes_generic(struct e1000_hw *hw,
> -						     u16 *speed, u16 *duplex);
> +						     u32 *speed, u16 *duplex);
>  s32  e1000_id_led_init_generic(struct e1000_hw *hw);
>  s32  e1000_led_on_generic(struct e1000_hw *hw);
>  s32  e1000_led_off_generic(struct e1000_hw *hw);
> diff --git a/drivers/net/e1000/base/e1000_vf.c b/drivers/net/e1000/base/e1000_vf.c
> index 7845b48..c7fc80f 100644
> --- a/drivers/net/e1000/base/e1000_vf.c
> +++ b/drivers/net/e1000/base/e1000_vf.c
> @@ -43,7 +43,7 @@ STATIC s32 e1000_setup_link_vf(struct e1000_hw *hw);
>  STATIC s32 e1000_get_bus_info_pcie_vf(struct e1000_hw *hw);
>  STATIC s32 e1000_init_mac_params_vf(struct e1000_hw *hw);
>  STATIC s32 e1000_check_for_link_vf(struct e1000_hw *hw);
> -STATIC s32 e1000_get_link_up_info_vf(struct e1000_hw *hw, u16 *speed,
> +STATIC s32 e1000_get_link_up_info_vf(struct e1000_hw *hw, u32 *speed,
>  				     u16 *duplex);
>  STATIC s32 e1000_init_hw_vf(struct e1000_hw *hw);
>  STATIC s32 e1000_reset_hw_vf(struct e1000_hw *hw);
> @@ -220,7 +220,7 @@ STATIC s32 e1000_get_bus_info_pcie_vf(struct e1000_hw *hw)
>   *  Since we cannot read the PHY and get accurate link info, we must rely upon
>   *  the status register's data which is often stale and inaccurate.
>   **/
> -STATIC s32 e1000_get_link_up_info_vf(struct e1000_hw *hw, u16 *speed,
> +STATIC s32 e1000_get_link_up_info_vf(struct e1000_hw *hw, u32 *speed,
>  				     u16 *duplex)
>  {
>  	s32 status;
> diff --git a/drivers/net/e1000/base/e1000_vf.h b/drivers/net/e1000/base/e1000_vf.h
> index d6216de..f7b5ea8 100644
> --- a/drivers/net/e1000/base/e1000_vf.h
> +++ b/drivers/net/e1000/base/e1000_vf.h
> @@ -201,7 +201,7 @@ struct e1000_mac_operations {
>  	s32  (*check_for_link)(struct e1000_hw *);
>  	void (*clear_vfta)(struct e1000_hw *);
>  	s32  (*get_bus_info)(struct e1000_hw *);
> -	s32  (*get_link_up_info)(struct e1000_hw *, u16 *, u16 *);
> +	s32  (*get_link_up_info)(struct e1000_hw *, u32 *, u16 *);
>  	void (*update_mc_addr_list)(struct e1000_hw *, u8 *, u32);
>  	s32  (*reset_hw)(struct e1000_hw *);
>  	s32  (*init_hw)(struct e1000_hw *);
> diff --git a/drivers/net/e1000/em_ethdev.c b/drivers/net/e1000/em_ethdev.c
> index fd48bbf..a041710 100644
> --- a/drivers/net/e1000/em_ethdev.c
> +++ b/drivers/net/e1000/em_ethdev.c
> @@ -509,6 +509,9 @@ eth_em_start(struct rte_eth_dev *dev)
>  	struct rte_intr_handle *intr_handle = &dev->pci_dev->intr_handle;
>  	int ret, mask;
>  	uint32_t intr_vector = 0;
> +	uint32_t *speeds;
> +	int num_speeds;
> +	bool autoneg;
> 
>  	PMD_INIT_FUNC_TRACE();
> 
> @@ -583,56 +586,46 @@ eth_em_start(struct rte_eth_dev *dev)
>  	E1000_WRITE_REG(hw, E1000_ITR, UINT16_MAX);
> 
>  	/* Setup link speed and duplex */
> -	switch (dev->data->dev_conf.link_speed) {
> -	case ETH_LINK_SPEED_AUTONEG:
> -		if (dev->data->dev_conf.link_duplex == ETH_LINK_AUTONEG_DUPLEX)
> -			hw->phy.autoneg_advertised = E1000_ALL_SPEED_DUPLEX;
> -		else if (dev->data->dev_conf.link_duplex ==
> -					ETH_LINK_HALF_DUPLEX)
> -			hw->phy.autoneg_advertised = E1000_ALL_HALF_DUPLEX;
> -		else if (dev->data->dev_conf.link_duplex ==
> -					ETH_LINK_FULL_DUPLEX)
> -			hw->phy.autoneg_advertised = E1000_ALL_FULL_DUPLEX;
> -		else
> -			goto error_invalid_config;
> -		break;
> -	case ETH_LINK_SPEED_10:
> -		if (dev->data->dev_conf.link_duplex == ETH_LINK_AUTONEG_DUPLEX)
> -			hw->phy.autoneg_advertised = E1000_ALL_10_SPEED;
> -		else if (dev->data->dev_conf.link_duplex ==
> -					ETH_LINK_HALF_DUPLEX)
> -			hw->phy.autoneg_advertised = ADVERTISE_10_HALF;
> -		else if (dev->data->dev_conf.link_duplex ==
> -					ETH_LINK_FULL_DUPLEX)
> -			hw->phy.autoneg_advertised = ADVERTISE_10_FULL;
> -		else
> -			goto error_invalid_config;
> -		break;
> -	case ETH_LINK_SPEED_100:
> -		if (dev->data->dev_conf.link_duplex == ETH_LINK_AUTONEG_DUPLEX)
> -			hw->phy.autoneg_advertised = E1000_ALL_100_SPEED;
> -		else if (dev->data->dev_conf.link_duplex ==
> -					ETH_LINK_HALF_DUPLEX)
> -			hw->phy.autoneg_advertised = ADVERTISE_100_HALF;
> -		else if (dev->data->dev_conf.link_duplex ==
> -					ETH_LINK_FULL_DUPLEX)
> -			hw->phy.autoneg_advertised = ADVERTISE_100_FULL;
> -		else
> +	speeds = &dev->data->dev_conf.link_speeds;
> +	if (*speeds == ETH_LINK_SPEED_AUTONEG) {
> +		hw->phy.autoneg_advertised = E1000_ALL_SPEED_DUPLEX;
> +	} else {
> +		num_speeds = 0;
> +		autoneg = ~(*speeds & ETH_LINK_SPEED_NO_AUTONEG);
> +
> +		/* Reset */
> +		hw->phy.autoneg_advertised = 0;
> +
> +		if (*speeds & ~(ETH_LINK_SPEED_10M_HD | ETH_LINK_SPEED_10M |
> +				ETH_LINK_SPEED_100M_HD | ETH_LINK_SPEED_100M |
> +				ETH_LINK_SPEED_1G)) {
> +			num_speeds = -1;
>  			goto error_invalid_config;
> -		break;
> -	case ETH_LINK_SPEED_1000:
> -		if ((dev->data->dev_conf.link_duplex ==
> -				ETH_LINK_AUTONEG_DUPLEX) ||
> -			(dev->data->dev_conf.link_duplex ==
> -					ETH_LINK_FULL_DUPLEX))
> -			hw->phy.autoneg_advertised = ADVERTISE_1000_FULL;
> -		else
> +		}
> +		if (*speeds & ETH_LINK_SPEED_10M_HD) {
> +			hw->phy.autoneg_advertised |= ADVERTISE_10_HALF;
> +			num_speeds++;
> +		}
> +		if (*speeds & ETH_LINK_SPEED_10M) {
> +			hw->phy.autoneg_advertised |= ADVERTISE_10_FULL;
> +			num_speeds++;
> +		}
> +		if (*speeds & ETH_LINK_SPEED_100M_HD) {
> +			hw->phy.autoneg_advertised |= ADVERTISE_100_HALF;
> +			num_speeds++;
> +		}
> +		if (*speeds & ETH_LINK_SPEED_100M) {
> +			hw->phy.autoneg_advertised |= ADVERTISE_100_FULL;
> +			num_speeds++;
> +		}
> +		if (*speeds & ETH_LINK_SPEED_1G) {
> +			hw->phy.autoneg_advertised |= ADVERTISE_1000_FULL;
> +			num_speeds++;
> +		}
> +		if (num_speeds == 0 || (!autoneg && (num_speeds > 2)))
>  			goto error_invalid_config;
> -		break;
> -	case ETH_LINK_SPEED_10000:
> -	default:
> -		goto error_invalid_config;
>  	}
> +
>  	e1000_setup_link(hw);
> 
>  	if (rte_intr_allow_others(intr_handle)) {
> @@ -665,9 +658,8 @@ eth_em_start(struct rte_eth_dev *dev)
>  	return (0);
> 
>  error_invalid_config:
> -	PMD_INIT_LOG(ERR, "Invalid link_speed/link_duplex (%u/%u) for port %u",
> -		     dev->data->dev_conf.link_speed,
> -		     dev->data->dev_conf.link_duplex, dev->data->port_id);
> +	PMD_INIT_LOG(ERR, "Invalid advertised speeds (%u) for port %u",
> +		     dev->data->dev_conf.link_speeds, dev->data->port_id);
>  	em_dev_clear_queues(dev);
>  	return (-EINVAL);
>  }
> @@ -1024,11 +1016,11 @@ eth_em_infos_get(struct rte_eth_dev *dev, struct rte_eth_dev_info *dev_info)
>  		.nb_align = EM_TXD_ALIGN,
>  	};
> 
> -	dev_info->speed_capa = ETH_SPEED_CAP_10M_HD |
> -					ETH_SPEED_CAP_10M_FD |
> -					ETH_SPEED_CAP_100M_HD |
> -					ETH_SPEED_CAP_100M_FD |
> -					ETH_SPEED_CAP_1G;
> +	dev_info->speed_capa = ETH_LINK_SPEED_10M_HD |
> +					ETH_LINK_SPEED_10M |
> +					ETH_LINK_SPEED_100M_HD |
> +					ETH_LINK_SPEED_100M |
> +					ETH_LINK_SPEED_1G;
>  }
> 
>  /* return 0 means link status changed, -1 means not changed */
> @@ -1077,13 +1069,16 @@ eth_em_link_update(struct rte_eth_dev *dev, int wait_to_complete)
> 
>  	/* Now we check if a transition has happened */
>  	if (link_check && (link.link_status == 0)) {
> +		uint16_t duplex;
>  		hw->mac.ops.get_link_up_info(hw, &link.link_speed,
> -			&link.link_duplex);
> -		link.link_status = 1;
> +			&duplex);
> +		link.link_duplex = (duplex) ? ETH_LINK_FULL_DUPLEX :
> +						ETH_LINK_HALF_DUPLEX;
> +		link.link_status = ETH_LINK_UP;
>  	} else if (!link_check && (link.link_status == 1)) {
>  		link.link_speed = 0;
> -		link.link_duplex = 0;
> -		link.link_status = 0;
> +		link.link_duplex = ETH_LINK_HALF_DUPLEX;
> +		link.link_status = ETH_LINK_DOWN;
>  	}
>  	rte_em_dev_atomic_write_link_status(dev, &link);
> 
> diff --git a/drivers/net/e1000/igb_ethdev.c b/drivers/net/e1000/igb_ethdev.c
> index 9c8dffa..c1c41b3 100644
> --- a/drivers/net/e1000/igb_ethdev.c
> +++ b/drivers/net/e1000/igb_ethdev.c
> @@ -1119,6 +1119,9 @@ eth_igb_start(struct rte_eth_dev *dev)
>  	int ret, mask;
>  	uint32_t intr_vector = 0;
>  	uint32_t ctrl_ext;
> +	uint32_t *speeds;
> +	int num_speeds;
> +	bool autoneg;
> 
>  	PMD_INIT_FUNC_TRACE();
> 
> @@ -1219,48 +1222,46 @@ eth_igb_start(struct rte_eth_dev *dev)
>  	}
> 
>  	/* Setup link speed and duplex */
> -	switch (dev->data->dev_conf.link_speed) {
> -	case ETH_LINK_SPEED_AUTONEG:
> -		if (dev->data->dev_conf.link_duplex == ETH_LINK_AUTONEG_DUPLEX)
> -			hw->phy.autoneg_advertised = E1000_ALL_SPEED_DUPLEX;
> -		else if (dev->data->dev_conf.link_duplex == ETH_LINK_HALF_DUPLEX)
> -			hw->phy.autoneg_advertised = E1000_ALL_HALF_DUPLEX;
> -		else if (dev->data->dev_conf.link_duplex == ETH_LINK_FULL_DUPLEX)
> -			hw->phy.autoneg_advertised = E1000_ALL_FULL_DUPLEX;
> -		else
> -			goto error_invalid_config;
> -		break;
> -	case ETH_LINK_SPEED_10:
> -		if (dev->data->dev_conf.link_duplex == ETH_LINK_AUTONEG_DUPLEX)
> -			hw->phy.autoneg_advertised = E1000_ALL_10_SPEED;
> -		else if (dev->data->dev_conf.link_duplex == ETH_LINK_HALF_DUPLEX)
> -			hw->phy.autoneg_advertised = ADVERTISE_10_HALF;
> -		else if (dev->data->dev_conf.link_duplex == ETH_LINK_FULL_DUPLEX)
> -			hw->phy.autoneg_advertised = ADVERTISE_10_FULL;
> -		else
> -			goto error_invalid_config;
> -		break;
> -	case ETH_LINK_SPEED_100:
> -		if (dev->data->dev_conf.link_duplex == ETH_LINK_AUTONEG_DUPLEX)
> -			hw->phy.autoneg_advertised = E1000_ALL_100_SPEED;
> -		else if (dev->data->dev_conf.link_duplex == ETH_LINK_HALF_DUPLEX)
> -			hw->phy.autoneg_advertised = ADVERTISE_100_HALF;
> -		else if (dev->data->dev_conf.link_duplex == ETH_LINK_FULL_DUPLEX)
> -			hw->phy.autoneg_advertised = ADVERTISE_100_FULL;
> -		else
> +	speeds = &dev->data->dev_conf.link_speeds;
> +	if (*speeds == ETH_LINK_SPEED_AUTONEG) {
> +		hw->phy.autoneg_advertised = E1000_ALL_SPEED_DUPLEX;
> +	} else {
> +		num_speeds = 0;
> +		autoneg = ~(*speeds & ETH_LINK_SPEED_NO_AUTONEG);
> +
> +		/* Reset */
> +		hw->phy.autoneg_advertised = 0;
> +
> +		if (*speeds & ~(ETH_LINK_SPEED_10M_HD | ETH_LINK_SPEED_10M |
> +				ETH_LINK_SPEED_100M_HD | ETH_LINK_SPEED_100M |
> +				ETH_LINK_SPEED_1G)) {
> +			num_speeds = -1;
>  			goto error_invalid_config;
> -		break;
> -	case ETH_LINK_SPEED_1000:
> -		if ((dev->data->dev_conf.link_duplex == ETH_LINK_AUTONEG_DUPLEX) ||
> -				(dev->data->dev_conf.link_duplex == ETH_LINK_FULL_DUPLEX))
> -			hw->phy.autoneg_advertised = ADVERTISE_1000_FULL;
> -		else
> +		}
> +		if (*speeds & ETH_LINK_SPEED_10M_HD) {
> +			hw->phy.autoneg_advertised |= ADVERTISE_10_HALF;
> +			num_speeds++;
> +		}
> +		if (*speeds & ETH_LINK_SPEED_10M) {
> +			hw->phy.autoneg_advertised |= ADVERTISE_10_FULL;
> +			num_speeds++;
> +		}
> +		if (*speeds & ETH_LINK_SPEED_100M_HD) {
> +			hw->phy.autoneg_advertised |= ADVERTISE_100_HALF;
> +			num_speeds++;
> +		}
> +		if (*speeds & ETH_LINK_SPEED_100M) {
> +			hw->phy.autoneg_advertised |= ADVERTISE_100_FULL;
> +			num_speeds++;
> +		}
> +		if (*speeds & ETH_LINK_SPEED_1G) {
> +			hw->phy.autoneg_advertised |= ADVERTISE_1000_FULL;
> +			num_speeds++;
> +		}
> +		if (num_speeds == 0 || (!autoneg && (num_speeds > 2)))
>  			goto error_invalid_config;
> -		break;
> -	case ETH_LINK_SPEED_10000:
> -	default:
> -		goto error_invalid_config;
>  	}
> +
>  	e1000_setup_link(hw);
> 
>  	if (rte_intr_allow_others(intr_handle)) {
> @@ -1292,9 +1293,8 @@ eth_igb_start(struct rte_eth_dev *dev)
>  	return (0);
> 
>  error_invalid_config:
> -	PMD_INIT_LOG(ERR, "Invalid link_speed/link_duplex (%u/%u) for port %u",
> -		     dev->data->dev_conf.link_speed,
> -		     dev->data->dev_conf.link_duplex, dev->data->port_id);
> +	PMD_INIT_LOG(ERR, "Invalid advertised speeds (%u) for port %u",
> +		     dev->data->dev_conf.link_speeds, dev->data->port_id);
>  	igb_dev_clear_queues(dev);
>  	return (-EINVAL);
>  }
> @@ -1909,11 +1909,11 @@ eth_igb_infos_get(struct rte_eth_dev *dev, struct rte_eth_dev_info *dev_info)
>  	dev_info->rx_desc_lim = rx_desc_lim;
>  	dev_info->tx_desc_lim = tx_desc_lim;
> 
> -	dev_info->speed_capa = ETH_SPEED_CAP_10M_HD |
> -					ETH_SPEED_CAP_10M_FD |
> -					ETH_SPEED_CAP_100M_HD |
> -					ETH_SPEED_CAP_100M_FD |
> -					ETH_SPEED_CAP_1G;
> +	dev_info->speed_capa = ETH_LINK_SPEED_10M_HD |
> +					ETH_LINK_SPEED_10M |
> +					ETH_LINK_SPEED_100M_HD |
> +					ETH_LINK_SPEED_100M |
> +					ETH_LINK_SPEED_1G;
>  }
> 
>  static void
> @@ -2023,13 +2023,19 @@ eth_igb_link_update(struct rte_eth_dev *dev, int wait_to_complete)
> 
>  	/* Now we check if a transition has happened */
>  	if (link_check) {
> +		uint16_t duplex;
>  		hw->mac.ops.get_link_up_info(hw, &link.link_speed,
> -					  &link.link_duplex);
> -		link.link_status = 1;
> +					  &duplex);
> +		link.link_duplex = (duplex) ? ETH_LINK_FULL_DUPLEX :
> +							ETH_LINK_HALF_DUPLEX ;
> +		link.link_status = ETH_LINK_UP;
> +		link.link_autoneg = ~(dev->data->dev_conf.link_speeds &
> +						ETH_LINK_SPEED_NO_AUTONEG);
>  	} else if (!link_check) {
>  		link.link_speed = 0;
> -		link.link_duplex = 0;
> -		link.link_status = 0;
> +		link.link_duplex = ETH_LINK_HALF_DUPLEX;
> +		link.link_status = ETH_LINK_DOWN;
> +		link.link_autoneg = ETH_LINK_SPEED_FIXED;
>  	}
>  	rte_igb_dev_atomic_write_link_status(dev, &link);
> 
> diff --git a/drivers/net/fm10k/fm10k_ethdev.c b/drivers/net/fm10k/fm10k_ethdev.c
> index aeb2962..702eb97 100644
> --- a/drivers/net/fm10k/fm10k_ethdev.c
> +++ b/drivers/net/fm10k/fm10k_ethdev.c
> @@ -1172,7 +1172,7 @@ fm10k_link_update(struct rte_eth_dev *dev,
>  	 * is no 50Gbps Ethernet. */
>  	dev->data->dev_link.link_speed  = 0;
>  	dev->data->dev_link.link_duplex = ETH_LINK_FULL_DUPLEX;
> -	dev->data->dev_link.link_status = 1;
> +	dev->data->dev_link.link_status = ETH_LINK_UP;
> 
>  	return 0;
>  }
> @@ -1334,9 +1334,9 @@ fm10k_dev_infos_get(struct rte_eth_dev *dev,
>  		.nb_align = FM10K_MULT_TX_DESC,
>  	};
> 
> -	dev_info->speed_capa = ETH_SPEED_CAP_1G | ETH_SPEED_CAP_2_5G |
> -					ETH_SPEED_CAP_10G | ETH_SPEED_CAP_25G |
> -					ETH_SPEED_CAP_40G | ETH_SPEED_CAP_100G;
> +	dev_info->speed_capa = ETH_LINK_SPEED_1G | ETH_LINK_SPEED_2_5G |
> +				ETH_LINK_SPEED_10G | ETH_LINK_SPEED_25G |
> +				ETH_LINK_SPEED_40G | ETH_LINK_SPEED_100G;
>  }
> 
>  static int
> diff --git a/drivers/net/i40e/i40e_ethdev.c b/drivers/net/i40e/i40e_ethdev.c
> index d242973..34bc2c9 100644
> --- a/drivers/net/i40e/i40e_ethdev.c
> +++ b/drivers/net/i40e/i40e_ethdev.c
> @@ -1326,27 +1326,20 @@ i40e_vsi_disable_queues_intr(struct i40e_vsi *vsi)
>  }
> 
>  static inline uint8_t
> -i40e_parse_link_speed(uint16_t eth_link_speed)
> +i40e_parse_link_speeds(uint16_t link_speeds)
>  {
>  	uint8_t link_speed = I40E_LINK_SPEED_UNKNOWN;
> 
> -	switch (eth_link_speed) {
> -	case ETH_LINK_SPEED_40G:
> -		link_speed = I40E_LINK_SPEED_40GB;
> -		break;
> -	case ETH_LINK_SPEED_20G:
> -		link_speed = I40E_LINK_SPEED_20GB;
> -		break;
> -	case ETH_LINK_SPEED_10G:
> -		link_speed = I40E_LINK_SPEED_10GB;
> -		break;
> -	case ETH_LINK_SPEED_1000:
> -		link_speed = I40E_LINK_SPEED_1GB;
> -		break;
> -	case ETH_LINK_SPEED_100:
> -		link_speed = I40E_LINK_SPEED_100MB;
> -		break;
> -	}
> +	if (link_speeds & ETH_LINK_SPEED_40G)
> +		link_speed |= I40E_LINK_SPEED_40GB;
> +	if (link_speeds & ETH_LINK_SPEED_20G)
> +		link_speed |= I40E_LINK_SPEED_20GB;
> +	if (link_speeds & ETH_LINK_SPEED_10G)
> +		link_speed |= I40E_LINK_SPEED_10GB;
> +	if (link_speeds & ETH_LINK_SPEED_1G)
> +		link_speed |= I40E_LINK_SPEED_1GB;
> +	if (link_speeds & ETH_LINK_SPEED_100M)
> +		link_speed |= I40E_LINK_SPEED_100MB;
> 
>  	return link_speed;
>  }
> @@ -1372,9 +1365,9 @@ i40e_apply_link_speed(struct rte_eth_dev *dev)
>  	struct i40e_hw *hw = I40E_DEV_PRIVATE_TO_HW(dev->data->dev_private);
>  	struct rte_eth_conf *conf = &dev->data->dev_conf;
> 
> -	speed = i40e_parse_link_speed(conf->link_speed);
> +	speed = i40e_parse_link_speeds(conf->link_speeds);
>  	abilities |= I40E_AQ_PHY_ENABLE_ATOMIC_LINK;
> -	if (conf->link_speed == ETH_LINK_SPEED_AUTONEG)
> +	if (conf->link_speeds & ETH_LINK_SPEED_AUTONEG)
>  		abilities |= I40E_AQ_PHY_AN_ENABLED;
>  	else
>  		abilities |= I40E_AQ_PHY_LINK_ENABLED;
> @@ -1394,10 +1387,8 @@ i40e_dev_start(struct rte_eth_dev *dev)
> 
>  	hw->adapter_stopped = 0;
> 
> -	if ((dev->data->dev_conf.link_duplex != ETH_LINK_AUTONEG_DUPLEX) &&
> -		(dev->data->dev_conf.link_duplex != ETH_LINK_FULL_DUPLEX)) {
> -		PMD_INIT_LOG(ERR, "Invalid link_duplex (%hu) for port %hhu",
> -			     dev->data->dev_conf.link_duplex,
> +	if (dev->data->dev_conf.link_speeds & ETH_LINK_SPEED_NO_AUTONEG) {
> +		PMD_INIT_LOG(ERR, "Invalid link_speeds for port %hhu; autonegociation disabled",
>  			     dev->data->port_id);
>  		return -EINVAL;
>  	}
> @@ -1470,6 +1461,13 @@ i40e_dev_start(struct rte_eth_dev *dev)
>  	}
> 
>  	/* Apply link configure */
> +	if (dev->data->dev_conf.link_speeds & ~(ETH_LINK_SPEED_100M |
> +				ETH_LINK_SPEED_1G | ETH_LINK_SPEED_10G |
> +				ETH_LINK_SPEED_20G | ETH_LINK_SPEED_40G)) {
> +		PMD_DRV_LOG(ERR, "Invalid link setting");
> +		goto err_up;
> +	}
> +
>  	ret = i40e_apply_link_speed(dev);
>  	if (I40E_SUCCESS != ret) {
>  		PMD_DRV_LOG(ERR, "Fail to apply link setting");
> @@ -1713,7 +1711,7 @@ i40e_dev_link_update(struct rte_eth_dev *dev,
>  		/* Get link status information from hardware */
>  		status = i40e_aq_get_link_info(hw, false, &link_status, NULL);
>  		if (status != I40E_SUCCESS) {
> -			link.link_speed = ETH_LINK_SPEED_100;
> +			link.link_speed = ETH_SPEED_NUM_100M;
>  			link.link_duplex = ETH_LINK_FULL_DUPLEX;
>  			PMD_DRV_LOG(ERR, "Failed to get link info");
>  			goto out;
> @@ -1735,25 +1733,28 @@ i40e_dev_link_update(struct rte_eth_dev *dev,
>  	/* Parse the link status */
>  	switch (link_status.link_speed) {
>  	case I40E_LINK_SPEED_100MB:
> -		link.link_speed = ETH_LINK_SPEED_100;
> +		link.link_speed = ETH_SPEED_NUM_100M;
>  		break;
>  	case I40E_LINK_SPEED_1GB:
> -		link.link_speed = ETH_LINK_SPEED_1000;
> +		link.link_speed = ETH_SPEED_NUM_1G;
>  		break;
>  	case I40E_LINK_SPEED_10GB:
> -		link.link_speed = ETH_LINK_SPEED_10G;
> +		link.link_speed = ETH_SPEED_NUM_10G;
>  		break;
>  	case I40E_LINK_SPEED_20GB:
> -		link.link_speed = ETH_LINK_SPEED_20G;
> +		link.link_speed = ETH_SPEED_NUM_20G;
>  		break;
>  	case I40E_LINK_SPEED_40GB:
> -		link.link_speed = ETH_LINK_SPEED_40G;
> +		link.link_speed = ETH_SPEED_NUM_40G;
>  		break;
>  	default:
> -		link.link_speed = ETH_LINK_SPEED_100;
> +		link.link_speed = ETH_SPEED_NUM_100M;
>  		break;
>  	}
> 
> +	link.link_autoneg = ~(dev->data->dev_conf.link_speeds &
> +						ETH_LINK_SPEED_NO_AUTONEG);
> +
>  out:
>  	rte_i40e_dev_atomic_write_link_status(dev, &link);
>  	if (link.link_status == old.link_status)
> @@ -2308,10 +2309,10 @@ i40e_dev_info_get(struct rte_eth_dev *dev, struct rte_eth_dev_info *dev_info)
> 
>  	if (i40e_is_40G_device(hw->device_id))
>  		/* For XL710 */
> -		dev_info->speed_capa = ETH_SPEED_CAP_1G | ETH_SPEED_CAP_10G;
> +		dev_info->speed_capa = ETH_LINK_SPEED_1G | ETH_LINK_SPEED_10G;
>  	else
>  		/* For X710 */
> -		dev_info->speed_capa = ETH_SPEED_CAP_10G | ETH_SPEED_CAP_40G;
> +		dev_info->speed_capa = ETH_LINK_SPEED_10G | ETH_LINK_SPEED_40G;
> 
>  }
> 
> @@ -7835,15 +7836,15 @@ i40e_start_timecounters(struct rte_eth_dev *dev)
>  	rte_i40e_dev_atomic_read_link_status(dev, &link);
> 
>  	switch (link.link_speed) {
> -	case ETH_LINK_SPEED_40G:
> +	case ETH_SPEED_NUM_40G:
>  		tsync_inc_l = I40E_PTP_40GB_INCVAL & 0xFFFFFFFF;
>  		tsync_inc_h = I40E_PTP_40GB_INCVAL >> 32;
>  		break;
> -	case ETH_LINK_SPEED_10G:
> +	case ETH_SPEED_NUM_10G:
>  		tsync_inc_l = I40E_PTP_10GB_INCVAL & 0xFFFFFFFF;
>  		tsync_inc_h = I40E_PTP_10GB_INCVAL >> 32;
>  		break;
> -	case ETH_LINK_SPEED_1000:
> +	case ETH_SPEED_NUM_1G:
>  		tsync_inc_l = I40E_PTP_1GB_INCVAL & 0xFFFFFFFF;
>  		tsync_inc_h = I40E_PTP_1GB_INCVAL >> 32;
>  		break;
> diff --git a/drivers/net/i40e/i40e_ethdev_vf.c b/drivers/net/i40e/i40e_ethdev_vf.c
> index 14d2a50..f06f828 100644
> --- a/drivers/net/i40e/i40e_ethdev_vf.c
> +++ b/drivers/net/i40e/i40e_ethdev_vf.c
> @@ -1911,13 +1911,14 @@ i40evf_dev_link_update(struct rte_eth_dev *dev,
>  	 * DPDK pf host provide interfacet to acquire link status
>  	 * while Linux driver does not
>  	 */
> -	if (vf->version_major == I40E_DPDK_VERSION_MAJOR)
> +	if (vf->version_major == I40E_DPDK_VERSION_MAJOR) {
>  		i40evf_get_link_status(dev, &new_link);
> -	else {
> +	} else {
>  		/* Always assume it's up, for Linux driver PF host */
> -		new_link.link_duplex = ETH_LINK_AUTONEG_DUPLEX;
> -		new_link.link_speed  = ETH_LINK_SPEED_10000;
> -		new_link.link_status = 1;
> +		new_link.link_speed  = ETH_SPEED_NUM_10G;
> +		new_link.link_duplex = ETH_LINK_FULL_DUPLEX;
> +		new_link.link_autoneg = ETH_LINK_SPEED_NEG;
> +		new_link.link_status = ETH_LINK_UP;
>  	}
>  	i40evf_dev_atomic_write_link_status(dev, &new_link);
> 
> diff --git a/drivers/net/ixgbe/ixgbe_ethdev.c b/drivers/net/ixgbe/ixgbe_ethdev.c
> index 4e3ab3d..14a03e1 100644
> --- a/drivers/net/ixgbe/ixgbe_ethdev.c
> +++ b/drivers/net/ixgbe/ixgbe_ethdev.c
> @@ -1979,14 +1979,13 @@ ixgbe_dev_start(struct rte_eth_dev *dev)
>  	int mask = 0;
>  	int status;
>  	uint16_t vf, idx;
> +	uint32_t *link_speeds;
> 
>  	PMD_INIT_FUNC_TRACE();
> 
>  	/* IXGBE devices don't support half duplex */
> -	if ((dev->data->dev_conf.link_duplex != ETH_LINK_AUTONEG_DUPLEX) &&
> -			(dev->data->dev_conf.link_duplex != ETH_LINK_FULL_DUPLEX)) {
> -		PMD_INIT_LOG(ERR, "Invalid link_duplex (%hu) for port %hhu",
> -			     dev->data->dev_conf.link_duplex,
> +	if (dev->data->dev_conf.link_speeds & ETH_LINK_SPEED_NO_AUTONEG) {
> +		PMD_INIT_LOG(ERR, "Invalid link_speeds for port %hhu; autonegociation disabled",
>  			     dev->data->port_id);
>  		return -EINVAL;
>  	}
> @@ -2076,32 +2075,22 @@ ixgbe_dev_start(struct rte_eth_dev *dev)
>  	if (err)
>  		goto error;
> 
> -	switch(dev->data->dev_conf.link_speed) {
> -	case ETH_LINK_SPEED_AUTONEG:
> -		speed = (hw->mac.type != ixgbe_mac_82598EB) ?
> -				IXGBE_LINK_SPEED_82599_AUTONEG :
> -				IXGBE_LINK_SPEED_82598_AUTONEG;
> -		break;
> -	case ETH_LINK_SPEED_100:
> -		/*
> -		 * Invalid for 82598 but error will be detected by
> -		 * ixgbe_setup_link()
> -		 */
> -		speed = IXGBE_LINK_SPEED_100_FULL;
> -		break;
> -	case ETH_LINK_SPEED_1000:
> -		speed = IXGBE_LINK_SPEED_1GB_FULL;
> -		break;
> -	case ETH_LINK_SPEED_10000:
> -		speed = IXGBE_LINK_SPEED_10GB_FULL;
> -		break;
> -	default:
> -		PMD_INIT_LOG(ERR, "Invalid link_speed (%hu) for port %hhu",
> -			     dev->data->dev_conf.link_speed,
> -			     dev->data->port_id);
> +	link_speeds = &dev->data->dev_conf.link_speeds;
> +	if (*link_speeds & ~(ETH_LINK_SPEED_100M | ETH_LINK_SPEED_1G |
> +							ETH_LINK_SPEED_10G)) {
> +		PMD_INIT_LOG(ERR, "Invalid link setting");
>  		goto error;
>  	}
> 
> +	speed = 0x0;
> +
> +	if (*link_speeds & ETH_LINK_SPEED_10G)
> +		speed |= IXGBE_LINK_SPEED_10GB_FULL;
> +	if (*link_speeds & ETH_LINK_SPEED_1G)
> +		speed |= IXGBE_LINK_SPEED_1GB_FULL;
> +	if (*link_speeds & ETH_LINK_SPEED_100M)
> +		speed |= IXGBE_LINK_SPEED_100_FULL;
> +
>  	err = ixgbe_setup_link(hw, speed, link_up);
>  	if (err)
>  		goto error;
> @@ -2828,15 +2817,16 @@ ixgbe_dev_info_get(struct rte_eth_dev *dev, struct rte_eth_dev_info *dev_info)
>  	dev_info->reta_size = ixgbe_reta_size_get(hw->mac.type);
>  	dev_info->flow_type_rss_offloads = IXGBE_RSS_OFFLOAD_ALL;
> 
> -	dev_info->speed_capa = ETH_SPEED_CAP_1G | ETH_SPEED_CAP_10G;
> +	dev_info->speed_capa = ETH_LINK_SPEED_1G | ETH_LINK_SPEED_10G;
> 
>  	if (hw->mac.type == ixgbe_mac_X540 ||
>  	    hw->mac.type == ixgbe_mac_X540_vf ||
>  	    hw->mac.type == ixgbe_mac_X550 ||
> -	    hw->mac.type == ixgbe_mac_X550_vf)
> +	    hw->mac.type == ixgbe_mac_X550_vf) {
> 
> -		dev_info->speed_capa |= ETH_SPEED_CAP_100M_FD /*|
> -					ETH_SPEED_CAP_100M_HD*/;
> +		dev_info->speed_capa |= ETH_LINK_SPEED_100M /*|
> +					ETH_LINK_SPEED_100M_HD*/;
> +	}
>  }
> 
>  static void
> @@ -2903,9 +2893,9 @@ ixgbe_dev_link_update(struct rte_eth_dev *dev, int wait_to_complete)
>  	int link_up;
>  	int diag;
> 
> -	link.link_status = 0;
> +	link.link_status = ETH_LINK_DOWN;
>  	link.link_speed = 0;
> -	link.link_duplex = 0;
> +	link.link_duplex = ETH_LINK_HALF_DUPLEX;
>  	memset(&old, 0, sizeof(old));
>  	rte_ixgbe_dev_atomic_read_link_status(dev, &old);
> 
> @@ -2918,8 +2908,8 @@ ixgbe_dev_link_update(struct rte_eth_dev *dev, int wait_to_complete)
>  		diag = ixgbe_check_link(hw, &link_speed, &link_up, 1);
> 
>  	if (diag != 0) {
> -		link.link_speed = ETH_LINK_SPEED_100;
> -		link.link_duplex = ETH_LINK_HALF_DUPLEX;
> +		link.link_speed = ETH_SPEED_NUM_100M;
> +		link.link_duplex = ETH_LINK_FULL_DUPLEX;
>  		rte_ixgbe_dev_atomic_write_link_status(dev, &link);
>  		if (link.link_status == old.link_status)
>  			return -1;
> @@ -2932,26 +2922,26 @@ ixgbe_dev_link_update(struct rte_eth_dev *dev, int wait_to_complete)
>  			return -1;
>  		return 0;
>  	}
> -	link.link_status = 1;
> +	link.link_status = ETH_LINK_UP;
>  	link.link_duplex = ETH_LINK_FULL_DUPLEX;
> 
>  	switch (link_speed) {
>  	default:
>  	case IXGBE_LINK_SPEED_UNKNOWN:
> -		link.link_duplex = ETH_LINK_HALF_DUPLEX;
> -		link.link_speed = ETH_LINK_SPEED_100;
> +		link.link_duplex = ETH_LINK_FULL_DUPLEX;
> +		link.link_speed = ETH_SPEED_NUM_100M;
>  		break;
> 
>  	case IXGBE_LINK_SPEED_100_FULL:
> -		link.link_speed = ETH_LINK_SPEED_100;
> +		link.link_speed = ETH_SPEED_NUM_100M;
>  		break;
> 
>  	case IXGBE_LINK_SPEED_1GB_FULL:
> -		link.link_speed = ETH_LINK_SPEED_1000;
> +		link.link_speed = ETH_SPEED_NUM_1G;
>  		break;
> 
>  	case IXGBE_LINK_SPEED_10GB_FULL:
> -		link.link_speed = ETH_LINK_SPEED_10000;
> +		link.link_speed = ETH_SPEED_NUM_10G;
>  		break;
>  	}
>  	rte_ixgbe_dev_atomic_write_link_status(dev, &link);
> @@ -5725,15 +5715,15 @@ ixgbe_start_timecounters(struct rte_eth_dev *dev)
>  	rte_ixgbe_dev_atomic_read_link_status(dev, &link);
> 
>  	switch (link.link_speed) {
> -	case ETH_LINK_SPEED_100:
> +	case ETH_SPEED_NUM_100M:
>  		incval = IXGBE_INCVAL_100;
>  		shift = IXGBE_INCVAL_SHIFT_100;
>  		break;
> -	case ETH_LINK_SPEED_1000:
> +	case ETH_SPEED_NUM_1G:
>  		incval = IXGBE_INCVAL_1GB;
>  		shift = IXGBE_INCVAL_SHIFT_1GB;
>  		break;
> -	case ETH_LINK_SPEED_10000:
> +	case ETH_SPEED_NUM_10G:
>  	default:
>  		incval = IXGBE_INCVAL_10GB;
>  		shift = IXGBE_INCVAL_SHIFT_10GB;
> diff --git a/drivers/net/mlx4/mlx4.c b/drivers/net/mlx4/mlx4.c
> index 1f3ed59..4dbc8a9 100644
> --- a/drivers/net/mlx4/mlx4.c
> +++ b/drivers/net/mlx4/mlx4.c
> @@ -4637,6 +4637,8 @@ mlx4_link_update_unlocked(struct rte_eth_dev *dev, int wait_to_complete)
>  		dev_link.link_speed = link_speed;
>  	dev_link.link_duplex = ((edata.duplex == DUPLEX_HALF) ?
>  				ETH_LINK_HALF_DUPLEX : ETH_LINK_FULL_DUPLEX);
> +	dev_link.link_autoneg = ~(dev->data->dev_conf.link_speeds &
> +						ETH_LINK_SPEED_NO_AUTONEG);
>  	if (memcmp(&dev_link, &dev->data->dev_link, sizeof(dev_link))) {
>  		/* Link status changed. */
>  		dev->data->dev_link = dev_link;
> diff --git a/drivers/net/mpipe/mpipe_tilegx.c b/drivers/net/mpipe/mpipe_tilegx.c
> index 35134ba..f42c1d4 100644
> --- a/drivers/net/mpipe/mpipe_tilegx.c
> +++ b/drivers/net/mpipe/mpipe_tilegx.c
> @@ -388,14 +388,16 @@ mpipe_link_update(struct rte_eth_dev *dev, int wait_to_complete)
> 
>  		speed = state & GXIO_MPIPE_LINK_SPEED_MASK;
> 
> +		new.link_autoneg = ~(dev->data->dev_conf.link_speeds &
> +						ETH_LINK_SPEED_NO_AUTONEG);
>  		if (speed == GXIO_MPIPE_LINK_1G) {
>  			new.link_speed = ETH_LINK_SPEED_1000;
>  			new.link_duplex = ETH_LINK_FULL_DUPLEX;
> -			new.link_status = 1;
> +			new.link_status = ETH_LINK_UP;
>  		} else if (speed == GXIO_MPIPE_LINK_10G) {
>  			new.link_speed = ETH_LINK_SPEED_10000;
>  			new.link_duplex = ETH_LINK_FULL_DUPLEX;
> -			new.link_status = 1;
> +			new.link_status = ETH_LINK_UP;
>  		}
> 
>  		rc = mpipe_link_compare(&old, &new);
> diff --git a/drivers/net/null/rte_eth_null.c b/drivers/net/null/rte_eth_null.c
> index 77fc988..55e1fc8 100644
> --- a/drivers/net/null/rte_eth_null.c
> +++ b/drivers/net/null/rte_eth_null.c
> @@ -93,9 +93,10 @@ struct pmd_internals {
>  static struct ether_addr eth_addr = { .addr_bytes = {0} };
>  static const char *drivername = "Null PMD";
>  static struct rte_eth_link pmd_link = {
> -	.link_speed = 10000,
> +	.link_speed = ETH_SPEED_NUM_10G,
>  	.link_duplex = ETH_LINK_FULL_DUPLEX,
> -	.link_status = 0
> +	.link_status = ETH_LINK_DOWN,
> +	.link_autoneg = ETH_LINK_SPEED_NEG,
>  };
> 
>  static uint16_t
> diff --git a/drivers/net/pcap/rte_eth_pcap.c b/drivers/net/pcap/rte_eth_pcap.c
> index f9230eb..650b521 100644
> --- a/drivers/net/pcap/rte_eth_pcap.c
> +++ b/drivers/net/pcap/rte_eth_pcap.c
> @@ -125,9 +125,10 @@ static int open_single_iface(const char *iface, pcap_t **pcap);
>  static struct ether_addr eth_addr = { .addr_bytes = { 0, 0, 0, 0x1, 0x2, 0x3 } };
>  static const char *drivername = "Pcap PMD";
>  static struct rte_eth_link pmd_link = {
> -		.link_speed = 10000,
> +		.link_speed = ETH_SPEED_NUM_10G,
>  		.link_duplex = ETH_LINK_FULL_DUPLEX,
> -		.link_status = 0
> +		.link_status = ETH_LINK_DOWN,
> +		.link_autoneg = ETH_LINK_SPEED_FIXED,
>  };
> 
>  static int
> @@ -430,7 +431,7 @@ eth_dev_start(struct rte_eth_dev *dev)
> 
>  status_up:
> 
> -	dev->data->dev_link.link_status = 1;
> +	dev->data->dev_link.link_status = ETH_LINK_UP;
>  	return 0;
>  }
> 
> @@ -481,7 +482,7 @@ eth_dev_stop(struct rte_eth_dev *dev)
>  	}
> 
>  status_down:
> -	dev->data->dev_link.link_status = 0;
> +	dev->data->dev_link.link_status = ETH_LINK_DOWN;
>  }
> 
>  static int
> diff --git a/drivers/net/ring/rte_eth_ring.c b/drivers/net/ring/rte_eth_ring.c
> index d92b088..043175a 100644
> --- a/drivers/net/ring/rte_eth_ring.c
> +++ b/drivers/net/ring/rte_eth_ring.c
> @@ -71,9 +71,10 @@ struct pmd_internals {
> 
>  static const char *drivername = "Rings PMD";
>  static struct rte_eth_link pmd_link = {
> -		.link_speed = 10000,
> +		.link_speed = ETH_SPEED_NUM_10G,
>  		.link_duplex = ETH_LINK_FULL_DUPLEX,
> -		.link_status = 0
> +		.link_status = ETH_LINK_DOWN,
> +		.link_autoneg = ETH_LINK_SPEED_NEG
>  };
> 
>  static uint16_t
> diff --git a/drivers/net/virtio/virtio_ethdev.c b/drivers/net/virtio/virtio_ethdev.c
> index d928339..83a2ffe 100644
> --- a/drivers/net/virtio/virtio_ethdev.c
> +++ b/drivers/net/virtio/virtio_ethdev.c
> @@ -1631,7 +1631,7 @@ virtio_dev_link_update(struct rte_eth_dev *dev, __rte_unused int wait_to_complet
>  	memset(&link, 0, sizeof(link));
>  	virtio_dev_atomic_read_link_status(dev, &link);
>  	old = link;
> -	link.link_duplex = FULL_DUPLEX;
> +	link.link_duplex = ETH_LINK_FULL_DUPLEX;
>  	link.link_speed  = SPEED_10G;
> 
>  	if (vtpci_with_feature(hw, VIRTIO_NET_F_STATUS)) {
> diff --git a/drivers/net/virtio/virtio_ethdev.h b/drivers/net/virtio/virtio_ethdev.h
> index ae2d47d..8598815 100644
> --- a/drivers/net/virtio/virtio_ethdev.h
> +++ b/drivers/net/virtio/virtio_ethdev.h
> @@ -42,8 +42,6 @@
>  #define SPEED_100	100
>  #define SPEED_1000	1000
>  #define SPEED_10G	10000
> -#define HALF_DUPLEX	1
> -#define FULL_DUPLEX	2
> 
>  #ifndef PAGE_SIZE
>  #define PAGE_SIZE 4096
> diff --git a/drivers/net/vmxnet3/vmxnet3_ethdev.c b/drivers/net/vmxnet3/vmxnet3_ethdev.c
> index c363bf6..2bb6ee9 100644
> --- a/drivers/net/vmxnet3/vmxnet3_ethdev.c
> +++ b/drivers/net/vmxnet3/vmxnet3_ethdev.c
> @@ -736,9 +736,10 @@ vmxnet3_dev_link_update(struct rte_eth_dev *dev, __attribute__((unused)) int wai
>  	ret = VMXNET3_READ_BAR1_REG(hw, VMXNET3_REG_CMD);
> 
>  	if (ret & 0x1) {
> -		link.link_status = 1;
> +		link.link_status = ETH_LINK_UP;
>  		link.link_duplex = ETH_LINK_FULL_DUPLEX;
> -		link.link_speed = ETH_LINK_SPEED_10000;
> +		link.link_speed = ETH_SPEED_NUM_10G;
> +		link.link_autoneg = ETH_LINK_SPEED_FIXED;
>  	}
> 
>  	vmxnet3_dev_atomic_write_link_status(dev, &link);
> diff --git a/drivers/net/xenvirt/rte_eth_xenvirt.c b/drivers/net/xenvirt/rte_eth_xenvirt.c
> index 3f31806..0fcf5d3 100644
> --- a/drivers/net/xenvirt/rte_eth_xenvirt.c
> +++ b/drivers/net/xenvirt/rte_eth_xenvirt.c
> @@ -70,9 +70,10 @@ static int virtio_idx = 0;
>  static const char *drivername = "xen virtio PMD";
> 
>  static struct rte_eth_link pmd_link = {
> -		.link_speed = 10000,
> +		.link_speed = ETH_SPEED_NUM_10G,
>  		.link_duplex = ETH_LINK_FULL_DUPLEX,
> -		.link_status = 0
> +		.link_status = ETH_LINK_DOWN,
> +		.link_autoneg = ETH_LINK_SPEED_FIXED
>  };
> 
>  static void
> diff --git a/examples/ip_pipeline/config_parse.c b/examples/ip_pipeline/config_parse.c
> index 1bedbe4..c581d41 100644
> --- a/examples/ip_pipeline/config_parse.c
> +++ b/examples/ip_pipeline/config_parse.c
> @@ -84,8 +84,7 @@ static const struct app_link_params link_params_default = {
>  	.mac_addr = 0,
> 
>  	.conf = {
> -		.link_speed = 0,
> -		.link_duplex = 0,
> +		.link_speeds = 0,
>  		.rxmode = {
>  			.mq_mode = ETH_MQ_RX_NONE,
> 
> diff --git a/lib/librte_ether/rte_ethdev.c b/lib/librte_ether/rte_ethdev.c
> index 756b234..7b0214d 100644
> --- a/lib/librte_ether/rte_ethdev.c
> +++ b/lib/librte_ether/rte_ethdev.c
> @@ -865,6 +865,55 @@ rte_eth_dev_tx_queue_config(struct rte_eth_dev *dev, uint16_t nb_queues)
>  }
> 
>  int
> +rte_eth_speed_to_bm_flag(uint32_t speed, int duplex, uint32_t *flag)
> +{
> +	switch (speed) {
> +	case ETH_SPEED_NUM_10M:
> +		*flag = (duplex) ? ETH_LINK_SPEED_10M :
> +							ETH_LINK_SPEED_10M_HD;
> +		break;
> +	case ETH_SPEED_NUM_100M:
> +		*flag = (duplex) ? ETH_LINK_SPEED_100M :
> +							ETH_LINK_SPEED_100M_HD;
> +		break;
> +	case ETH_SPEED_NUM_1G:
> +		*flag = ETH_LINK_SPEED_1G;
> +		break;
> +	case ETH_SPEED_NUM_2_5G:
> +		*flag = ETH_LINK_SPEED_2_5G;
> +		break;
> +	case ETH_SPEED_NUM_5G:
> +		*flag = ETH_LINK_SPEED_5G;
> +		break;
> +	case ETH_SPEED_NUM_10G:
> +		*flag = ETH_LINK_SPEED_10G;
> +		break;
> +	case ETH_SPEED_NUM_20G:
> +		*flag = ETH_LINK_SPEED_20G;
> +		break;
> +	case ETH_SPEED_NUM_25G:
> +		*flag = ETH_LINK_SPEED_25G;
> +		break;
> +	case ETH_SPEED_NUM_40G:
> +		*flag = ETH_LINK_SPEED_40G;
> +		break;
> +	case ETH_SPEED_NUM_50G:
> +		*flag = ETH_LINK_SPEED_50G;
> +		break;
> +	case ETH_SPEED_NUM_56G:
> +		*flag = ETH_LINK_SPEED_56G;
> +		break;
> +	case ETH_SPEED_NUM_100G:
> +		*flag = ETH_LINK_SPEED_100G;
> +		break;
> +	default:
> +		return -EINVAL;
> +	}
> +
> +	return 0;
> +}
> +
> +int
>  rte_eth_dev_configure(uint8_t port_id, uint16_t nb_rx_q, uint16_t nb_tx_q,
>  		      const struct rte_eth_conf *dev_conf)
>  {
> diff --git a/lib/librte_ether/rte_ethdev.h b/lib/librte_ether/rte_ethdev.h
> index dbc1599..9b32de5 100644
> --- a/lib/librte_ether/rte_ethdev.h
> +++ b/lib/librte_ether/rte_ethdev.h
> @@ -242,26 +242,59 @@ struct rte_eth_stats {
>  };
> 
>  /**
> + * Device supported speeds bitmap flags
> + */
> +#define ETH_LINK_SPEED_AUTONEG		(0 << 0)  /*< Autonegociate (all speeds)  */
> +#define ETH_LINK_SPEED_NO_AUTONEG	(1 << 0)  /*< Disable autoneg (fixed speed)  */
> +#define ETH_LINK_SPEED_10M_HD		(1 << 1)  /*< 10 Mbps half-duplex */
> +#define ETH_LINK_SPEED_10M		(1 << 2)  /*< 10 Mbps full-duplex */
> +#define ETH_LINK_SPEED_100M_HD		(1 << 3)  /*< 100 Mbps half-duplex */
> +#define ETH_LINK_SPEED_100M		(1 << 4)  /*< 100 Mbps full-duplex */
> +#define ETH_LINK_SPEED_1G		(1 << 5)  /*< 1 Gbps */
> +#define ETH_LINK_SPEED_2_5G		(1 << 6)  /*< 2.5 Gbps */
> +#define ETH_LINK_SPEED_5G		(1 << 7)  /*< 5 Gbps */
> +#define ETH_LINK_SPEED_10G		(1 << 8)  /*< 10 Mbps */
> +#define ETH_LINK_SPEED_20G		(1 << 9)  /*< 20 Gbps */
> +#define ETH_LINK_SPEED_25G		(1 << 10)  /*< 25 Gbps */
> +#define ETH_LINK_SPEED_40G		(1 << 11)  /*< 40 Gbps */
> +#define ETH_LINK_SPEED_50G		(1 << 12)  /*< 50 Gbps */
> +#define ETH_LINK_SPEED_56G		(1 << 13)  /*< 56 Gbps */
> +#define ETH_LINK_SPEED_100G		(1 << 14)  /*< 100 Gbps */
> +
> +/**
> + * 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 Mbps */
> +#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 */
> +
> +/**
>   * A structure used to retrieve link-level information of an Ethernet port.
>   */
>  struct rte_eth_link {
> -	uint16_t link_speed;      /**< ETH_LINK_SPEED_[10, 100, 1000, 10000] */
> -	uint16_t link_duplex;     /**< ETH_LINK_[HALF_DUPLEX, FULL_DUPLEX] */
> -	uint8_t  link_status : 1; /**< 1 -> link up, 0 -> link down */
> -}__attribute__((aligned(8)));     /**< aligned for atomic64 read/write */
> -
> -#define ETH_LINK_SPEED_AUTONEG  0       /**< Auto-negotiate link speed. */
> -#define ETH_LINK_SPEED_10       10      /**< 10 megabits/second. */
> -#define ETH_LINK_SPEED_100      100     /**< 100 megabits/second. */
> -#define ETH_LINK_SPEED_1000     1000    /**< 1 gigabits/second. */
> -#define ETH_LINK_SPEED_10000    10000   /**< 10 gigabits/second. */
> -#define ETH_LINK_SPEED_10G      10000   /**< alias of 10 gigabits/second. */
> -#define ETH_LINK_SPEED_20G      20000   /**< 20 gigabits/second. */
> -#define ETH_LINK_SPEED_40G      40000   /**< 40 gigabits/second. */
> +	uint32_t link_speed;        /**< Link speed (ETH_SPEED_NUM_) */
> +	uint16_t link_duplex  : 1;  /**< 1 -> full duplex, 0 -> half duplex */
> +	uint16_t link_autoneg : 1;  /**< 1 -> link speed has been autoneg */
> +	uint16_t link_status  : 1;  /**< 1 -> link up, 0 -> link down */
> +} __attribute__((aligned(8)));      /**< aligned for atomic64 read/write */
> 
> -#define ETH_LINK_AUTONEG_DUPLEX 0       /**< Auto-negotiate duplex. */
> -#define ETH_LINK_HALF_DUPLEX    1       /**< Half-duplex connection. */
> -#define ETH_LINK_FULL_DUPLEX    2       /**< Full-duplex connection. */
> +/* Utility constants */
> +#define ETH_LINK_HALF_DUPLEX    0	/**< Half-duplex connection. */
> +#define ETH_LINK_FULL_DUPLEX    1	/**< Full-duplex connection. */
> +#define ETH_LINK_SPEED_FIXED    0	/**< Link speed was not autonegociated. */
> +#define ETH_LINK_SPEED_NEG      1	/**< Link speed was autonegociated. */
> +#define ETH_LINK_DOWN		0	/**< Link is down. */
> +#define ETH_LINK_UP		1	/**< Link is up. */
> 
>  /**
>   * A structure used to configure the ring threshold registers of an RX/TX
> @@ -760,10 +793,14 @@ struct rte_intr_conf {
>   * configuration settings may be needed.
>   */
>  struct rte_eth_conf {
> -	uint16_t link_speed;
> -	/**< ETH_LINK_SPEED_10[0|00|000], or 0 for autonegotation */
> -	uint16_t link_duplex;
> -	/**< ETH_LINK_[HALF_DUPLEX|FULL_DUPLEX], or 0 for autonegotation */
> +	uint32_t link_speeds; /**< bitmap of ETH_LINK_SPEED_XXX of speeds to be
> +				used. ETH_LINK_SPEED_NO_AUTONEG disables link
> +				autonegociation, and a unique speed shall be
> +				set. Otherwise, the bitmap defines the set of
> +				speeds to be advertised. If the special value
> +				ETH_LINK_SPEED_AUTONEG (0) is used, all speeds
> +				supported are advertised.
> +				*/
>  	struct rte_eth_rxmode rxmode; /**< Port RX configuration. */
>  	struct rte_eth_txmode txmode; /**< Port TX configuration. */
>  	uint32_t lpbk_mode; /**< Loopback operation mode. By default the value
> @@ -825,26 +862,6 @@ struct rte_eth_conf {
>  #define DEV_TX_OFFLOAD_QINQ_INSERT 0x00000100
> 
>  /**
> - * Device supported speeds
> - */
> -#define ETH_SPEED_CAP_NOT_PHY	(0)  /*< No phy media > */
> -#define ETH_SPEED_CAP_10M_HD	(1 << 0)  /*< 10 Mbps half-duplex> */
> -#define ETH_SPEED_CAP_10M_FD	(1 << 1)  /*< 10 Mbps full-duplex> */
> -#define ETH_SPEED_CAP_100M_HD	(1 << 2)  /*< 100 Mbps half-duplex> */
> -#define ETH_SPEED_CAP_100M_FD	(1 << 3)  /*< 100 Mbps full-duplex> */
> -#define ETH_SPEED_CAP_1G	(1 << 4)  /*< 1 Gbps > */
> -#define ETH_SPEED_CAP_2_5G	(1 << 5)  /*< 2.5 Gbps > */
> -#define ETH_SPEED_CAP_5G	(1 << 6)  /*< 5 Gbps > */
> -#define ETH_SPEED_CAP_10G	(1 << 7)  /*< 10 Mbps > */
> -#define ETH_SPEED_CAP_20G	(1 << 8)  /*< 20 Gbps > */
> -#define ETH_SPEED_CAP_25G	(1 << 9)  /*< 25 Gbps > */
> -#define ETH_SPEED_CAP_40G	(1 << 10)  /*< 40 Gbps > */
> -#define ETH_SPEED_CAP_50G	(1 << 11)  /*< 50 Gbps > */
> -#define ETH_SPEED_CAP_56G	(1 << 12)  /*< 56 Gbps > */
> -#define ETH_SPEED_CAP_100G	(1 << 13)  /*< 100 Gbps > */
> -
> -
> -/**
>   * Ethernet device information
>   */
>  struct rte_eth_dev_info {
> @@ -1811,6 +1828,22 @@ struct eth_driver {
>  void rte_eth_driver_register(struct eth_driver *eth_drv);
> 
>  /**
> + * Convert a numerical speed in Mbps to a bitmap flag that can be used in
> + * the bitmap link_speeds of the struct rte_eth_conf
> + *
> + * @param
> + *   Numerical speed value in Mbps
> + * @param
> + *   Boolean is duplex (only for 10/100 speeds)
> + * @param
> + *   On success, the converted speed into a bitmap flag
> + * @return
> + *   0 on success, -EINVAL if the speed cannot be mapped
> + */
> +extern int rte_eth_speed_to_bm_flag(uint32_t speed, int duplex,
> +							uint32_t *flag);
> +
> +/**
>   * Configure an Ethernet device.
>   * This function must be invoked first before any other function in the
>   * Ethernet API. This function can also be re-invoked when a device is in the
> --
> 2.1.4

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

* Re: [PATCH v7 3/5] ethdev: redesign link speed config API
  2016-01-29  9:24       ` Ananyev, Konstantin
@ 2016-01-29  9:37         ` Thomas Monjalon
  2016-01-29  9:47           ` Ananyev, Konstantin
  0 siblings, 1 reply; 167+ messages in thread
From: Thomas Monjalon @ 2016-01-29  9:37 UTC (permalink / raw)
  To: Ananyev, Konstantin; +Cc: dev

2016-01-29 09:24, Ananyev, Konstantin:
> Can you avoid modifications in the e1000/base code?
> We do not modify (and maintain) that part on our own.
> Instead we take it straight from Intel ND.  
> So if you feel like these changes are really necessary - please submit a patch
> to ND first, and if your changes will be applied, will pick it up from them. 

I was not aware we can submit a change to ND for Intel base drivers.
What is the procedure please?
May it be documented in the DPDK doc?

Thanks

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

* Re: [PATCH v7 3/5] ethdev: redesign link speed config API
  2016-01-29  9:37         ` Thomas Monjalon
@ 2016-01-29  9:47           ` Ananyev, Konstantin
  2016-01-29  9:53             ` Thomas Monjalon
  0 siblings, 1 reply; 167+ messages in thread
From: Ananyev, Konstantin @ 2016-01-29  9:47 UTC (permalink / raw)
  To: Thomas Monjalon; +Cc: dev

Hi Thomas,

> -----Original Message-----
> From: Thomas Monjalon [mailto:thomas.monjalon@6wind.com]
> Sent: Friday, January 29, 2016 9:38 AM
> To: Ananyev, Konstantin
> Cc: dev@dpdk.org; Marc Sune; Lu, Wenzhuo; Zhang, Helin; Harish Patil; Chen, Jing D; Mcnamara, John
> Subject: Re: [dpdk-dev] [PATCH v7 3/5] ethdev: redesign link speed config API
> 
> 2016-01-29 09:24, Ananyev, Konstantin:
> > Can you avoid modifications in the e1000/base code?
> > We do not modify (and maintain) that part on our own.
> > Instead we take it straight from Intel ND.
> > So if you feel like these changes are really necessary - please submit a patch
> > to ND first, and if your changes will be applied, will pick it up from them.
> 
> I was not aware we can submit a change to ND for Intel base drivers.
> What is the procedure please?

I meant not to the ND directly, but probably to the freebsd e1000 kernel driver.
As I remember, that is the closest one to what we have.
>From my understanding (I might be wrong here):
If they will be accepted, we should see these changes In next code drops from ND.
Konstantin

> May it be documented in the DPDK doc?



> 
> Thanks

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

* Re: [PATCH v7 3/5] ethdev: redesign link speed config API
  2016-01-29  9:47           ` Ananyev, Konstantin
@ 2016-01-29  9:53             ` Thomas Monjalon
  2016-01-29 10:17               ` Ananyev, Konstantin
  0 siblings, 1 reply; 167+ messages in thread
From: Thomas Monjalon @ 2016-01-29  9:53 UTC (permalink / raw)
  To: Ananyev, Konstantin; +Cc: dev

2016-01-29 09:47, Ananyev, Konstantin:
> From: Thomas Monjalon [mailto:thomas.monjalon@6wind.com]
> > 2016-01-29 09:24, Ananyev, Konstantin:
> > > Can you avoid modifications in the e1000/base code?
> > > We do not modify (and maintain) that part on our own.
> > > Instead we take it straight from Intel ND.
> > > So if you feel like these changes are really necessary - please submit a patch
> > > to ND first, and if your changes will be applied, will pick it up from them.
> > 
> > I was not aware we can submit a change to ND for Intel base drivers.
> > What is the procedure please?
> 
> I meant not to the ND directly, but probably to the freebsd e1000 kernel driver.
> As I remember, that is the closest one to what we have.
> From my understanding (I might be wrong here):
> If they will be accepted, we should see these changes In next code drops from ND.

These base drivers are used in several places.
We are allowed to submit a patch in Linux or FreeBSD but not in DPDK
where the base driver is verbatim?
We have an agreement to not touch them in DPDK but I still think the
ND team could consider some patches from dpdk.org.

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

* Re: [PATCH v7 3/5] ethdev: redesign link speed config API
  2016-01-29  9:53             ` Thomas Monjalon
@ 2016-01-29 10:17               ` Ananyev, Konstantin
  2016-01-29 12:40                 ` Marc
  2016-02-01  0:40                 ` Zhang, Helin
  0 siblings, 2 replies; 167+ messages in thread
From: Ananyev, Konstantin @ 2016-01-29 10:17 UTC (permalink / raw)
  To: Thomas Monjalon; +Cc: dev



> -----Original Message-----
> From: Thomas Monjalon [mailto:thomas.monjalon@6wind.com]
> Sent: Friday, January 29, 2016 9:54 AM
> To: Ananyev, Konstantin
> Cc: dev@dpdk.org; Marc Sune; Lu, Wenzhuo; Zhang, Helin; Harish Patil; Chen, Jing D; Mcnamara, John
> Subject: Re: [dpdk-dev] [PATCH v7 3/5] ethdev: redesign link speed config API
> 
> 2016-01-29 09:47, Ananyev, Konstantin:
> > From: Thomas Monjalon [mailto:thomas.monjalon@6wind.com]
> > > 2016-01-29 09:24, Ananyev, Konstantin:
> > > > Can you avoid modifications in the e1000/base code?
> > > > We do not modify (and maintain) that part on our own.
> > > > Instead we take it straight from Intel ND.
> > > > So if you feel like these changes are really necessary - please submit a patch
> > > > to ND first, and if your changes will be applied, will pick it up from them.
> > >
> > > I was not aware we can submit a change to ND for Intel base drivers.
> > > What is the procedure please?
> >
> > I meant not to the ND directly, but probably to the freebsd e1000 kernel driver.
> > As I remember, that is the closest one to what we have.
> > From my understanding (I might be wrong here):
> > If they will be accepted, we should see these changes In next code drops from ND.
> 
> These base drivers are used in several places.
> We are allowed to submit a patch in Linux or FreeBSD but not in DPDK
> where the base driver is verbatim?

Yes, that's my understanding.

> We have an agreement to not touch them in DPDK

Yes.

> but I still think the
> ND team could consider some patches from dpdk.org.

I personally think that would be a good thing,
but it is up to ND guys to make such decision.
 
Konstantin

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

* Re: [PATCH v7 3/5] ethdev: redesign link speed config API
  2016-01-29 10:17               ` Ananyev, Konstantin
@ 2016-01-29 12:40                 ` Marc
  2016-02-01  0:40                 ` Zhang, Helin
  1 sibling, 0 replies; 167+ messages in thread
From: Marc @ 2016-01-29 12:40 UTC (permalink / raw)
  To: Ananyev, Konstantin; +Cc: dev

On 29 January 2016 at 11:17, Ananyev, Konstantin <
konstantin.ananyev@intel.com> wrote:

>
>
> > -----Original Message-----
> > From: Thomas Monjalon [mailto:thomas.monjalon@6wind.com]
> > Sent: Friday, January 29, 2016 9:54 AM
> > To: Ananyev, Konstantin
> > Cc: dev@dpdk.org; Marc Sune; Lu, Wenzhuo; Zhang, Helin; Harish Patil;
> Chen, Jing D; Mcnamara, John
> > Subject: Re: [dpdk-dev] [PATCH v7 3/5] ethdev: redesign link speed
> config API
> >
> > 2016-01-29 09:47, Ananyev, Konstantin:
> > > From: Thomas Monjalon [mailto:thomas.monjalon@6wind.com]
> > > > 2016-01-29 09:24, Ananyev, Konstantin:
> > > > > Can you avoid modifications in the e1000/base code?
>

Yes I can. It was just to save intermediate variables and conversions.
Previously u16 was used to store numeric throughput in mbps in ethdev, and
passed to the inner functions in e1000/base, but it cannot accommodate 100G
values, so I moved it to uint32_t. But I can do the conversion outside of
e1000/base.

> > > > We do not modify (and maintain) that part on our own.
> > > > > Instead we take it straight from Intel ND.
> > > > > So if you feel like these changes are really necessary - please
> submit a patch
> > > > > to ND first, and if your changes will be applied, will pick it up
> from them.
> > > >
> > > > I was not aware we can submit a change to ND for Intel base drivers.
> > > > What is the procedure please?
> > >
> > > I meant not to the ND directly, but probably to the freebsd e1000
> kernel driver.
> > > As I remember, that is the closest one to what we have.
> > > From my understanding (I might be wrong here):
> > > If they will be accepted, we should see these changes In next code
> drops from ND.
> >
> > These base drivers are used in several places.
> > We are allowed to submit a patch in Linux or FreeBSD but not in DPDK
> > where the base driver is verbatim?
>
> Yes, that's my understanding.
>
> > We have an agreement to not touch them in DPDK
>
> Yes.
>
> > but I still think the
> > ND team could consider some patches from dpdk.org.
>
> I personally think that would be a good thing,
> but it is up to ND guys to make such decision.


Agree, but:

Besides documenting (which is necessary), why not importing the sources via
a git submodule pointing to the base project where these files are obtained
(e.g. in  drivers/net/e1000/ext/ or even in the root folder under ext/ and
making symlinks to that in e1000 driver), and just use the raw sources and
headers from there?

That would make it more explicit that these files should not be modified by
DPDK by strictly forbidding so, and that changes should be done via the
repository pointed in drivers/net/e1000/ext/, hence following that
repository's workflow.

marc


>
> Konstantin
>
>

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

* Re: [PATCH v7 5/5] ethdev: add rte_eth_speed_to_bm_flag() to ver. map
  2016-01-29  0:42     ` [PATCH v7 5/5] ethdev: add rte_eth_speed_to_bm_flag() to ver. map Marc Sune
@ 2016-01-29 13:05       ` Panu Matilainen
  2016-01-31 21:21         ` Marc
  0 siblings, 1 reply; 167+ messages in thread
From: Panu Matilainen @ 2016-01-29 13:05 UTC (permalink / raw)
  To: Marc Sune, dev, Wenzhuo Lu, Helin Zhang, Harish Patil, Jing Chen

On 01/29/2016 02:42 AM, Marc Sune wrote:
> Added rte_eth_speed_to_bm_flag() to DPDK2.2 version map.
>
> Signed-off-by: Marc Sune <marcdevel@gmail.com>
> ---
>   lib/librte_ether/rte_ether_version.map | 6 ++++++
>   1 file changed, 6 insertions(+)
>
> diff --git a/lib/librte_ether/rte_ether_version.map b/lib/librte_ether/rte_ether_version.map
> index d8db24d..2c14ad7 100644
> --- a/lib/librte_ether/rte_ether_version.map
> +++ b/lib/librte_ether/rte_ether_version.map
> @@ -117,3 +117,9 @@ DPDK_2.2 {
>
>   	local: *;
>   };
> +
> +DPDK_2.3 {
> +	global:
> +
> +	rte_eth_speed_to_bm_flag;
> +}DPDK_2.2;
>

The version map must be updated in the patch that adds the symbol(s) in 
question to the code, not separately.

	- Panu -

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

* Re: [PATCH v7 3/5] ethdev: redesign link speed config API
  2016-01-29  0:42     ` [PATCH v7 3/5] ethdev: redesign link speed config API Marc Sune
  2016-01-29  9:24       ` Ananyev, Konstantin
@ 2016-01-29 16:16       ` Nélio Laranjeiro
  2016-01-31 21:24         ` Marc
  1 sibling, 1 reply; 167+ messages in thread
From: Nélio Laranjeiro @ 2016-01-29 16:16 UTC (permalink / raw)
  To: Marc Sune; +Cc: dev

Hi Marc,

On Fri, Jan 29, 2016 at 01:42:05AM +0100, Marc Sune wrote:
>[...]
>  /**
> - * Device supported speeds
> - */
> -#define ETH_SPEED_CAP_NOT_PHY	(0)  /*< No phy media > */
> -#define ETH_SPEED_CAP_10M_HD	(1 << 0)  /*< 10 Mbps half-duplex> */
> -#define ETH_SPEED_CAP_10M_FD	(1 << 1)  /*< 10 Mbps full-duplex> */
> -#define ETH_SPEED_CAP_100M_HD	(1 << 2)  /*< 100 Mbps half-duplex> */
> -#define ETH_SPEED_CAP_100M_FD	(1 << 3)  /*< 100 Mbps full-duplex> */
> -#define ETH_SPEED_CAP_1G	(1 << 4)  /*< 1 Gbps > */
> -#define ETH_SPEED_CAP_2_5G	(1 << 5)  /*< 2.5 Gbps > */
> -#define ETH_SPEED_CAP_5G	(1 << 6)  /*< 5 Gbps > */
> -#define ETH_SPEED_CAP_10G	(1 << 7)  /*< 10 Mbps > */
> -#define ETH_SPEED_CAP_20G	(1 << 8)  /*< 20 Gbps > */
> -#define ETH_SPEED_CAP_25G	(1 << 9)  /*< 25 Gbps > */
> -#define ETH_SPEED_CAP_40G	(1 << 10)  /*< 40 Gbps > */
> -#define ETH_SPEED_CAP_50G	(1 << 11)  /*< 50 Gbps > */
> -#define ETH_SPEED_CAP_56G	(1 << 12)  /*< 56 Gbps > */
> -#define ETH_SPEED_CAP_100G	(1 << 13)  /*< 100 Gbps > */
>[...]

In the previous commit you update mlx4.c to use those define, in this
commit it should update it again.

Regards,

-- 
Nélio Laranjeiro
6WIND

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

* Re: [PATCH v7 5/5] ethdev: add rte_eth_speed_to_bm_flag() to ver. map
  2016-01-29 13:05       ` Panu Matilainen
@ 2016-01-31 21:21         ` Marc
  0 siblings, 0 replies; 167+ messages in thread
From: Marc @ 2016-01-31 21:21 UTC (permalink / raw)
  To: Panu Matilainen; +Cc: dev

On 29 January 2016 at 14:05, Panu Matilainen <pmatilai@redhat.com> wrote:

> On 01/29/2016 02:42 AM, Marc Sune wrote:
>
>> Added rte_eth_speed_to_bm_flag() to DPDK2.2 version map.
>>
>> Signed-off-by: Marc Sune <marcdevel@gmail.com>
>> ---
>>   lib/librte_ether/rte_ether_version.map | 6 ++++++
>>   1 file changed, 6 insertions(+)
>>
>> diff --git a/lib/librte_ether/rte_ether_version.map
>> b/lib/librte_ether/rte_ether_version.map
>> index d8db24d..2c14ad7 100644
>> --- a/lib/librte_ether/rte_ether_version.map
>> +++ b/lib/librte_ether/rte_ether_version.map
>> @@ -117,3 +117,9 @@ DPDK_2.2 {
>>
>>         local: *;
>>   };
>> +
>> +DPDK_2.3 {
>> +       global:
>> +
>> +       rte_eth_speed_to_bm_flag;
>> +}DPDK_2.2;
>>
>>
> The version map must be updated in the patch that adds the symbol(s) in
> question to the code, not separately.


Panu,

I will merge it with patch 3.

Marc



>
>
>         - Panu -
>

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

* Re: [PATCH v7 3/5] ethdev: redesign link speed config API
  2016-01-29 16:16       ` Nélio Laranjeiro
@ 2016-01-31 21:24         ` Marc
  0 siblings, 0 replies; 167+ messages in thread
From: Marc @ 2016-01-31 21:24 UTC (permalink / raw)
  To: Nélio Laranjeiro; +Cc: dev

On 29 January 2016 at 17:16, Nélio Laranjeiro <nelio.laranjeiro@6wind.com>
wrote:

> Hi Marc,
>
> On Fri, Jan 29, 2016 at 01:42:05AM +0100, Marc Sune wrote:
> >[...]
> >  /**
> > - * Device supported speeds
> > - */
> > -#define ETH_SPEED_CAP_NOT_PHY        (0)  /*< No phy media > */
> > -#define ETH_SPEED_CAP_10M_HD (1 << 0)  /*< 10 Mbps half-duplex> */
> > -#define ETH_SPEED_CAP_10M_FD (1 << 1)  /*< 10 Mbps full-duplex> */
> > -#define ETH_SPEED_CAP_100M_HD        (1 << 2)  /*< 100 Mbps
> half-duplex> */
> > -#define ETH_SPEED_CAP_100M_FD        (1 << 3)  /*< 100 Mbps
> full-duplex> */
> > -#define ETH_SPEED_CAP_1G     (1 << 4)  /*< 1 Gbps > */
> > -#define ETH_SPEED_CAP_2_5G   (1 << 5)  /*< 2.5 Gbps > */
> > -#define ETH_SPEED_CAP_5G     (1 << 6)  /*< 5 Gbps > */
> > -#define ETH_SPEED_CAP_10G    (1 << 7)  /*< 10 Mbps > */
> > -#define ETH_SPEED_CAP_20G    (1 << 8)  /*< 20 Gbps > */
> > -#define ETH_SPEED_CAP_25G    (1 << 9)  /*< 25 Gbps > */
> > -#define ETH_SPEED_CAP_40G    (1 << 10)  /*< 40 Gbps > */
> > -#define ETH_SPEED_CAP_50G    (1 << 11)  /*< 50 Gbps > */
> > -#define ETH_SPEED_CAP_56G    (1 << 12)  /*< 56 Gbps > */
> > -#define ETH_SPEED_CAP_100G   (1 << 13)  /*< 100 Gbps > */
> >[...]
>
> In the previous commit you update mlx4.c to use those define, in this
> commit it should update it again.
>

Neilo,

You are right, thanks. I will fix that in a new version.

marc



>
> Regards,
>
> --
> Nélio Laranjeiro
> 6WIND
>

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

* Re: [PATCH v7 3/5] ethdev: redesign link speed config API
  2016-01-29 10:17               ` Ananyev, Konstantin
  2016-01-29 12:40                 ` Marc
@ 2016-02-01  0:40                 ` Zhang, Helin
  2016-02-02  0:04                   ` Marc
  1 sibling, 1 reply; 167+ messages in thread
From: Zhang, Helin @ 2016-02-01  0:40 UTC (permalink / raw)
  To: Ananyev, Konstantin, Thomas Monjalon; +Cc: dev



> -----Original Message-----
> From: Ananyev, Konstantin
> Sent: Friday, January 29, 2016 6:18 PM
> To: Thomas Monjalon
> Cc: dev@dpdk.org; Marc Sune; Lu, Wenzhuo; Zhang, Helin; Harish Patil; Chen,
> Jing D; Mcnamara, John
> Subject: RE: [dpdk-dev] [PATCH v7 3/5] ethdev: redesign link speed config
> API
> 
> 
> 
> > -----Original Message-----
> > From: Thomas Monjalon [mailto:thomas.monjalon@6wind.com]
> > Sent: Friday, January 29, 2016 9:54 AM
> > To: Ananyev, Konstantin
> > Cc: dev@dpdk.org; Marc Sune; Lu, Wenzhuo; Zhang, Helin; Harish Patil;
> > Chen, Jing D; Mcnamara, John
> > Subject: Re: [dpdk-dev] [PATCH v7 3/5] ethdev: redesign link speed
> > config API
> >
> > 2016-01-29 09:47, Ananyev, Konstantin:
> > > From: Thomas Monjalon [mailto:thomas.monjalon@6wind.com]
> > > > 2016-01-29 09:24, Ananyev, Konstantin:
> > > > > Can you avoid modifications in the e1000/base code?
> > > > > We do not modify (and maintain) that part on our own.
> > > > > Instead we take it straight from Intel ND.
> > > > > So if you feel like these changes are really necessary - please
> > > > > submit a patch to ND first, and if your changes will be applied, will pick
> it up from them.
> > > >
> > > > I was not aware we can submit a change to ND for Intel base drivers.
> > > > What is the procedure please?
> > >
> > > I meant not to the ND directly, but probably to the freebsd e1000 kernel
> driver.
> > > As I remember, that is the closest one to what we have.
> > > From my understanding (I might be wrong here):
> > > If they will be accepted, we should see these changes In next code drops
> from ND.
> >
> > These base drivers are used in several places.
> > We are allowed to submit a patch in Linux or FreeBSD but not in DPDK
> > where the base driver is verbatim?
> 
> Yes, that's my understanding.
> 
> > We have an agreement to not touch them in DPDK
> 
> Yes.
> 
> > but I still think the
> > ND team could consider some patches from dpdk.org.
> 
> I personally think that would be a good thing, but it is up to ND guys to make
> such decision.
[Zhang, Helin] The key reason of not touching base driver is we don't want to
maintain those source files, and just reuse others. This can help us a lot.
We should try to avoid touching source files in base driver, but if you still insist
something critical or a bug should be faced. First of all we can try to do something
in the dpdk developed source files (e.g. i40e_ethdev.c, i40e_rxtx.c, i40e_osdep.h).
This was what we have done for a long time, and it works quite well.
If there is no other way to fix a bug in base driver, we can try the way like
Konstantin indicated, or let me know, I will try to influence ND. But note that this
might be the lowest efficiency way, due to the complicated process.

Sorry for any inconvenience! This the way we are using now might be the best for
us right now.

Regards,
Heiln

> 
> Konstantin

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

* Re: [PATCH v7 3/5] ethdev: redesign link speed config API
  2016-02-01  0:40                 ` Zhang, Helin
@ 2016-02-02  0:04                   ` Marc
  2016-02-02  0:45                     ` FW: " Zhang, Helin
  0 siblings, 1 reply; 167+ messages in thread
From: Marc @ 2016-02-02  0:04 UTC (permalink / raw)
  To: Zhang, Helin; +Cc: dev

On 1 February 2016 at 01:40, Zhang, Helin <helin.zhang@intel.com> wrote:

>
>
> > -----Original Message-----
> > From: Ananyev, Konstantin
> > Sent: Friday, January 29, 2016 6:18 PM
> > To: Thomas Monjalon
> > Cc: dev@dpdk.org; Marc Sune; Lu, Wenzhuo; Zhang, Helin; Harish Patil;
> Chen,
> > Jing D; Mcnamara, John
> > Subject: RE: [dpdk-dev] [PATCH v7 3/5] ethdev: redesign link speed config
> > API
> >
> >
> >
> > > -----Original Message-----
> > > From: Thomas Monjalon [mailto:thomas.monjalon@6wind.com]
> > > Sent: Friday, January 29, 2016 9:54 AM
> > > To: Ananyev, Konstantin
> > > Cc: dev@dpdk.org; Marc Sune; Lu, Wenzhuo; Zhang, Helin; Harish Patil;
> > > Chen, Jing D; Mcnamara, John
> > > Subject: Re: [dpdk-dev] [PATCH v7 3/5] ethdev: redesign link speed
> > > config API
> > >
> > > 2016-01-29 09:47, Ananyev, Konstantin:
> > > > From: Thomas Monjalon [mailto:thomas.monjalon@6wind.com]
> > > > > 2016-01-29 09:24, Ananyev, Konstantin:
> > > > > > Can you avoid modifications in the e1000/base code?
> > > > > > We do not modify (and maintain) that part on our own.
> > > > > > Instead we take it straight from Intel ND.
> > > > > > So if you feel like these changes are really necessary - please
> > > > > > submit a patch to ND first, and if your changes will be applied,
> will pick
> > it up from them.
> > > > >
> > > > > I was not aware we can submit a change to ND for Intel base
> drivers.
> > > > > What is the procedure please?
> > > >
> > > > I meant not to the ND directly, but probably to the freebsd e1000
> kernel
> > driver.
> > > > As I remember, that is the closest one to what we have.
> > > > From my understanding (I might be wrong here):
> > > > If they will be accepted, we should see these changes In next code
> drops
> > from ND.
> > >
> > > These base drivers are used in several places.
> > > We are allowed to submit a patch in Linux or FreeBSD but not in DPDK
> > > where the base driver is verbatim?
> >
> > Yes, that's my understanding.
> >
> > > We have an agreement to not touch them in DPDK
> >
> > Yes.
> >
> > > but I still think the
> > > ND team could consider some patches from dpdk.org.
> >
> > I personally think that would be a good thing, but it is up to ND guys
> to make
> > such decision.
> [Zhang, Helin] The key reason of not touching base driver is we don't want
> to
> maintain those source files, and just reuse others.


So files under base/ strictly copies of what is in this other Intel
repository (ND) or there are modifications?

If IIRC rte_link was crafted so that matches e1000 (at least) so that link
reads can be done atomically. I think it makes more sense that ethdev has a
generic, device independent struct and that drivers handle the translation,
if necessary. Do we agree on this?

This can help us a lot.
> We should try to avoid touching source files in base driver, but if you
> still insist
> something critical or a bug should be faced. First of all we can try to do
> something
> in the dpdk developed source files (e.g. i40e_ethdev.c, i40e_rxtx.c,
> i40e_osdep.h).
> This was what we have done for a long time, and it works quite well.
> If there is no other way to fix a bug in base driver, we can try the way
> like
> Konstantin indicated, or let me know, I will try to influence ND. But note
> that this
> might be the lowest efficiency way, due to the complicated process.


> Sorry for any inconvenience! This the way we are using now might be the
> best for
> us right now.
>

I will go back and redesign commit 3 in the series once more. I will need
some time (other things in the pipeline). I would have appreciated rising
this red flag in one of the 6 previous versions.

marc


>
> Regards,
> Heiln
>
> >
> > Konstantin
>
>

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

* FW: [PATCH v7 3/5] ethdev: redesign link speed config API
  2016-02-02  0:04                   ` Marc
@ 2016-02-02  0:45                     ` Zhang, Helin
  0 siblings, 0 replies; 167+ messages in thread
From: Zhang, Helin @ 2016-02-02  0:45 UTC (permalink / raw)
  To: Marc; +Cc: dev



>From: marc.sune@gmail.com [mailto:marc.sune@gmail.com] On Behalf Of Marc
>Sent: Tuesday, February 2, 2016 8:04 AM
>To: Zhang, Helin
>Cc: Ananyev, Konstantin; Thomas Monjalon; dev@dpdk.org; Lu, Wenzhuo; Harish Patil; Chen, Jing D; Mcnamara, John
>Subject: Re: [dpdk-dev] [PATCH v7 3/5] ethdev: redesign link speed config API
>
>
>
>On 1 February 2016 at 01:40, Zhang, Helin <helin.zhang@intel.com> wrote:
>
>
>> -----Original Message-----
>> From: Ananyev, Konstantin
>> Sent: Friday, January 29, 2016 6:18 PM
>> To: Thomas Monjalon
>> Cc: dev@dpdk.org; Marc Sune; Lu, Wenzhuo; Zhang, Helin; Harish Patil; Chen,
>> Jing D; Mcnamara, John
>> Subject: RE: [dpdk-dev] [PATCH v7 3/5] ethdev: redesign link speed config
>> API
>>
>>
>>
>> > -----Original Message-----
>> > From: Thomas Monjalon [mailto:thomas.monjalon@6wind.com]
>> > Sent: Friday, January 29, 2016 9:54 AM
>> > To: Ananyev, Konstantin
>> > Cc: dev@dpdk.org; Marc Sune; Lu, Wenzhuo; Zhang, Helin; Harish Patil;
>> > Chen, Jing D; Mcnamara, John
>> > Subject: Re: [dpdk-dev] [PATCH v7 3/5] ethdev: redesign link speed
>> > config API
>> >
>> > 2016-01-29 09:47, Ananyev, Konstantin:
>> > > From: Thomas Monjalon [mailto:thomas.monjalon@6wind.com]
>> > > > 2016-01-29 09:24, Ananyev, Konstantin:
>> > > > > Can you avoid modifications in the e1000/base code?
>> > > > > We do not modify (and maintain) that part on our own.
>> > > > > Instead we take it straight from Intel ND.
>> > > > > So if you feel like these changes are really necessary - please
>> > > > > submit a patch to ND first, and if your changes will be applied, will pick
>> it up from them.
>> > > >
>> > > > I was not aware we can submit a change to ND for Intel base drivers.
>> > > > What is the procedure please?
>> > >
>> > > I meant not to the ND directly, but probably to the freebsd e1000 kernel
>> driver.
>> > > As I remember, that is the closest one to what we have.
>> > > From my understanding (I might be wrong here):
>> > > If they will be accepted, we should see these changes In next code drops
>> from ND.
>> >
>> > These base drivers are used in several places.
>> > We are allowed to submit a patch in Linux or FreeBSD but not in DPDK
>> > where the base driver is verbatim?
>>
>> Yes, that's my understanding.
>>
>> > We have an agreement to not touch them in DPDK
>>
>> Yes.
>>
>> > but I still think the
>> > ND team could consider some patches from dpdk.org.
>>
>> I personally think that would be a good thing, but it is up to ND guys to make
>> such decision.
>[Zhang, Helin] The key reason of not touching base driver is we don't want to
>maintain those source files, and just reuse others. 
>
>So files under base/ strictly copies of what is in this other Intel repository (ND) or there are modifications?
Long time ago, those source files were copied from FreeBSD version of driver, without any modification.
Though there is a bit different from that time, but they are similar.
Note that 'base/i40e_osdep.h or ixgbe_osdep.h' is the only file we can modify to support DPDK.
Of cause, all other files than base driver are what we developed, and can be modified.

>
>If IIRC rte_link was crafted so that matches e1000 (at least) so that link reads can be done atomically. I think it makes more sense that ethdev has a generic, device independent struct and that drivers handle the translation, if necessary. Do we agree on this?
I agree with you to have a generic structure in ethdev, and it can be filled with information obtained from base driver.

>
>This can help us a lot.
>We should try to avoid touching source files in base driver, but if you still insist
>something critical or a bug should be faced. First of all we can try to do something
>in the dpdk developed source files (e.g. i40e_ethdev.c, i40e_rxtx.c, i40e_osdep.h).
>This was what we have done for a long time, and it works quite well.
>If there is no other way to fix a bug in base driver, we can try the way like
>Konstantin indicated, or let me know, I will try to influence ND. But note that this
>might be the lowest efficiency way, due to the complicated process. 
>
>Sorry for any inconvenience! This the way we are using now might be the best for
>us right now.
>
>I will go back and redesign commit 3 in the series once more. I will need some time (other things in the pipeline). I would have appreciated rising this red flag in one of the 6 previous versions.
Thank you very much for the helps, and patience!

Regards,
Helin

>
>marc
> 
>
>Regards,
>Heiln
>
>>
>> Konstantin
>

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

* [PATCH v8 0/4] ethdev: add speed capabilities and refactor link API
  2016-01-29  0:42   ` [PATCH v7 " Marc Sune
                       ` (4 preceding siblings ...)
  2016-01-29  0:42     ` [PATCH v7 5/5] ethdev: add rte_eth_speed_to_bm_flag() to ver. map Marc Sune
@ 2016-02-14 22:17     ` Marc Sune
  2016-02-14 22:17       ` [PATCH v8 1/4] ethdev: Added ETH_SPEED_CAP bitmap for ports Marc Sune
                         ` (4 more replies)
  5 siblings, 5 replies; 167+ messages in thread
From: Marc Sune @ 2016-02-14 22:17 UTC (permalink / raw)
  To: dev, Wenzhuo Lu, Helin Zhang, Harish Patil, Jing Chen

The current rte_eth_dev_info abstraction does not provide any mechanism to
get the supported speed(s) of an ethdev.

For some drivers (e.g. ixgbe), an educated guess could be done based on the
driver's name (driver_name in rte_eth_dev_info), see:

http://dpdk.org/ml/archives/dev/2013-August/000412.html

However, i) doing string comparisons is annoying, and can silently
break existing applications if PMDs change their names ii) it does not
provide all the supported capabilities of the ethdev iii) for some drivers it
is impossible determine correctly the (max) speed by the application
(e.g. in i40, distinguish between XL710 and X710).

In addition, the link APIs do not allow to define a set of advertised link
speeds for autonegociation.

This series of patches adds the following capabilities:

* speed_capa bitmap in rte_eth_dev_info, which is filled by the PMDs
  according to the physical device capabilities.
* refactors link API in ethdev to allow the definition of the advertised
  link speeds, fix speed (no auto-negociation) or advertise all supported
  speeds (default).

WARNING: this patch series, specifically 3/4, is NOT tested for most of the
PMDs, due to the lack of hardware. Only generic EM is tested (VM). Reviewing
and testing required by PMD maintainers.

* * * * *

v2: rebase, converted speed_capa into 32 bits bitmap, fixed alignment
(checkpatch).

v3: rebase to v2.1. unified ETH_LINK_SPEED and ETH_SPEED_CAP into ETH_SPEED.
    Converted field speed in struct rte_eth_conf to speed, to allow a bitmap
    for defining the announced speeds, as suggested M. Brorup. Fixed spelling
    issues.

v4: fixed errata in the documentation of field speeds of rte_eth_conf, and
    commit 1/2 message. rebased to v2.1.0. v3 was incorrectly based on
    ~2.1.0-rc1.

v5: revert to v2 speed capabilities patch. Fixed MLX4 speed capabilities
    (thanks N. Laranjeiro). Refactored link speed API to allow setting
    advertised speeds (3/4). Added NO_AUTONEG option to explicitely disable
    auto-negociation. Updated 2.2 rel. notes (4/4). Rebased to current HEAD.

v6: Move link_duplex to be part of bitfield. Fixed i40 autoneg flag link
    update code. Added rte_eth_speed_to_bm_flag() to .map file. Fixed other
    spelling issues. Rebased to current HEAD.

v7: Rebased to current HEAD. Moved documentation to v2.3. Still needs testing
    from PMD maintainers.

v8: Rebased to current HEAD. Modified em driver impl. to not touch base files.
    Merged patch 5 into 3 (map file). Changed numeric speed to a 64 bit value.
    Filled-in speed capabilities for drivers bnx2x, cxgbe, mlx5 and nfp in
    addition to the ones of previous patch sets.

Marc Sune (4):
  ethdev: Added ETH_SPEED_CAP bitmap for ports
  ethdev: Fill speed capability bitmaps in the PMDs
  ethdev: redesign link speed config API
  doc: update with link changes

 app/test-pipeline/init.c                  |   2 +-
 app/test-pmd/cmdline.c                    | 124 +++++++++++++++---------------
 app/test-pmd/config.c                     |   4 +-
 app/test/virtual_pmd.c                    |   4 +-
 doc/guides/rel_notes/release_2_3.rst      | 102 ++++++++++++++++++++++++
 drivers/net/af_packet/rte_eth_af_packet.c |   5 +-
 drivers/net/bnx2x/bnx2x_ethdev.c          |   7 +-
 drivers/net/bonding/rte_eth_bond_8023ad.c |  14 ++--
 drivers/net/cxgbe/base/t4_hw.c            |   8 +-
 drivers/net/cxgbe/cxgbe_ethdev.c          |   1 +
 drivers/net/e1000/em_ethdev.c             | 112 ++++++++++++++-------------
 drivers/net/e1000/igb_ethdev.c            | 107 +++++++++++++++-----------
 drivers/net/fm10k/fm10k_ethdev.c          |   6 +-
 drivers/net/i40e/i40e_ethdev.c            |  78 +++++++++++--------
 drivers/net/i40e/i40e_ethdev_vf.c         |  11 +--
 drivers/net/ixgbe/ixgbe_ethdev.c          |  80 +++++++++----------
 drivers/net/mlx4/mlx4.c                   |   6 ++
 drivers/net/mlx5/mlx5_ethdev.c            |   5 ++
 drivers/net/mpipe/mpipe_tilegx.c          |   6 +-
 drivers/net/nfp/nfp_net.c                 |   4 +-
 drivers/net/null/rte_eth_null.c           |   5 +-
 drivers/net/pcap/rte_eth_pcap.c           |   9 ++-
 drivers/net/ring/rte_eth_ring.c           |   5 +-
 drivers/net/virtio/virtio_ethdev.c        |   2 +-
 drivers/net/virtio/virtio_ethdev.h        |   2 -
 drivers/net/vmxnet3/vmxnet3_ethdev.c      |   5 +-
 drivers/net/xenvirt/rte_eth_xenvirt.c     |   5 +-
 examples/ip_pipeline/config_parse.c       |   3 +-
 lib/librte_ether/rte_ethdev.c             |  49 ++++++++++++
 lib/librte_ether/rte_ethdev.h             |  97 ++++++++++++++++++-----
 lib/librte_ether/rte_ether_version.map    |   6 ++
 31 files changed, 573 insertions(+), 301 deletions(-)
 create mode 100644 doc/guides/rel_notes/release_2_3.rst

-- 
2.1.4

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

* [PATCH v8 1/4] ethdev: Added ETH_SPEED_CAP bitmap for ports
  2016-02-14 22:17     ` [PATCH v8 0/4] ethdev: add speed capabilities and refactor link API Marc Sune
@ 2016-02-14 22:17       ` Marc Sune
  2016-02-16 20:42         ` Stephen Hemminger
  2016-02-14 22:17       ` [PATCH v8 2/4] ethdev: Fill speed capability bitmaps in the PMDs Marc Sune
                         ` (3 subsequent siblings)
  4 siblings, 1 reply; 167+ messages in thread
From: Marc Sune @ 2016-02-14 22:17 UTC (permalink / raw)
  To: dev, Wenzhuo Lu, Helin Zhang, Harish Patil, Jing Chen

Added constants and bitmap to struct rte_eth_dev_info to be used by PMDs.

Signed-off-by: Marc Sune <marcdevel@gmail.com>
---
 lib/librte_ether/rte_ethdev.h | 24 ++++++++++++++++++++++++
 1 file changed, 24 insertions(+)

diff --git a/lib/librte_ether/rte_ethdev.h b/lib/librte_ether/rte_ethdev.h
index 16da821..83ddbb7 100644
--- a/lib/librte_ether/rte_ethdev.h
+++ b/lib/librte_ether/rte_ethdev.h
@@ -824,6 +824,29 @@ struct rte_eth_conf {
 #define DEV_TX_OFFLOAD_OUTER_IPV4_CKSUM 0x00000080 /**< Used for tunneling packet. */
 #define DEV_TX_OFFLOAD_QINQ_INSERT 0x00000100
 
+/**
+ * Device supported speeds
+ */
+#define ETH_SPEED_CAP_NOT_PHY	(0)  /*< No phy media > */
+#define ETH_SPEED_CAP_10M_HD	(1 << 0)  /*< 10 Mbps half-duplex> */
+#define ETH_SPEED_CAP_10M_FD	(1 << 1)  /*< 10 Mbps full-duplex> */
+#define ETH_SPEED_CAP_100M_HD	(1 << 2)  /*< 100 Mbps half-duplex> */
+#define ETH_SPEED_CAP_100M_FD	(1 << 3)  /*< 100 Mbps full-duplex> */
+#define ETH_SPEED_CAP_1G	(1 << 4)  /*< 1 Gbps > */
+#define ETH_SPEED_CAP_2_5G	(1 << 5)  /*< 2.5 Gbps > */
+#define ETH_SPEED_CAP_5G	(1 << 6)  /*< 5 Gbps > */
+#define ETH_SPEED_CAP_10G	(1 << 7)  /*< 10 Mbps > */
+#define ETH_SPEED_CAP_20G	(1 << 8)  /*< 20 Gbps > */
+#define ETH_SPEED_CAP_25G	(1 << 9)  /*< 25 Gbps > */
+#define ETH_SPEED_CAP_40G	(1 << 10)  /*< 40 Gbps > */
+#define ETH_SPEED_CAP_50G	(1 << 11)  /*< 50 Gbps > */
+#define ETH_SPEED_CAP_56G	(1 << 12)  /*< 56 Gbps > */
+#define ETH_SPEED_CAP_100G	(1 << 13)  /*< 100 Gbps > */
+
+
+/**
+ * Ethernet device information
+ */
 struct rte_eth_dev_info {
 	struct rte_pci_device *pci_dev; /**< Device PCI information. */
 	const char *driver_name; /**< Device Driver name. */
@@ -852,6 +875,7 @@ struct rte_eth_dev_info {
 	uint16_t vmdq_pool_base;  /**< First ID of VMDQ pools. */
 	struct rte_eth_desc_lim rx_desc_lim;  /**< RX descriptors limits */
 	struct rte_eth_desc_lim tx_desc_lim;  /**< TX descriptors limits */
+	uint32_t speed_capa;  /**< Supported speeds bitmap (ETH_SPEED_CAP_). */
 };
 
 /**
-- 
2.1.4

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

* [PATCH v8 2/4] ethdev: Fill speed capability bitmaps in the PMDs
  2016-02-14 22:17     ` [PATCH v8 0/4] ethdev: add speed capabilities and refactor link API Marc Sune
  2016-02-14 22:17       ` [PATCH v8 1/4] ethdev: Added ETH_SPEED_CAP bitmap for ports Marc Sune
@ 2016-02-14 22:17       ` Marc Sune
  2016-02-15  8:43         ` Nélio Laranjeiro
  2016-02-15 14:43         ` Rahul Lakkireddy
  2016-02-14 22:17       ` [PATCH v8 3/4] ethdev: redesign link speed config API Marc Sune
                         ` (2 subsequent siblings)
  4 siblings, 2 replies; 167+ messages in thread
From: Marc Sune @ 2016-02-14 22:17 UTC (permalink / raw)
  To: dev, Wenzhuo Lu, Helin Zhang, Harish Patil, Jing Chen

Added speed capabilities to all pmds supporting physical NICs:

* e1000
* ixgbe
* i40
* bnx2x
* cxgbe
* mlx4
* mlx5
* nfp
* fm10k

Signed-off-by: Marc Sune <marcdevel@gmail.com>
---
 drivers/net/bnx2x/bnx2x_ethdev.c |  1 +
 drivers/net/cxgbe/cxgbe_ethdev.c |  1 +
 drivers/net/e1000/em_ethdev.c    |  6 ++++++
 drivers/net/e1000/igb_ethdev.c   |  6 ++++++
 drivers/net/fm10k/fm10k_ethdev.c |  4 ++++
 drivers/net/i40e/i40e_ethdev.c   |  9 +++++++++
 drivers/net/ixgbe/ixgbe_ethdev.c | 10 ++++++++++
 drivers/net/mlx4/mlx4.c          |  4 ++++
 drivers/net/mlx5/mlx5_ethdev.c   |  5 +++++
 drivers/net/nfp/nfp_net.c        |  2 ++
 10 files changed, 48 insertions(+)

diff --git a/drivers/net/bnx2x/bnx2x_ethdev.c b/drivers/net/bnx2x/bnx2x_ethdev.c
index 69df02e..b547ac3 100644
--- a/drivers/net/bnx2x/bnx2x_ethdev.c
+++ b/drivers/net/bnx2x/bnx2x_ethdev.c
@@ -347,6 +347,7 @@ bnx2x_dev_infos_get(struct rte_eth_dev *dev, __rte_unused struct rte_eth_dev_inf
 	dev_info->min_rx_bufsize = BNX2X_MIN_RX_BUF_SIZE;
 	dev_info->max_rx_pktlen  = BNX2X_MAX_RX_PKT_LEN;
 	dev_info->max_mac_addrs  = BNX2X_MAX_MAC_ADDRS;
+	dev_info->speed_capa = ETH_SPEED_CAP_10G | ETH_SPEED_CAP_20G;
 }
 
 static void
diff --git a/drivers/net/cxgbe/cxgbe_ethdev.c b/drivers/net/cxgbe/cxgbe_ethdev.c
index 97ef152..203e119 100644
--- a/drivers/net/cxgbe/cxgbe_ethdev.c
+++ b/drivers/net/cxgbe/cxgbe_ethdev.c
@@ -171,6 +171,7 @@ static void cxgbe_dev_info_get(struct rte_eth_dev *eth_dev,
 
 	device_info->rx_desc_lim = cxgbe_desc_lim;
 	device_info->tx_desc_lim = cxgbe_desc_lim;
+	device_info->speed_capa = ETH_SPEED_CAP_10G | ETH_SPEED_CAP_40G;
 }
 
 static void cxgbe_dev_promiscuous_enable(struct rte_eth_dev *eth_dev)
diff --git a/drivers/net/e1000/em_ethdev.c b/drivers/net/e1000/em_ethdev.c
index 4a843fe..e40dc37 100644
--- a/drivers/net/e1000/em_ethdev.c
+++ b/drivers/net/e1000/em_ethdev.c
@@ -1023,6 +1023,12 @@ eth_em_infos_get(struct rte_eth_dev *dev, struct rte_eth_dev_info *dev_info)
 		.nb_min = E1000_MIN_RING_DESC,
 		.nb_align = EM_TXD_ALIGN,
 	};
+
+	dev_info->speed_capa = ETH_SPEED_CAP_10M_HD |
+					ETH_SPEED_CAP_10M_FD |
+					ETH_SPEED_CAP_100M_HD |
+					ETH_SPEED_CAP_100M_FD |
+					ETH_SPEED_CAP_1G;
 }
 
 /* return 0 means link status changed, -1 means not changed */
diff --git a/drivers/net/e1000/igb_ethdev.c b/drivers/net/e1000/igb_ethdev.c
index 4ed5e95..7eac8ea 100644
--- a/drivers/net/e1000/igb_ethdev.c
+++ b/drivers/net/e1000/igb_ethdev.c
@@ -1908,6 +1908,12 @@ eth_igb_infos_get(struct rte_eth_dev *dev, struct rte_eth_dev_info *dev_info)
 
 	dev_info->rx_desc_lim = rx_desc_lim;
 	dev_info->tx_desc_lim = tx_desc_lim;
+
+	dev_info->speed_capa = ETH_SPEED_CAP_10M_HD |
+					ETH_SPEED_CAP_10M_FD |
+					ETH_SPEED_CAP_100M_HD |
+					ETH_SPEED_CAP_100M_FD |
+					ETH_SPEED_CAP_1G;
 }
 
 static void
diff --git a/drivers/net/fm10k/fm10k_ethdev.c b/drivers/net/fm10k/fm10k_ethdev.c
index 421266b..2e6ec60 100644
--- a/drivers/net/fm10k/fm10k_ethdev.c
+++ b/drivers/net/fm10k/fm10k_ethdev.c
@@ -1333,6 +1333,10 @@ fm10k_dev_infos_get(struct rte_eth_dev *dev,
 		.nb_min = FM10K_MIN_TX_DESC,
 		.nb_align = FM10K_MULT_TX_DESC,
 	};
+
+	dev_info->speed_capa = ETH_SPEED_CAP_1G | ETH_SPEED_CAP_2_5G |
+					ETH_SPEED_CAP_10G | ETH_SPEED_CAP_25G |
+					ETH_SPEED_CAP_40G | ETH_SPEED_CAP_100G;
 }
 
 static int
diff --git a/drivers/net/i40e/i40e_ethdev.c b/drivers/net/i40e/i40e_ethdev.c
index ef24122..78a0cbd 100644
--- a/drivers/net/i40e/i40e_ethdev.c
+++ b/drivers/net/i40e/i40e_ethdev.c
@@ -2233,6 +2233,7 @@ static void
 i40e_dev_info_get(struct rte_eth_dev *dev, struct rte_eth_dev_info *dev_info)
 {
 	struct i40e_pf *pf = I40E_DEV_PRIVATE_TO_PF(dev->data->dev_private);
+	struct i40e_hw *hw = I40E_DEV_PRIVATE_TO_HW(dev->data->dev_private);
 	struct i40e_vsi *vsi = pf->main_vsi;
 
 	dev_info->max_rx_queues = vsi->nb_qps;
@@ -2304,6 +2305,14 @@ i40e_dev_info_get(struct rte_eth_dev *dev, struct rte_eth_dev_info *dev_info)
 		dev_info->max_rx_queues += dev_info->vmdq_queue_num;
 		dev_info->max_tx_queues += dev_info->vmdq_queue_num;
 	}
+
+	if (i40e_is_40G_device(hw->device_id))
+		/* For XL710 */
+		dev_info->speed_capa = ETH_SPEED_CAP_1G | ETH_SPEED_CAP_10G;
+	else
+		/* For X710 */
+		dev_info->speed_capa = ETH_SPEED_CAP_10G | ETH_SPEED_CAP_40G;
+
 }
 
 static int
diff --git a/drivers/net/ixgbe/ixgbe_ethdev.c b/drivers/net/ixgbe/ixgbe_ethdev.c
index 3e6fe86..7e29c18 100644
--- a/drivers/net/ixgbe/ixgbe_ethdev.c
+++ b/drivers/net/ixgbe/ixgbe_ethdev.c
@@ -2827,6 +2827,16 @@ ixgbe_dev_info_get(struct rte_eth_dev *dev, struct rte_eth_dev_info *dev_info)
 	dev_info->hash_key_size = IXGBE_HKEY_MAX_INDEX * sizeof(uint32_t);
 	dev_info->reta_size = ixgbe_reta_size_get(hw->mac.type);
 	dev_info->flow_type_rss_offloads = IXGBE_RSS_OFFLOAD_ALL;
+
+	dev_info->speed_capa = ETH_SPEED_CAP_1G | ETH_SPEED_CAP_10G;
+
+	if (hw->mac.type == ixgbe_mac_X540 ||
+	    hw->mac.type == ixgbe_mac_X540_vf ||
+	    hw->mac.type == ixgbe_mac_X550 ||
+	    hw->mac.type == ixgbe_mac_X550_vf)
+
+		dev_info->speed_capa |= ETH_SPEED_CAP_100M_FD /*|
+					ETH_SPEED_CAP_100M_HD*/;
 }
 
 static void
diff --git a/drivers/net/mlx4/mlx4.c b/drivers/net/mlx4/mlx4.c
index ee00151..c5688a7 100644
--- a/drivers/net/mlx4/mlx4.c
+++ b/drivers/net/mlx4/mlx4.c
@@ -4264,6 +4264,10 @@ mlx4_dev_infos_get(struct rte_eth_dev *dev, struct rte_eth_dev_info *info)
 		 0);
 	if (priv_get_ifname(priv, &ifname) == 0)
 		info->if_index = if_nametoindex(ifname);
+
+	info->speed_capa = ETH_SPEED_CAP_10G |ETH_SPEED_CAP_40G |
+					ETH_SPEED_CAP_56G;
+
 	priv_unlock(priv);
 }
 
diff --git a/drivers/net/mlx5/mlx5_ethdev.c b/drivers/net/mlx5/mlx5_ethdev.c
index 1159fa3..99dac09 100644
--- a/drivers/net/mlx5/mlx5_ethdev.c
+++ b/drivers/net/mlx5/mlx5_ethdev.c
@@ -523,6 +523,11 @@ mlx5_dev_infos_get(struct rte_eth_dev *dev, struct rte_eth_dev_info *info)
 	 * size if it is not fixed.
 	 * The API should be updated to solve this problem. */
 	info->reta_size = priv->ind_table_max_size;
+
+	info->speed_capa = ETH_SPEED_CAP_1G | ETH_SPEED_CAP_10G |
+					ETH_SPEED_CAP_10G | ETH_SPEED_CAP_40G |
+					ETH_SPEED_CAP_56G;
+
 	priv_unlock(priv);
 }
 
diff --git a/drivers/net/nfp/nfp_net.c b/drivers/net/nfp/nfp_net.c
index fd4dd39..98a957a 100644
--- a/drivers/net/nfp/nfp_net.c
+++ b/drivers/net/nfp/nfp_net.c
@@ -1071,6 +1071,8 @@ nfp_net_infos_get(struct rte_eth_dev *dev, struct rte_eth_dev_info *dev_info)
 
 	dev_info->reta_size = NFP_NET_CFG_RSS_ITBL_SZ;
 	dev_info->hash_key_size = NFP_NET_CFG_RSS_KEY_SZ;
+
+	dev_info->speed_capa = ETH_SPEED_CAP_50G | ETH_SPEED_CAP_100G;
 }
 
 static uint32_t
-- 
2.1.4

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

* [PATCH v8 3/4] ethdev: redesign link speed config API
  2016-02-14 22:17     ` [PATCH v8 0/4] ethdev: add speed capabilities and refactor link API Marc Sune
  2016-02-14 22:17       ` [PATCH v8 1/4] ethdev: Added ETH_SPEED_CAP bitmap for ports Marc Sune
  2016-02-14 22:17       ` [PATCH v8 2/4] ethdev: Fill speed capability bitmaps in the PMDs Marc Sune
@ 2016-02-14 22:17       ` Marc Sune
  2016-02-15  8:46         ` Nélio Laranjeiro
  2016-02-16 10:28         ` Matej Vido
  2016-02-14 22:17       ` [PATCH v8 4/4] doc: update with link changes Marc Sune
  2016-03-01  0:45       ` [PATCH v9 0/4] ethdev: add speed capabilities and refactor link API Marc Sune
  4 siblings, 2 replies; 167+ messages in thread
From: Marc Sune @ 2016-02-14 22:17 UTC (permalink / raw)
  To: dev, Wenzhuo Lu, Helin Zhang, Harish Patil, Jing Chen

This patch redesigns the API to set the link speed/s configure
for an ethernet port. Specifically:

- it allows to define a set of advertised speeds for
  auto-negociation.
- it allows to disable link auto-negociation (single fixed speed).
- default: auto-negociate all supported speeds.

Other changes:

* Added utility MACROs ETH_SPEED_NUM_XXX with the numeric
  values of all supported link speeds, in Mbps.
* Converted link_speed to uint64_t to accomodate 100G speeds
  and beyond (bug).
* Added autoneg flag in struct rte_eth_link to indicate if
  link speed was a result of auto-negociation or was fixed
  by configuration.
* Added utility function to convert numeric speeds to bitmap
  fields.
* Added rte_eth_speed_to_bm_flag() to version map.

Signed-off-by: Marc Sune <marcdevel@gmail.com>
---
 app/test-pipeline/init.c                  |   2 +-
 app/test-pmd/cmdline.c                    | 124 +++++++++++++++---------------
 app/test-pmd/config.c                     |   4 +-
 app/test/virtual_pmd.c                    |   4 +-
 drivers/net/af_packet/rte_eth_af_packet.c |   5 +-
 drivers/net/bnx2x/bnx2x_ethdev.c          |   8 +-
 drivers/net/bonding/rte_eth_bond_8023ad.c |  14 ++--
 drivers/net/cxgbe/base/t4_hw.c            |   8 +-
 drivers/net/cxgbe/cxgbe_ethdev.c          |   2 +-
 drivers/net/e1000/em_ethdev.c             | 116 ++++++++++++++--------------
 drivers/net/e1000/igb_ethdev.c            | 111 +++++++++++++-------------
 drivers/net/fm10k/fm10k_ethdev.c          |   8 +-
 drivers/net/i40e/i40e_ethdev.c            |  73 +++++++++---------
 drivers/net/i40e/i40e_ethdev_vf.c         |  11 +--
 drivers/net/ixgbe/ixgbe_ethdev.c          |  78 ++++++++-----------
 drivers/net/mlx4/mlx4.c                   |   6 +-
 drivers/net/mpipe/mpipe_tilegx.c          |   6 +-
 drivers/net/nfp/nfp_net.c                 |   4 +-
 drivers/net/null/rte_eth_null.c           |   5 +-
 drivers/net/pcap/rte_eth_pcap.c           |   9 ++-
 drivers/net/ring/rte_eth_ring.c           |   5 +-
 drivers/net/virtio/virtio_ethdev.c        |   2 +-
 drivers/net/virtio/virtio_ethdev.h        |   2 -
 drivers/net/vmxnet3/vmxnet3_ethdev.c      |   5 +-
 drivers/net/xenvirt/rte_eth_xenvirt.c     |   5 +-
 examples/ip_pipeline/config_parse.c       |   3 +-
 lib/librte_ether/rte_ethdev.c             |  49 ++++++++++++
 lib/librte_ether/rte_ethdev.h             | 113 +++++++++++++++++----------
 lib/librte_ether/rte_ether_version.map    |   6 ++
 29 files changed, 443 insertions(+), 345 deletions(-)

diff --git a/app/test-pipeline/init.c b/app/test-pipeline/init.c
index db2196b..08fb041 100644
--- a/app/test-pipeline/init.c
+++ b/app/test-pipeline/init.c
@@ -200,7 +200,7 @@ app_ports_check_link(void)
 		port = (uint8_t) app.ports[i];
 		memset(&link, 0, sizeof(link));
 		rte_eth_link_get_nowait(port, &link);
-		RTE_LOG(INFO, USER1, "Port %u (%u Gbps) %s\n",
+		RTE_LOG(INFO, USER1, "Port %u (%" PRIu64 " Gbps) %s\n",
 			port,
 			link.link_speed / 1000,
 			link.link_status ? "UP" : "DOWN");
diff --git a/app/test-pmd/cmdline.c b/app/test-pmd/cmdline.c
index 52e9f5f..57ad25f 100644
--- a/app/test-pmd/cmdline.c
+++ b/app/test-pmd/cmdline.c
@@ -956,14 +956,65 @@ struct cmd_config_speed_all {
 	cmdline_fixed_string_t value2;
 };
 
+static int
+parse_and_check_speed_duplex(char *value1, char *value2, uint32_t *link_speed)
+{
+
+	int duplex;
+
+	if (!strcmp(value2, "half")) {
+		duplex = 0;
+	} else if (!strcmp(value2, "full")) {
+		duplex = 1;
+	} else if (!strcmp(value2, "auto")) {
+		duplex = 1;
+	} else {
+		printf("Unknown parameter\n");
+		return -1;
+	}
+
+	if (!strcmp(value1, "10")) {
+		*link_speed = (duplex) ? ETH_LINK_SPEED_10M :
+							ETH_LINK_SPEED_10M_HD;
+	} else if (!strcmp(value1, "100")) {
+		*link_speed = (duplex) ? ETH_LINK_SPEED_100M :
+							ETH_LINK_SPEED_100M_HD;
+	} else if (!strcmp(value1, "1000")) {
+		if (!duplex)
+			goto invalid_speed_param;
+		*link_speed = ETH_LINK_SPEED_1G;
+	} else if (!strcmp(value1, "10000")) {
+		if (!duplex)
+			goto invalid_speed_param;
+		*link_speed = ETH_LINK_SPEED_10G;
+	} else if (!strcmp(value1, "40000")) {
+		if (!duplex)
+			goto invalid_speed_param;
+		*link_speed = ETH_LINK_SPEED_40G;
+	} else if (!strcmp(value1, "auto")) {
+		if (!duplex)
+			goto invalid_speed_param;
+		*link_speed = ETH_LINK_SPEED_AUTONEG;
+	} else {
+		printf("Unknown parameter\n");
+		return -1;
+	}
+
+	return 0;
+
+invalid_speed_param:
+
+	printf("Invalid speed parameter\n");
+	return -1;
+}
+
 static void
 cmd_config_speed_all_parsed(void *parsed_result,
 			__attribute__((unused)) struct cmdline *cl,
 			__attribute__((unused)) void *data)
 {
 	struct cmd_config_speed_all *res = parsed_result;
-	uint16_t link_speed = ETH_LINK_SPEED_AUTONEG;
-	uint16_t link_duplex = 0;
+	uint32_t link_speed;
 	portid_t pid;
 
 	if (!all_ports_stopped()) {
@@ -971,40 +1022,18 @@ cmd_config_speed_all_parsed(void *parsed_result,
 		return;
 	}
 
-	if (!strcmp(res->value1, "10"))
-		link_speed = ETH_LINK_SPEED_10;
-	else if (!strcmp(res->value1, "100"))
-		link_speed = ETH_LINK_SPEED_100;
-	else if (!strcmp(res->value1, "1000"))
-		link_speed = ETH_LINK_SPEED_1000;
-	else if (!strcmp(res->value1, "10000"))
-		link_speed = ETH_LINK_SPEED_10G;
-	else if (!strcmp(res->value1, "40000"))
-		link_speed = ETH_LINK_SPEED_40G;
-	else if (!strcmp(res->value1, "auto"))
-		link_speed = ETH_LINK_SPEED_AUTONEG;
-	else {
-		printf("Unknown parameter\n");
+	if (parse_and_check_speed_duplex(res->value1,
+						res->value2,
+						&link_speed) < 0)
 		return;
-	}
-
-	if (!strcmp(res->value2, "half"))
-		link_duplex = ETH_LINK_HALF_DUPLEX;
-	else if (!strcmp(res->value2, "full"))
-		link_duplex = ETH_LINK_FULL_DUPLEX;
-	else if (!strcmp(res->value2, "auto"))
-		link_duplex = ETH_LINK_AUTONEG_DUPLEX;
-	else {
-		printf("Unknown parameter\n");
-		return;
-	}
 
 	FOREACH_PORT(pid, ports) {
-		ports[pid].dev_conf.link_speed = link_speed;
-		ports[pid].dev_conf.link_duplex = link_duplex;
+		ports[pid].dev_conf.link_speeds = link_speed;
 	}
 
 	cmd_reconfig_device_queue(RTE_PORT_ALL, 1, 1);
+
+	return;
 }
 
 cmdline_parse_token_string_t cmd_config_speed_all_port =
@@ -1059,8 +1088,7 @@ cmd_config_speed_specific_parsed(void *parsed_result,
 				__attribute__((unused)) void *data)
 {
 	struct cmd_config_speed_specific *res = parsed_result;
-	uint16_t link_speed = ETH_LINK_SPEED_AUTONEG;
-	uint16_t link_duplex = 0;
+	uint32_t link_speed;
 
 	if (!all_ports_stopped()) {
 		printf("Please stop all ports first\n");
@@ -1070,36 +1098,12 @@ cmd_config_speed_specific_parsed(void *parsed_result,
 	if (port_id_is_invalid(res->id, ENABLED_WARN))
 		return;
 
-	if (!strcmp(res->value1, "10"))
-		link_speed = ETH_LINK_SPEED_10;
-	else if (!strcmp(res->value1, "100"))
-		link_speed = ETH_LINK_SPEED_100;
-	else if (!strcmp(res->value1, "1000"))
-		link_speed = ETH_LINK_SPEED_1000;
-	else if (!strcmp(res->value1, "10000"))
-		link_speed = ETH_LINK_SPEED_10000;
-	else if (!strcmp(res->value1, "40000"))
-		link_speed = ETH_LINK_SPEED_40G;
-	else if (!strcmp(res->value1, "auto"))
-		link_speed = ETH_LINK_SPEED_AUTONEG;
-	else {
-		printf("Unknown parameter\n");
+	if (parse_and_check_speed_duplex(res->value1,
+						res->value2,
+						&link_speed) < 0)
 		return;
-	}
-
-	if (!strcmp(res->value2, "half"))
-		link_duplex = ETH_LINK_HALF_DUPLEX;
-	else if (!strcmp(res->value2, "full"))
-		link_duplex = ETH_LINK_FULL_DUPLEX;
-	else if (!strcmp(res->value2, "auto"))
-		link_duplex = ETH_LINK_AUTONEG_DUPLEX;
-	else {
-		printf("Unknown parameter\n");
-		return;
-	}
 
-	ports[res->id].dev_conf.link_speed = link_speed;
-	ports[res->id].dev_conf.link_duplex = link_duplex;
+	ports[res->id].dev_conf.link_speeds = link_speed;
 
 	cmd_reconfig_device_queue(RTE_PORT_ALL, 1, 1);
 }
diff --git a/app/test-pmd/config.c b/app/test-pmd/config.c
index 0062484..caeb2d9 100644
--- a/app/test-pmd/config.c
+++ b/app/test-pmd/config.c
@@ -2241,7 +2241,7 @@ set_queue_rate_limit(portid_t port_id, uint16_t queue_idx, uint16_t rate)
 		return 1;
 	rte_eth_link_get_nowait(port_id, &link);
 	if (rate > link.link_speed) {
-		printf("Invalid rate value:%u bigger than link speed: %u\n",
+		printf("Invalid rate value:%u bigger than link speed: %" PRIu64 "\n",
 			rate, link.link_speed);
 		return 1;
 	}
@@ -2266,7 +2266,7 @@ set_vf_rate_limit(portid_t port_id, uint16_t vf, uint16_t rate, uint64_t q_msk)
 		return 1;
 	rte_eth_link_get_nowait(port_id, &link);
 	if (rate > link.link_speed) {
-		printf("Invalid rate value:%u bigger than link speed: %u\n",
+		printf("Invalid rate value:%u bigger than link speed: %" PRIu64 "\n",
 			rate, link.link_speed);
 		return 1;
 	}
diff --git a/app/test/virtual_pmd.c b/app/test/virtual_pmd.c
index a538c8a..3c4040b 100644
--- a/app/test/virtual_pmd.c
+++ b/app/test/virtual_pmd.c
@@ -603,8 +603,8 @@ virtual_ethdev_create(const char *name, struct ether_addr *mac_addr,
 
 	TAILQ_INIT(&(eth_dev->link_intr_cbs));
 
-	eth_dev->data->dev_link.link_status = 0;
-	eth_dev->data->dev_link.link_speed = ETH_LINK_SPEED_10000;
+	eth_dev->data->dev_link.link_status = ETH_LINK_DOWN;
+	eth_dev->data->dev_link.link_speed = ETH_SPEED_NUM_10G;
 	eth_dev->data->dev_link.link_duplex = ETH_LINK_FULL_DUPLEX;
 
 	eth_dev->data->mac_addrs = rte_zmalloc(name, ETHER_ADDR_LEN, 0);
diff --git a/drivers/net/af_packet/rte_eth_af_packet.c b/drivers/net/af_packet/rte_eth_af_packet.c
index 767f36b..5db1db2 100644
--- a/drivers/net/af_packet/rte_eth_af_packet.c
+++ b/drivers/net/af_packet/rte_eth_af_packet.c
@@ -116,9 +116,10 @@ static const char *valid_arguments[] = {
 static const char *drivername = "AF_PACKET PMD";
 
 static struct rte_eth_link pmd_link = {
-	.link_speed = 10000,
+	.link_speed = ETH_SPEED_NUM_10G,
 	.link_duplex = ETH_LINK_FULL_DUPLEX,
-	.link_status = 0
+	.link_status = ETH_LINK_DOWN,
+	.link_autoneg = ETH_LINK_SPEED_NEG
 };
 
 static uint16_t
diff --git a/drivers/net/bnx2x/bnx2x_ethdev.c b/drivers/net/bnx2x/bnx2x_ethdev.c
index b547ac3..efefae6 100644
--- a/drivers/net/bnx2x/bnx2x_ethdev.c
+++ b/drivers/net/bnx2x/bnx2x_ethdev.c
@@ -45,8 +45,12 @@ bnx2x_link_update(struct rte_eth_dev *dev)
 			dev->data->dev_link.link_duplex = ETH_LINK_HALF_DUPLEX;
 			break;
 		default:
-			dev->data->dev_link.link_duplex = ETH_LINK_AUTONEG_DUPLEX;
+			break;
 	}
+
+	dev->data->dev_link.link_autoneg = ~(dev->data->dev_conf.link_speeds &
+						ETH_LINK_SPEED_NO_AUTONEG);
+
 	dev->data->dev_link.link_status = sc->link_vars.link_up;
 }
 
@@ -347,7 +351,7 @@ bnx2x_dev_infos_get(struct rte_eth_dev *dev, __rte_unused struct rte_eth_dev_inf
 	dev_info->min_rx_bufsize = BNX2X_MIN_RX_BUF_SIZE;
 	dev_info->max_rx_pktlen  = BNX2X_MAX_RX_PKT_LEN;
 	dev_info->max_mac_addrs  = BNX2X_MAX_MAC_ADDRS;
-	dev_info->speed_capa = ETH_SPEED_CAP_10G | ETH_SPEED_CAP_20G;
+	dev_info->speed_capa = ETH_LINK_SPEED_10G | ETH_LINK_SPEED_20G;
 }
 
 static void
diff --git a/drivers/net/bonding/rte_eth_bond_8023ad.c b/drivers/net/bonding/rte_eth_bond_8023ad.c
index b3b30f6..3b446e1 100644
--- a/drivers/net/bonding/rte_eth_bond_8023ad.c
+++ b/drivers/net/bonding/rte_eth_bond_8023ad.c
@@ -708,25 +708,25 @@ link_speed_key(uint16_t speed) {
 	uint16_t key_speed;
 
 	switch (speed) {
-	case ETH_LINK_SPEED_AUTONEG:
+	case ETH_SPEED_NUM_NONE:
 		key_speed = 0x00;
 		break;
-	case ETH_LINK_SPEED_10:
+	case ETH_SPEED_NUM_10M:
 		key_speed = BOND_LINK_SPEED_KEY_10M;
 		break;
-	case ETH_LINK_SPEED_100:
+	case ETH_SPEED_NUM_100M:
 		key_speed = BOND_LINK_SPEED_KEY_100M;
 		break;
-	case ETH_LINK_SPEED_1000:
+	case ETH_SPEED_NUM_1G:
 		key_speed = BOND_LINK_SPEED_KEY_1000M;
 		break;
-	case ETH_LINK_SPEED_10G:
+	case ETH_SPEED_NUM_10G:
 		key_speed = BOND_LINK_SPEED_KEY_10G;
 		break;
-	case ETH_LINK_SPEED_20G:
+	case ETH_SPEED_NUM_20G:
 		key_speed = BOND_LINK_SPEED_KEY_20G;
 		break;
-	case ETH_LINK_SPEED_40G:
+	case ETH_SPEED_NUM_40G:
 		key_speed = BOND_LINK_SPEED_KEY_40G;
 		break;
 	default:
diff --git a/drivers/net/cxgbe/base/t4_hw.c b/drivers/net/cxgbe/base/t4_hw.c
index 884d2cf..79af806 100644
--- a/drivers/net/cxgbe/base/t4_hw.c
+++ b/drivers/net/cxgbe/base/t4_hw.c
@@ -2159,13 +2159,13 @@ int t4_handle_fw_rpl(struct adapter *adap, const __be64 *rpl)
 		if (stat & F_FW_PORT_CMD_TXPAUSE)
 			fc |= PAUSE_TX;
 		if (stat & V_FW_PORT_CMD_LSPEED(FW_PORT_CAP_SPEED_100M))
-			speed = ETH_LINK_SPEED_100;
+			speed = ETH_SPEED_NUM_100M;
 		else if (stat & V_FW_PORT_CMD_LSPEED(FW_PORT_CAP_SPEED_1G))
-			speed = ETH_LINK_SPEED_1000;
+			speed = ETH_SPEED_NUM_1G;
 		else if (stat & V_FW_PORT_CMD_LSPEED(FW_PORT_CAP_SPEED_10G))
-			speed = ETH_LINK_SPEED_10000;
+			speed = ETH_SPEED_NUM_10G;
 		else if (stat & V_FW_PORT_CMD_LSPEED(FW_PORT_CAP_SPEED_40G))
-			speed = ETH_LINK_SPEED_40G;
+			speed = ETH_SPEED_NUM_40G;
 
 		for_each_port(adap, i) {
 			pi = adap2pinfo(adap, i);
diff --git a/drivers/net/cxgbe/cxgbe_ethdev.c b/drivers/net/cxgbe/cxgbe_ethdev.c
index 203e119..05b954d 100644
--- a/drivers/net/cxgbe/cxgbe_ethdev.c
+++ b/drivers/net/cxgbe/cxgbe_ethdev.c
@@ -171,7 +171,7 @@ static void cxgbe_dev_info_get(struct rte_eth_dev *eth_dev,
 
 	device_info->rx_desc_lim = cxgbe_desc_lim;
 	device_info->tx_desc_lim = cxgbe_desc_lim;
-	device_info->speed_capa = ETH_SPEED_CAP_10G | ETH_SPEED_CAP_40G;
+	device_info->speed_capa = ETH_LINK_SPEED_10G | ETH_LINK_SPEED_40G;
 }
 
 static void cxgbe_dev_promiscuous_enable(struct rte_eth_dev *eth_dev)
diff --git a/drivers/net/e1000/em_ethdev.c b/drivers/net/e1000/em_ethdev.c
index e40dc37..12c4c63 100644
--- a/drivers/net/e1000/em_ethdev.c
+++ b/drivers/net/e1000/em_ethdev.c
@@ -509,6 +509,9 @@ eth_em_start(struct rte_eth_dev *dev)
 	struct rte_intr_handle *intr_handle = &dev->pci_dev->intr_handle;
 	int ret, mask;
 	uint32_t intr_vector = 0;
+	uint32_t *speeds;
+	int num_speeds;
+	bool autoneg;
 
 	PMD_INIT_FUNC_TRACE();
 
@@ -583,56 +586,46 @@ eth_em_start(struct rte_eth_dev *dev)
 	E1000_WRITE_REG(hw, E1000_ITR, UINT16_MAX);
 
 	/* Setup link speed and duplex */
-	switch (dev->data->dev_conf.link_speed) {
-	case ETH_LINK_SPEED_AUTONEG:
-		if (dev->data->dev_conf.link_duplex == ETH_LINK_AUTONEG_DUPLEX)
-			hw->phy.autoneg_advertised = E1000_ALL_SPEED_DUPLEX;
-		else if (dev->data->dev_conf.link_duplex ==
-					ETH_LINK_HALF_DUPLEX)
-			hw->phy.autoneg_advertised = E1000_ALL_HALF_DUPLEX;
-		else if (dev->data->dev_conf.link_duplex ==
-					ETH_LINK_FULL_DUPLEX)
-			hw->phy.autoneg_advertised = E1000_ALL_FULL_DUPLEX;
-		else
-			goto error_invalid_config;
-		break;
-	case ETH_LINK_SPEED_10:
-		if (dev->data->dev_conf.link_duplex == ETH_LINK_AUTONEG_DUPLEX)
-			hw->phy.autoneg_advertised = E1000_ALL_10_SPEED;
-		else if (dev->data->dev_conf.link_duplex ==
-					ETH_LINK_HALF_DUPLEX)
-			hw->phy.autoneg_advertised = ADVERTISE_10_HALF;
-		else if (dev->data->dev_conf.link_duplex ==
-					ETH_LINK_FULL_DUPLEX)
-			hw->phy.autoneg_advertised = ADVERTISE_10_FULL;
-		else
-			goto error_invalid_config;
-		break;
-	case ETH_LINK_SPEED_100:
-		if (dev->data->dev_conf.link_duplex == ETH_LINK_AUTONEG_DUPLEX)
-			hw->phy.autoneg_advertised = E1000_ALL_100_SPEED;
-		else if (dev->data->dev_conf.link_duplex ==
-					ETH_LINK_HALF_DUPLEX)
-			hw->phy.autoneg_advertised = ADVERTISE_100_HALF;
-		else if (dev->data->dev_conf.link_duplex ==
-					ETH_LINK_FULL_DUPLEX)
-			hw->phy.autoneg_advertised = ADVERTISE_100_FULL;
-		else
+	speeds = &dev->data->dev_conf.link_speeds;
+	if (*speeds == ETH_LINK_SPEED_AUTONEG) {
+		hw->phy.autoneg_advertised = E1000_ALL_SPEED_DUPLEX;
+	} else {
+		num_speeds = 0;
+		autoneg = ~(*speeds & ETH_LINK_SPEED_NO_AUTONEG);
+
+		/* Reset */
+		hw->phy.autoneg_advertised = 0;
+
+		if (*speeds & ~(ETH_LINK_SPEED_10M_HD | ETH_LINK_SPEED_10M |
+				ETH_LINK_SPEED_100M_HD | ETH_LINK_SPEED_100M |
+				ETH_LINK_SPEED_1G)) {
+			num_speeds = -1;
 			goto error_invalid_config;
-		break;
-	case ETH_LINK_SPEED_1000:
-		if ((dev->data->dev_conf.link_duplex ==
-				ETH_LINK_AUTONEG_DUPLEX) ||
-			(dev->data->dev_conf.link_duplex ==
-					ETH_LINK_FULL_DUPLEX))
-			hw->phy.autoneg_advertised = ADVERTISE_1000_FULL;
-		else
+		}
+		if (*speeds & ETH_LINK_SPEED_10M_HD) {
+			hw->phy.autoneg_advertised |= ADVERTISE_10_HALF;
+			num_speeds++;
+		}
+		if (*speeds & ETH_LINK_SPEED_10M) {
+			hw->phy.autoneg_advertised |= ADVERTISE_10_FULL;
+			num_speeds++;
+		}
+		if (*speeds & ETH_LINK_SPEED_100M_HD) {
+			hw->phy.autoneg_advertised |= ADVERTISE_100_HALF;
+			num_speeds++;
+		}
+		if (*speeds & ETH_LINK_SPEED_100M) {
+			hw->phy.autoneg_advertised |= ADVERTISE_100_FULL;
+			num_speeds++;
+		}
+		if (*speeds & ETH_LINK_SPEED_1G) {
+			hw->phy.autoneg_advertised |= ADVERTISE_1000_FULL;
+			num_speeds++;
+		}
+		if (num_speeds == 0 || (!autoneg && (num_speeds > 2)))
 			goto error_invalid_config;
-		break;
-	case ETH_LINK_SPEED_10000:
-	default:
-		goto error_invalid_config;
 	}
+
 	e1000_setup_link(hw);
 
 	if (rte_intr_allow_others(intr_handle)) {
@@ -665,9 +658,8 @@ eth_em_start(struct rte_eth_dev *dev)
 	return 0;
 
 error_invalid_config:
-	PMD_INIT_LOG(ERR, "Invalid link_speed/link_duplex (%u/%u) for port %u",
-		     dev->data->dev_conf.link_speed,
-		     dev->data->dev_conf.link_duplex, dev->data->port_id);
+	PMD_INIT_LOG(ERR, "Invalid advertised speeds (%u) for port %u",
+		     dev->data->dev_conf.link_speeds, dev->data->port_id);
 	em_dev_clear_queues(dev);
 	return -EINVAL;
 }
@@ -1024,11 +1016,11 @@ eth_em_infos_get(struct rte_eth_dev *dev, struct rte_eth_dev_info *dev_info)
 		.nb_align = EM_TXD_ALIGN,
 	};
 
-	dev_info->speed_capa = ETH_SPEED_CAP_10M_HD |
-					ETH_SPEED_CAP_10M_FD |
-					ETH_SPEED_CAP_100M_HD |
-					ETH_SPEED_CAP_100M_FD |
-					ETH_SPEED_CAP_1G;
+	dev_info->speed_capa = ETH_LINK_SPEED_10M_HD |
+					ETH_LINK_SPEED_10M |
+					ETH_LINK_SPEED_100M_HD |
+					ETH_LINK_SPEED_100M |
+					ETH_LINK_SPEED_1G;
 }
 
 /* return 0 means link status changed, -1 means not changed */
@@ -1077,13 +1069,17 @@ eth_em_link_update(struct rte_eth_dev *dev, int wait_to_complete)
 
 	/* Now we check if a transition has happened */
 	if (link_check && (link.link_status == 0)) {
-		hw->mac.ops.get_link_up_info(hw, &link.link_speed,
-			&link.link_duplex);
-		link.link_status = 1;
+		uint16_t duplex, speed;
+		hw->mac.ops.get_link_up_info(hw, &speed, &duplex);
+
+		link.link_duplex = (duplex) ? ETH_LINK_FULL_DUPLEX :
+						ETH_LINK_HALF_DUPLEX;
+		link.link_speed = speed;
+		link.link_status = ETH_LINK_UP;
 	} else if (!link_check && (link.link_status == 1)) {
 		link.link_speed = 0;
-		link.link_duplex = 0;
-		link.link_status = 0;
+		link.link_duplex = ETH_LINK_HALF_DUPLEX;
+		link.link_status = ETH_LINK_DOWN;
 	}
 	rte_em_dev_atomic_write_link_status(dev, &link);
 
diff --git a/drivers/net/e1000/igb_ethdev.c b/drivers/net/e1000/igb_ethdev.c
index 7eac8ea..6682df5 100644
--- a/drivers/net/e1000/igb_ethdev.c
+++ b/drivers/net/e1000/igb_ethdev.c
@@ -1119,6 +1119,9 @@ eth_igb_start(struct rte_eth_dev *dev)
 	int ret, mask;
 	uint32_t intr_vector = 0;
 	uint32_t ctrl_ext;
+	uint32_t *speeds;
+	int num_speeds;
+	bool autoneg;
 
 	PMD_INIT_FUNC_TRACE();
 
@@ -1219,48 +1222,46 @@ eth_igb_start(struct rte_eth_dev *dev)
 	}
 
 	/* Setup link speed and duplex */
-	switch (dev->data->dev_conf.link_speed) {
-	case ETH_LINK_SPEED_AUTONEG:
-		if (dev->data->dev_conf.link_duplex == ETH_LINK_AUTONEG_DUPLEX)
-			hw->phy.autoneg_advertised = E1000_ALL_SPEED_DUPLEX;
-		else if (dev->data->dev_conf.link_duplex == ETH_LINK_HALF_DUPLEX)
-			hw->phy.autoneg_advertised = E1000_ALL_HALF_DUPLEX;
-		else if (dev->data->dev_conf.link_duplex == ETH_LINK_FULL_DUPLEX)
-			hw->phy.autoneg_advertised = E1000_ALL_FULL_DUPLEX;
-		else
-			goto error_invalid_config;
-		break;
-	case ETH_LINK_SPEED_10:
-		if (dev->data->dev_conf.link_duplex == ETH_LINK_AUTONEG_DUPLEX)
-			hw->phy.autoneg_advertised = E1000_ALL_10_SPEED;
-		else if (dev->data->dev_conf.link_duplex == ETH_LINK_HALF_DUPLEX)
-			hw->phy.autoneg_advertised = ADVERTISE_10_HALF;
-		else if (dev->data->dev_conf.link_duplex == ETH_LINK_FULL_DUPLEX)
-			hw->phy.autoneg_advertised = ADVERTISE_10_FULL;
-		else
-			goto error_invalid_config;
-		break;
-	case ETH_LINK_SPEED_100:
-		if (dev->data->dev_conf.link_duplex == ETH_LINK_AUTONEG_DUPLEX)
-			hw->phy.autoneg_advertised = E1000_ALL_100_SPEED;
-		else if (dev->data->dev_conf.link_duplex == ETH_LINK_HALF_DUPLEX)
-			hw->phy.autoneg_advertised = ADVERTISE_100_HALF;
-		else if (dev->data->dev_conf.link_duplex == ETH_LINK_FULL_DUPLEX)
-			hw->phy.autoneg_advertised = ADVERTISE_100_FULL;
-		else
+	speeds = &dev->data->dev_conf.link_speeds;
+	if (*speeds == ETH_LINK_SPEED_AUTONEG) {
+		hw->phy.autoneg_advertised = E1000_ALL_SPEED_DUPLEX;
+	} else {
+		num_speeds = 0;
+		autoneg = ~(*speeds & ETH_LINK_SPEED_NO_AUTONEG);
+
+		/* Reset */
+		hw->phy.autoneg_advertised = 0;
+
+		if (*speeds & ~(ETH_LINK_SPEED_10M_HD | ETH_LINK_SPEED_10M |
+				ETH_LINK_SPEED_100M_HD | ETH_LINK_SPEED_100M |
+				ETH_LINK_SPEED_1G)) {
+			num_speeds = -1;
 			goto error_invalid_config;
-		break;
-	case ETH_LINK_SPEED_1000:
-		if ((dev->data->dev_conf.link_duplex == ETH_LINK_AUTONEG_DUPLEX) ||
-				(dev->data->dev_conf.link_duplex == ETH_LINK_FULL_DUPLEX))
-			hw->phy.autoneg_advertised = ADVERTISE_1000_FULL;
-		else
+		}
+		if (*speeds & ETH_LINK_SPEED_10M_HD) {
+			hw->phy.autoneg_advertised |= ADVERTISE_10_HALF;
+			num_speeds++;
+		}
+		if (*speeds & ETH_LINK_SPEED_10M) {
+			hw->phy.autoneg_advertised |= ADVERTISE_10_FULL;
+			num_speeds++;
+		}
+		if (*speeds & ETH_LINK_SPEED_100M_HD) {
+			hw->phy.autoneg_advertised |= ADVERTISE_100_HALF;
+			num_speeds++;
+		}
+		if (*speeds & ETH_LINK_SPEED_100M) {
+			hw->phy.autoneg_advertised |= ADVERTISE_100_FULL;
+			num_speeds++;
+		}
+		if (*speeds & ETH_LINK_SPEED_1G) {
+			hw->phy.autoneg_advertised |= ADVERTISE_1000_FULL;
+			num_speeds++;
+		}
+		if (num_speeds == 0 || (!autoneg && (num_speeds > 2)))
 			goto error_invalid_config;
-		break;
-	case ETH_LINK_SPEED_10000:
-	default:
-		goto error_invalid_config;
 	}
+
 	e1000_setup_link(hw);
 
 	if (rte_intr_allow_others(intr_handle)) {
@@ -1292,9 +1293,8 @@ eth_igb_start(struct rte_eth_dev *dev)
 	return 0;
 
 error_invalid_config:
-	PMD_INIT_LOG(ERR, "Invalid link_speed/link_duplex (%u/%u) for port %u",
-		     dev->data->dev_conf.link_speed,
-		     dev->data->dev_conf.link_duplex, dev->data->port_id);
+	PMD_INIT_LOG(ERR, "Invalid advertised speeds (%u) for port %u",
+		     dev->data->dev_conf.link_speeds, dev->data->port_id);
 	igb_dev_clear_queues(dev);
 	return -EINVAL;
 }
@@ -1909,11 +1909,11 @@ eth_igb_infos_get(struct rte_eth_dev *dev, struct rte_eth_dev_info *dev_info)
 	dev_info->rx_desc_lim = rx_desc_lim;
 	dev_info->tx_desc_lim = tx_desc_lim;
 
-	dev_info->speed_capa = ETH_SPEED_CAP_10M_HD |
-					ETH_SPEED_CAP_10M_FD |
-					ETH_SPEED_CAP_100M_HD |
-					ETH_SPEED_CAP_100M_FD |
-					ETH_SPEED_CAP_1G;
+	dev_info->speed_capa = ETH_LINK_SPEED_10M_HD |
+					ETH_LINK_SPEED_10M |
+					ETH_LINK_SPEED_100M_HD |
+					ETH_LINK_SPEED_100M |
+					ETH_LINK_SPEED_1G;
 }
 
 static void
@@ -2023,13 +2023,20 @@ eth_igb_link_update(struct rte_eth_dev *dev, int wait_to_complete)
 
 	/* Now we check if a transition has happened */
 	if (link_check) {
-		hw->mac.ops.get_link_up_info(hw, &link.link_speed,
-					  &link.link_duplex);
-		link.link_status = 1;
+		uint16_t duplex, speed;
+		hw->mac.ops.get_link_up_info(hw, &speed, &duplex);
+
+		link.link_duplex = (duplex) ? ETH_LINK_FULL_DUPLEX :
+							ETH_LINK_HALF_DUPLEX;
+		link.link_speed = speed;
+		link.link_status = ETH_LINK_UP;
+		link.link_autoneg = ~(dev->data->dev_conf.link_speeds &
+						ETH_LINK_SPEED_NO_AUTONEG);
 	} else if (!link_check) {
 		link.link_speed = 0;
-		link.link_duplex = 0;
-		link.link_status = 0;
+		link.link_duplex = ETH_LINK_HALF_DUPLEX;
+		link.link_status = ETH_LINK_DOWN;
+		link.link_autoneg = ETH_LINK_SPEED_FIXED;
 	}
 	rte_igb_dev_atomic_write_link_status(dev, &link);
 
diff --git a/drivers/net/fm10k/fm10k_ethdev.c b/drivers/net/fm10k/fm10k_ethdev.c
index 2e6ec60..f44818f 100644
--- a/drivers/net/fm10k/fm10k_ethdev.c
+++ b/drivers/net/fm10k/fm10k_ethdev.c
@@ -1172,7 +1172,7 @@ fm10k_link_update(struct rte_eth_dev *dev,
 	 * is no 50Gbps Ethernet. */
 	dev->data->dev_link.link_speed  = 0;
 	dev->data->dev_link.link_duplex = ETH_LINK_FULL_DUPLEX;
-	dev->data->dev_link.link_status = 1;
+	dev->data->dev_link.link_status = ETH_LINK_UP;
 
 	return 0;
 }
@@ -1334,9 +1334,9 @@ fm10k_dev_infos_get(struct rte_eth_dev *dev,
 		.nb_align = FM10K_MULT_TX_DESC,
 	};
 
-	dev_info->speed_capa = ETH_SPEED_CAP_1G | ETH_SPEED_CAP_2_5G |
-					ETH_SPEED_CAP_10G | ETH_SPEED_CAP_25G |
-					ETH_SPEED_CAP_40G | ETH_SPEED_CAP_100G;
+	dev_info->speed_capa = ETH_LINK_SPEED_1G | ETH_LINK_SPEED_2_5G |
+				ETH_LINK_SPEED_10G | ETH_LINK_SPEED_25G |
+				ETH_LINK_SPEED_40G | ETH_LINK_SPEED_100G;
 }
 
 static int
diff --git a/drivers/net/i40e/i40e_ethdev.c b/drivers/net/i40e/i40e_ethdev.c
index 78a0cbd..e440dcf 100644
--- a/drivers/net/i40e/i40e_ethdev.c
+++ b/drivers/net/i40e/i40e_ethdev.c
@@ -1326,27 +1326,20 @@ i40e_vsi_disable_queues_intr(struct i40e_vsi *vsi)
 }
 
 static inline uint8_t
-i40e_parse_link_speed(uint16_t eth_link_speed)
+i40e_parse_link_speeds(uint16_t link_speeds)
 {
 	uint8_t link_speed = I40E_LINK_SPEED_UNKNOWN;
 
-	switch (eth_link_speed) {
-	case ETH_LINK_SPEED_40G:
-		link_speed = I40E_LINK_SPEED_40GB;
-		break;
-	case ETH_LINK_SPEED_20G:
-		link_speed = I40E_LINK_SPEED_20GB;
-		break;
-	case ETH_LINK_SPEED_10G:
-		link_speed = I40E_LINK_SPEED_10GB;
-		break;
-	case ETH_LINK_SPEED_1000:
-		link_speed = I40E_LINK_SPEED_1GB;
-		break;
-	case ETH_LINK_SPEED_100:
-		link_speed = I40E_LINK_SPEED_100MB;
-		break;
-	}
+	if (link_speeds & ETH_LINK_SPEED_40G)
+		link_speed |= I40E_LINK_SPEED_40GB;
+	if (link_speeds & ETH_LINK_SPEED_20G)
+		link_speed |= I40E_LINK_SPEED_20GB;
+	if (link_speeds & ETH_LINK_SPEED_10G)
+		link_speed |= I40E_LINK_SPEED_10GB;
+	if (link_speeds & ETH_LINK_SPEED_1G)
+		link_speed |= I40E_LINK_SPEED_1GB;
+	if (link_speeds & ETH_LINK_SPEED_100M)
+		link_speed |= I40E_LINK_SPEED_100MB;
 
 	return link_speed;
 }
@@ -1372,9 +1365,9 @@ i40e_apply_link_speed(struct rte_eth_dev *dev)
 	struct i40e_hw *hw = I40E_DEV_PRIVATE_TO_HW(dev->data->dev_private);
 	struct rte_eth_conf *conf = &dev->data->dev_conf;
 
-	speed = i40e_parse_link_speed(conf->link_speed);
+	speed = i40e_parse_link_speeds(conf->link_speeds);
 	abilities |= I40E_AQ_PHY_ENABLE_ATOMIC_LINK;
-	if (conf->link_speed == ETH_LINK_SPEED_AUTONEG)
+	if (conf->link_speeds & ETH_LINK_SPEED_AUTONEG)
 		abilities |= I40E_AQ_PHY_AN_ENABLED;
 	else
 		abilities |= I40E_AQ_PHY_LINK_ENABLED;
@@ -1394,10 +1387,8 @@ i40e_dev_start(struct rte_eth_dev *dev)
 
 	hw->adapter_stopped = 0;
 
-	if ((dev->data->dev_conf.link_duplex != ETH_LINK_AUTONEG_DUPLEX) &&
-		(dev->data->dev_conf.link_duplex != ETH_LINK_FULL_DUPLEX)) {
-		PMD_INIT_LOG(ERR, "Invalid link_duplex (%hu) for port %hhu",
-			     dev->data->dev_conf.link_duplex,
+	if (dev->data->dev_conf.link_speeds & ETH_LINK_SPEED_NO_AUTONEG) {
+		PMD_INIT_LOG(ERR, "Invalid link_speeds for port %hhu; autonegociation disabled",
 			     dev->data->port_id);
 		return -EINVAL;
 	}
@@ -1470,6 +1461,13 @@ i40e_dev_start(struct rte_eth_dev *dev)
 	}
 
 	/* Apply link configure */
+	if (dev->data->dev_conf.link_speeds & ~(ETH_LINK_SPEED_100M |
+				ETH_LINK_SPEED_1G | ETH_LINK_SPEED_10G |
+				ETH_LINK_SPEED_20G | ETH_LINK_SPEED_40G)) {
+		PMD_DRV_LOG(ERR, "Invalid link setting");
+		goto err_up;
+	}
+
 	ret = i40e_apply_link_speed(dev);
 	if (I40E_SUCCESS != ret) {
 		PMD_DRV_LOG(ERR, "Fail to apply link setting");
@@ -1713,7 +1711,7 @@ i40e_dev_link_update(struct rte_eth_dev *dev,
 		/* Get link status information from hardware */
 		status = i40e_aq_get_link_info(hw, false, &link_status, NULL);
 		if (status != I40E_SUCCESS) {
-			link.link_speed = ETH_LINK_SPEED_100;
+			link.link_speed = ETH_SPEED_NUM_100M;
 			link.link_duplex = ETH_LINK_FULL_DUPLEX;
 			PMD_DRV_LOG(ERR, "Failed to get link info");
 			goto out;
@@ -1735,25 +1733,28 @@ i40e_dev_link_update(struct rte_eth_dev *dev,
 	/* Parse the link status */
 	switch (link_status.link_speed) {
 	case I40E_LINK_SPEED_100MB:
-		link.link_speed = ETH_LINK_SPEED_100;
+		link.link_speed = ETH_SPEED_NUM_100M;
 		break;
 	case I40E_LINK_SPEED_1GB:
-		link.link_speed = ETH_LINK_SPEED_1000;
+		link.link_speed = ETH_SPEED_NUM_1G;
 		break;
 	case I40E_LINK_SPEED_10GB:
-		link.link_speed = ETH_LINK_SPEED_10G;
+		link.link_speed = ETH_SPEED_NUM_10G;
 		break;
 	case I40E_LINK_SPEED_20GB:
-		link.link_speed = ETH_LINK_SPEED_20G;
+		link.link_speed = ETH_SPEED_NUM_20G;
 		break;
 	case I40E_LINK_SPEED_40GB:
-		link.link_speed = ETH_LINK_SPEED_40G;
+		link.link_speed = ETH_SPEED_NUM_40G;
 		break;
 	default:
-		link.link_speed = ETH_LINK_SPEED_100;
+		link.link_speed = ETH_SPEED_NUM_100M;
 		break;
 	}
 
+	link.link_autoneg = ~(dev->data->dev_conf.link_speeds &
+						ETH_LINK_SPEED_NO_AUTONEG);
+
 out:
 	rte_i40e_dev_atomic_write_link_status(dev, &link);
 	if (link.link_status == old.link_status)
@@ -2308,10 +2309,10 @@ i40e_dev_info_get(struct rte_eth_dev *dev, struct rte_eth_dev_info *dev_info)
 
 	if (i40e_is_40G_device(hw->device_id))
 		/* For XL710 */
-		dev_info->speed_capa = ETH_SPEED_CAP_1G | ETH_SPEED_CAP_10G;
+		dev_info->speed_capa = ETH_LINK_SPEED_1G | ETH_LINK_SPEED_10G;
 	else
 		/* For X710 */
-		dev_info->speed_capa = ETH_SPEED_CAP_10G | ETH_SPEED_CAP_40G;
+		dev_info->speed_capa = ETH_LINK_SPEED_10G | ETH_LINK_SPEED_40G;
 
 }
 
@@ -7835,15 +7836,15 @@ i40e_start_timecounters(struct rte_eth_dev *dev)
 	rte_i40e_dev_atomic_read_link_status(dev, &link);
 
 	switch (link.link_speed) {
-	case ETH_LINK_SPEED_40G:
+	case ETH_SPEED_NUM_40G:
 		tsync_inc_l = I40E_PTP_40GB_INCVAL & 0xFFFFFFFF;
 		tsync_inc_h = I40E_PTP_40GB_INCVAL >> 32;
 		break;
-	case ETH_LINK_SPEED_10G:
+	case ETH_SPEED_NUM_10G:
 		tsync_inc_l = I40E_PTP_10GB_INCVAL & 0xFFFFFFFF;
 		tsync_inc_h = I40E_PTP_10GB_INCVAL >> 32;
 		break;
-	case ETH_LINK_SPEED_1000:
+	case ETH_SPEED_NUM_1G:
 		tsync_inc_l = I40E_PTP_1GB_INCVAL & 0xFFFFFFFF;
 		tsync_inc_h = I40E_PTP_1GB_INCVAL >> 32;
 		break;
diff --git a/drivers/net/i40e/i40e_ethdev_vf.c b/drivers/net/i40e/i40e_ethdev_vf.c
index 13c5b3d..dd8f1e2 100644
--- a/drivers/net/i40e/i40e_ethdev_vf.c
+++ b/drivers/net/i40e/i40e_ethdev_vf.c
@@ -1911,13 +1911,14 @@ i40evf_dev_link_update(struct rte_eth_dev *dev,
 	 * DPDK pf host provide interfacet to acquire link status
 	 * while Linux driver does not
 	 */
-	if (vf->version_major == I40E_DPDK_VERSION_MAJOR)
+	if (vf->version_major == I40E_DPDK_VERSION_MAJOR) {
 		i40evf_get_link_status(dev, &new_link);
-	else {
+	} else {
 		/* Always assume it's up, for Linux driver PF host */
-		new_link.link_duplex = ETH_LINK_AUTONEG_DUPLEX;
-		new_link.link_speed  = ETH_LINK_SPEED_10000;
-		new_link.link_status = 1;
+		new_link.link_speed  = ETH_SPEED_NUM_10G;
+		new_link.link_duplex = ETH_LINK_FULL_DUPLEX;
+		new_link.link_autoneg = ETH_LINK_SPEED_NEG;
+		new_link.link_status = ETH_LINK_UP;
 	}
 	i40evf_dev_atomic_write_link_status(dev, &new_link);
 
diff --git a/drivers/net/ixgbe/ixgbe_ethdev.c b/drivers/net/ixgbe/ixgbe_ethdev.c
index 7e29c18..4fa07b6 100644
--- a/drivers/net/ixgbe/ixgbe_ethdev.c
+++ b/drivers/net/ixgbe/ixgbe_ethdev.c
@@ -1979,14 +1979,13 @@ ixgbe_dev_start(struct rte_eth_dev *dev)
 	int mask = 0;
 	int status;
 	uint16_t vf, idx;
+	uint32_t *link_speeds;
 
 	PMD_INIT_FUNC_TRACE();
 
 	/* IXGBE devices don't support half duplex */
-	if ((dev->data->dev_conf.link_duplex != ETH_LINK_AUTONEG_DUPLEX) &&
-			(dev->data->dev_conf.link_duplex != ETH_LINK_FULL_DUPLEX)) {
-		PMD_INIT_LOG(ERR, "Invalid link_duplex (%hu) for port %hhu",
-			     dev->data->dev_conf.link_duplex,
+	if (dev->data->dev_conf.link_speeds & ETH_LINK_SPEED_NO_AUTONEG) {
+		PMD_INIT_LOG(ERR, "Invalid link_speeds for port %hhu; autonegociation disabled",
 			     dev->data->port_id);
 		return -EINVAL;
 	}
@@ -2076,32 +2075,22 @@ ixgbe_dev_start(struct rte_eth_dev *dev)
 	if (err)
 		goto error;
 
-	switch(dev->data->dev_conf.link_speed) {
-	case ETH_LINK_SPEED_AUTONEG:
-		speed = (hw->mac.type != ixgbe_mac_82598EB) ?
-				IXGBE_LINK_SPEED_82599_AUTONEG :
-				IXGBE_LINK_SPEED_82598_AUTONEG;
-		break;
-	case ETH_LINK_SPEED_100:
-		/*
-		 * Invalid for 82598 but error will be detected by
-		 * ixgbe_setup_link()
-		 */
-		speed = IXGBE_LINK_SPEED_100_FULL;
-		break;
-	case ETH_LINK_SPEED_1000:
-		speed = IXGBE_LINK_SPEED_1GB_FULL;
-		break;
-	case ETH_LINK_SPEED_10000:
-		speed = IXGBE_LINK_SPEED_10GB_FULL;
-		break;
-	default:
-		PMD_INIT_LOG(ERR, "Invalid link_speed (%hu) for port %hhu",
-			     dev->data->dev_conf.link_speed,
-			     dev->data->port_id);
+	link_speeds = &dev->data->dev_conf.link_speeds;
+	if (*link_speeds & ~(ETH_LINK_SPEED_100M | ETH_LINK_SPEED_1G |
+							ETH_LINK_SPEED_10G)) {
+		PMD_INIT_LOG(ERR, "Invalid link setting");
 		goto error;
 	}
 
+	speed = 0x0;
+
+	if (*link_speeds & ETH_LINK_SPEED_10G)
+		speed |= IXGBE_LINK_SPEED_10GB_FULL;
+	if (*link_speeds & ETH_LINK_SPEED_1G)
+		speed |= IXGBE_LINK_SPEED_1GB_FULL;
+	if (*link_speeds & ETH_LINK_SPEED_100M)
+		speed |= IXGBE_LINK_SPEED_100_FULL;
+
 	err = ixgbe_setup_link(hw, speed, link_up);
 	if (err)
 		goto error;
@@ -2828,15 +2817,16 @@ ixgbe_dev_info_get(struct rte_eth_dev *dev, struct rte_eth_dev_info *dev_info)
 	dev_info->reta_size = ixgbe_reta_size_get(hw->mac.type);
 	dev_info->flow_type_rss_offloads = IXGBE_RSS_OFFLOAD_ALL;
 
-	dev_info->speed_capa = ETH_SPEED_CAP_1G | ETH_SPEED_CAP_10G;
+	dev_info->speed_capa = ETH_LINK_SPEED_1G | ETH_LINK_SPEED_10G;
 
 	if (hw->mac.type == ixgbe_mac_X540 ||
 	    hw->mac.type == ixgbe_mac_X540_vf ||
 	    hw->mac.type == ixgbe_mac_X550 ||
-	    hw->mac.type == ixgbe_mac_X550_vf)
+	    hw->mac.type == ixgbe_mac_X550_vf) {
 
-		dev_info->speed_capa |= ETH_SPEED_CAP_100M_FD /*|
-					ETH_SPEED_CAP_100M_HD*/;
+		dev_info->speed_capa |= ETH_LINK_SPEED_100M /*|
+					ETH_LINK_SPEED_100M_HD*/;
+	}
 }
 
 static void
@@ -2903,9 +2893,9 @@ ixgbe_dev_link_update(struct rte_eth_dev *dev, int wait_to_complete)
 	int link_up;
 	int diag;
 
-	link.link_status = 0;
+	link.link_status = ETH_LINK_DOWN;
 	link.link_speed = 0;
-	link.link_duplex = 0;
+	link.link_duplex = ETH_LINK_HALF_DUPLEX;
 	memset(&old, 0, sizeof(old));
 	rte_ixgbe_dev_atomic_read_link_status(dev, &old);
 
@@ -2918,8 +2908,8 @@ ixgbe_dev_link_update(struct rte_eth_dev *dev, int wait_to_complete)
 		diag = ixgbe_check_link(hw, &link_speed, &link_up, 1);
 
 	if (diag != 0) {
-		link.link_speed = ETH_LINK_SPEED_100;
-		link.link_duplex = ETH_LINK_HALF_DUPLEX;
+		link.link_speed = ETH_SPEED_NUM_100M;
+		link.link_duplex = ETH_LINK_FULL_DUPLEX;
 		rte_ixgbe_dev_atomic_write_link_status(dev, &link);
 		if (link.link_status == old.link_status)
 			return -1;
@@ -2932,26 +2922,26 @@ ixgbe_dev_link_update(struct rte_eth_dev *dev, int wait_to_complete)
 			return -1;
 		return 0;
 	}
-	link.link_status = 1;
+	link.link_status = ETH_LINK_UP;
 	link.link_duplex = ETH_LINK_FULL_DUPLEX;
 
 	switch (link_speed) {
 	default:
 	case IXGBE_LINK_SPEED_UNKNOWN:
-		link.link_duplex = ETH_LINK_HALF_DUPLEX;
-		link.link_speed = ETH_LINK_SPEED_100;
+		link.link_duplex = ETH_LINK_FULL_DUPLEX;
+		link.link_speed = ETH_SPEED_NUM_100M;
 		break;
 
 	case IXGBE_LINK_SPEED_100_FULL:
-		link.link_speed = ETH_LINK_SPEED_100;
+		link.link_speed = ETH_SPEED_NUM_100M;
 		break;
 
 	case IXGBE_LINK_SPEED_1GB_FULL:
-		link.link_speed = ETH_LINK_SPEED_1000;
+		link.link_speed = ETH_SPEED_NUM_1G;
 		break;
 
 	case IXGBE_LINK_SPEED_10GB_FULL:
-		link.link_speed = ETH_LINK_SPEED_10000;
+		link.link_speed = ETH_SPEED_NUM_10G;
 		break;
 	}
 	rte_ixgbe_dev_atomic_write_link_status(dev, &link);
@@ -5725,15 +5715,15 @@ ixgbe_start_timecounters(struct rte_eth_dev *dev)
 	rte_ixgbe_dev_atomic_read_link_status(dev, &link);
 
 	switch (link.link_speed) {
-	case ETH_LINK_SPEED_100:
+	case ETH_SPEED_NUM_100M:
 		incval = IXGBE_INCVAL_100;
 		shift = IXGBE_INCVAL_SHIFT_100;
 		break;
-	case ETH_LINK_SPEED_1000:
+	case ETH_SPEED_NUM_1G:
 		incval = IXGBE_INCVAL_1GB;
 		shift = IXGBE_INCVAL_SHIFT_1GB;
 		break;
-	case ETH_LINK_SPEED_10000:
+	case ETH_SPEED_NUM_10G:
 	default:
 		incval = IXGBE_INCVAL_10GB;
 		shift = IXGBE_INCVAL_SHIFT_10GB;
diff --git a/drivers/net/mlx4/mlx4.c b/drivers/net/mlx4/mlx4.c
index c5688a7..01c3a5c 100644
--- a/drivers/net/mlx4/mlx4.c
+++ b/drivers/net/mlx4/mlx4.c
@@ -4265,8 +4265,8 @@ mlx4_dev_infos_get(struct rte_eth_dev *dev, struct rte_eth_dev_info *info)
 	if (priv_get_ifname(priv, &ifname) == 0)
 		info->if_index = if_nametoindex(ifname);
 
-	info->speed_capa = ETH_SPEED_CAP_10G |ETH_SPEED_CAP_40G |
-					ETH_SPEED_CAP_56G;
+	info->speed_capa = ETH_LINK_SPEED_10G |ETH_LINK_SPEED_40G |
+					ETH_LINK_SPEED_56G;
 
 	priv_unlock(priv);
 }
@@ -4636,6 +4636,8 @@ mlx4_link_update_unlocked(struct rte_eth_dev *dev, int wait_to_complete)
 		dev_link.link_speed = link_speed;
 	dev_link.link_duplex = ((edata.duplex == DUPLEX_HALF) ?
 				ETH_LINK_HALF_DUPLEX : ETH_LINK_FULL_DUPLEX);
+	dev_link.link_autoneg = ~(dev->data->dev_conf.link_speeds &
+						ETH_LINK_SPEED_NO_AUTONEG);
 	if (memcmp(&dev_link, &dev->data->dev_link, sizeof(dev_link))) {
 		/* Link status changed. */
 		dev->data->dev_link = dev_link;
diff --git a/drivers/net/mpipe/mpipe_tilegx.c b/drivers/net/mpipe/mpipe_tilegx.c
index 04f3c9f..ecb69b1 100644
--- a/drivers/net/mpipe/mpipe_tilegx.c
+++ b/drivers/net/mpipe/mpipe_tilegx.c
@@ -388,14 +388,16 @@ mpipe_link_update(struct rte_eth_dev *dev, int wait_to_complete)
 
 		speed = state & GXIO_MPIPE_LINK_SPEED_MASK;
 
+		new.link_autoneg = ~(dev->data->dev_conf.link_speeds &
+						ETH_LINK_SPEED_NO_AUTONEG);
 		if (speed == GXIO_MPIPE_LINK_1G) {
 			new.link_speed = ETH_LINK_SPEED_1000;
 			new.link_duplex = ETH_LINK_FULL_DUPLEX;
-			new.link_status = 1;
+			new.link_status = ETH_LINK_UP;
 		} else if (speed == GXIO_MPIPE_LINK_10G) {
 			new.link_speed = ETH_LINK_SPEED_10000;
 			new.link_duplex = ETH_LINK_FULL_DUPLEX;
-			new.link_status = 1;
+			new.link_status = ETH_LINK_UP;
 		}
 
 		rc = mpipe_link_compare(&old, &new);
diff --git a/drivers/net/nfp/nfp_net.c b/drivers/net/nfp/nfp_net.c
index 98a957a..adde1a2 100644
--- a/drivers/net/nfp/nfp_net.c
+++ b/drivers/net/nfp/nfp_net.c
@@ -831,7 +831,7 @@ nfp_net_link_update(struct rte_eth_dev *dev, __rte_unused int wait_to_complete)
 
 	link.link_duplex = ETH_LINK_FULL_DUPLEX;
 	/* Other cards can limit the tx and rx rate per VF */
-	link.link_speed = ETH_LINK_SPEED_40G;
+	link.link_speed = ETH_SPEED_NUM_40G;
 
 	if (old.link_status != link.link_status) {
 		nfp_net_dev_atomic_write_link_status(dev, &link);
@@ -1072,7 +1072,7 @@ nfp_net_infos_get(struct rte_eth_dev *dev, struct rte_eth_dev_info *dev_info)
 	dev_info->reta_size = NFP_NET_CFG_RSS_ITBL_SZ;
 	dev_info->hash_key_size = NFP_NET_CFG_RSS_KEY_SZ;
 
-	dev_info->speed_capa = ETH_SPEED_CAP_50G | ETH_SPEED_CAP_100G;
+	dev_info->speed_capa = ETH_LINK_SPEED_50G | ETH_LINK_SPEED_100G;
 }
 
 static uint32_t
diff --git a/drivers/net/null/rte_eth_null.c b/drivers/net/null/rte_eth_null.c
index 77fc988..55e1fc8 100644
--- a/drivers/net/null/rte_eth_null.c
+++ b/drivers/net/null/rte_eth_null.c
@@ -93,9 +93,10 @@ struct pmd_internals {
 static struct ether_addr eth_addr = { .addr_bytes = {0} };
 static const char *drivername = "Null PMD";
 static struct rte_eth_link pmd_link = {
-	.link_speed = 10000,
+	.link_speed = ETH_SPEED_NUM_10G,
 	.link_duplex = ETH_LINK_FULL_DUPLEX,
-	.link_status = 0
+	.link_status = ETH_LINK_DOWN,
+	.link_autoneg = ETH_LINK_SPEED_NEG,
 };
 
 static uint16_t
diff --git a/drivers/net/pcap/rte_eth_pcap.c b/drivers/net/pcap/rte_eth_pcap.c
index f9230eb..650b521 100644
--- a/drivers/net/pcap/rte_eth_pcap.c
+++ b/drivers/net/pcap/rte_eth_pcap.c
@@ -125,9 +125,10 @@ static int open_single_iface(const char *iface, pcap_t **pcap);
 static struct ether_addr eth_addr = { .addr_bytes = { 0, 0, 0, 0x1, 0x2, 0x3 } };
 static const char *drivername = "Pcap PMD";
 static struct rte_eth_link pmd_link = {
-		.link_speed = 10000,
+		.link_speed = ETH_SPEED_NUM_10G,
 		.link_duplex = ETH_LINK_FULL_DUPLEX,
-		.link_status = 0
+		.link_status = ETH_LINK_DOWN,
+		.link_autoneg = ETH_LINK_SPEED_FIXED,
 };
 
 static int
@@ -430,7 +431,7 @@ eth_dev_start(struct rte_eth_dev *dev)
 
 status_up:
 
-	dev->data->dev_link.link_status = 1;
+	dev->data->dev_link.link_status = ETH_LINK_UP;
 	return 0;
 }
 
@@ -481,7 +482,7 @@ eth_dev_stop(struct rte_eth_dev *dev)
 	}
 
 status_down:
-	dev->data->dev_link.link_status = 0;
+	dev->data->dev_link.link_status = ETH_LINK_DOWN;
 }
 
 static int
diff --git a/drivers/net/ring/rte_eth_ring.c b/drivers/net/ring/rte_eth_ring.c
index d92b088..043175a 100644
--- a/drivers/net/ring/rte_eth_ring.c
+++ b/drivers/net/ring/rte_eth_ring.c
@@ -71,9 +71,10 @@ struct pmd_internals {
 
 static const char *drivername = "Rings PMD";
 static struct rte_eth_link pmd_link = {
-		.link_speed = 10000,
+		.link_speed = ETH_SPEED_NUM_10G,
 		.link_duplex = ETH_LINK_FULL_DUPLEX,
-		.link_status = 0
+		.link_status = ETH_LINK_DOWN,
+		.link_autoneg = ETH_LINK_SPEED_NEG
 };
 
 static uint16_t
diff --git a/drivers/net/virtio/virtio_ethdev.c b/drivers/net/virtio/virtio_ethdev.c
index caa970c..12e71af 100644
--- a/drivers/net/virtio/virtio_ethdev.c
+++ b/drivers/net/virtio/virtio_ethdev.c
@@ -1381,7 +1381,7 @@ virtio_dev_link_update(struct rte_eth_dev *dev, __rte_unused int wait_to_complet
 	memset(&link, 0, sizeof(link));
 	virtio_dev_atomic_read_link_status(dev, &link);
 	old = link;
-	link.link_duplex = FULL_DUPLEX;
+	link.link_duplex = ETH_LINK_FULL_DUPLEX;
 	link.link_speed  = SPEED_10G;
 
 	if (vtpci_with_feature(hw, VIRTIO_NET_F_STATUS)) {
diff --git a/drivers/net/virtio/virtio_ethdev.h b/drivers/net/virtio/virtio_ethdev.h
index fed9571..66423a0 100644
--- a/drivers/net/virtio/virtio_ethdev.h
+++ b/drivers/net/virtio/virtio_ethdev.h
@@ -42,8 +42,6 @@
 #define SPEED_100	100
 #define SPEED_1000	1000
 #define SPEED_10G	10000
-#define HALF_DUPLEX	1
-#define FULL_DUPLEX	2
 
 #ifndef PAGE_SIZE
 #define PAGE_SIZE 4096
diff --git a/drivers/net/vmxnet3/vmxnet3_ethdev.c b/drivers/net/vmxnet3/vmxnet3_ethdev.c
index c363bf6..2bb6ee9 100644
--- a/drivers/net/vmxnet3/vmxnet3_ethdev.c
+++ b/drivers/net/vmxnet3/vmxnet3_ethdev.c
@@ -736,9 +736,10 @@ vmxnet3_dev_link_update(struct rte_eth_dev *dev, __attribute__((unused)) int wai
 	ret = VMXNET3_READ_BAR1_REG(hw, VMXNET3_REG_CMD);
 
 	if (ret & 0x1) {
-		link.link_status = 1;
+		link.link_status = ETH_LINK_UP;
 		link.link_duplex = ETH_LINK_FULL_DUPLEX;
-		link.link_speed = ETH_LINK_SPEED_10000;
+		link.link_speed = ETH_SPEED_NUM_10G;
+		link.link_autoneg = ETH_LINK_SPEED_FIXED;
 	}
 
 	vmxnet3_dev_atomic_write_link_status(dev, &link);
diff --git a/drivers/net/xenvirt/rte_eth_xenvirt.c b/drivers/net/xenvirt/rte_eth_xenvirt.c
index 3f31806..0fcf5d3 100644
--- a/drivers/net/xenvirt/rte_eth_xenvirt.c
+++ b/drivers/net/xenvirt/rte_eth_xenvirt.c
@@ -70,9 +70,10 @@ static int virtio_idx = 0;
 static const char *drivername = "xen virtio PMD";
 
 static struct rte_eth_link pmd_link = {
-		.link_speed = 10000,
+		.link_speed = ETH_SPEED_NUM_10G,
 		.link_duplex = ETH_LINK_FULL_DUPLEX,
-		.link_status = 0
+		.link_status = ETH_LINK_DOWN,
+		.link_autoneg = ETH_LINK_SPEED_FIXED
 };
 
 static void
diff --git a/examples/ip_pipeline/config_parse.c b/examples/ip_pipeline/config_parse.c
index 1bedbe4..c581d41 100644
--- a/examples/ip_pipeline/config_parse.c
+++ b/examples/ip_pipeline/config_parse.c
@@ -84,8 +84,7 @@ static const struct app_link_params link_params_default = {
 	.mac_addr = 0,
 
 	.conf = {
-		.link_speed = 0,
-		.link_duplex = 0,
+		.link_speeds = 0,
 		.rxmode = {
 			.mq_mode = ETH_MQ_RX_NONE,
 
diff --git a/lib/librte_ether/rte_ethdev.c b/lib/librte_ether/rte_ethdev.c
index 756b234..7b0214d 100644
--- a/lib/librte_ether/rte_ethdev.c
+++ b/lib/librte_ether/rte_ethdev.c
@@ -865,6 +865,55 @@ rte_eth_dev_tx_queue_config(struct rte_eth_dev *dev, uint16_t nb_queues)
 }
 
 int
+rte_eth_speed_to_bm_flag(uint32_t speed, int duplex, uint32_t *flag)
+{
+	switch (speed) {
+	case ETH_SPEED_NUM_10M:
+		*flag = (duplex) ? ETH_LINK_SPEED_10M :
+							ETH_LINK_SPEED_10M_HD;
+		break;
+	case ETH_SPEED_NUM_100M:
+		*flag = (duplex) ? ETH_LINK_SPEED_100M :
+							ETH_LINK_SPEED_100M_HD;
+		break;
+	case ETH_SPEED_NUM_1G:
+		*flag = ETH_LINK_SPEED_1G;
+		break;
+	case ETH_SPEED_NUM_2_5G:
+		*flag = ETH_LINK_SPEED_2_5G;
+		break;
+	case ETH_SPEED_NUM_5G:
+		*flag = ETH_LINK_SPEED_5G;
+		break;
+	case ETH_SPEED_NUM_10G:
+		*flag = ETH_LINK_SPEED_10G;
+		break;
+	case ETH_SPEED_NUM_20G:
+		*flag = ETH_LINK_SPEED_20G;
+		break;
+	case ETH_SPEED_NUM_25G:
+		*flag = ETH_LINK_SPEED_25G;
+		break;
+	case ETH_SPEED_NUM_40G:
+		*flag = ETH_LINK_SPEED_40G;
+		break;
+	case ETH_SPEED_NUM_50G:
+		*flag = ETH_LINK_SPEED_50G;
+		break;
+	case ETH_SPEED_NUM_56G:
+		*flag = ETH_LINK_SPEED_56G;
+		break;
+	case ETH_SPEED_NUM_100G:
+		*flag = ETH_LINK_SPEED_100G;
+		break;
+	default:
+		return -EINVAL;
+	}
+
+	return 0;
+}
+
+int
 rte_eth_dev_configure(uint8_t port_id, uint16_t nb_rx_q, uint16_t nb_tx_q,
 		      const struct rte_eth_conf *dev_conf)
 {
diff --git a/lib/librte_ether/rte_ethdev.h b/lib/librte_ether/rte_ethdev.h
index 83ddbb7..8661521 100644
--- a/lib/librte_ether/rte_ethdev.h
+++ b/lib/librte_ether/rte_ethdev.h
@@ -242,26 +242,59 @@ struct rte_eth_stats {
 };
 
 /**
+ * Device supported speeds bitmap flags
+ */
+#define ETH_LINK_SPEED_AUTONEG		(0 << 0)  /*< Autonegociate (all speeds)  */
+#define ETH_LINK_SPEED_NO_AUTONEG	(1 << 0)  /*< Disable autoneg (fixed speed)  */
+#define ETH_LINK_SPEED_10M_HD		(1 << 1)  /*< 10 Mbps half-duplex */
+#define ETH_LINK_SPEED_10M		(1 << 2)  /*< 10 Mbps full-duplex */
+#define ETH_LINK_SPEED_100M_HD		(1 << 3)  /*< 100 Mbps half-duplex */
+#define ETH_LINK_SPEED_100M		(1 << 4)  /*< 100 Mbps full-duplex */
+#define ETH_LINK_SPEED_1G		(1 << 5)  /*< 1 Gbps */
+#define ETH_LINK_SPEED_2_5G		(1 << 6)  /*< 2.5 Gbps */
+#define ETH_LINK_SPEED_5G		(1 << 7)  /*< 5 Gbps */
+#define ETH_LINK_SPEED_10G		(1 << 8)  /*< 10 Mbps */
+#define ETH_LINK_SPEED_20G		(1 << 9)  /*< 20 Gbps */
+#define ETH_LINK_SPEED_25G		(1 << 10)  /*< 25 Gbps */
+#define ETH_LINK_SPEED_40G		(1 << 11)  /*< 40 Gbps */
+#define ETH_LINK_SPEED_50G		(1 << 12)  /*< 50 Gbps */
+#define ETH_LINK_SPEED_56G		(1 << 13)  /*< 56 Gbps */
+#define ETH_LINK_SPEED_100G		(1 << 14)  /*< 100 Gbps */
+
+/**
+ * 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 Mbps */
+#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 */
+
+/**
  * A structure used to retrieve link-level information of an Ethernet port.
  */
 struct rte_eth_link {
-	uint16_t link_speed;      /**< ETH_LINK_SPEED_[10, 100, 1000, 10000] */
-	uint16_t link_duplex;     /**< ETH_LINK_[HALF_DUPLEX, FULL_DUPLEX] */
-	uint8_t  link_status : 1; /**< 1 -> link up, 0 -> link down */
-}__attribute__((aligned(8)));     /**< aligned for atomic64 read/write */
-
-#define ETH_LINK_SPEED_AUTONEG  0       /**< Auto-negotiate link speed. */
-#define ETH_LINK_SPEED_10       10      /**< 10 megabits/second. */
-#define ETH_LINK_SPEED_100      100     /**< 100 megabits/second. */
-#define ETH_LINK_SPEED_1000     1000    /**< 1 gigabits/second. */
-#define ETH_LINK_SPEED_10000    10000   /**< 10 gigabits/second. */
-#define ETH_LINK_SPEED_10G      10000   /**< alias of 10 gigabits/second. */
-#define ETH_LINK_SPEED_20G      20000   /**< 20 gigabits/second. */
-#define ETH_LINK_SPEED_40G      40000   /**< 40 gigabits/second. */
+	uint64_t link_speed;        /**< Link speed (ETH_SPEED_NUM_) */
+	uint16_t link_duplex  : 1;  /**< 1 -> full duplex, 0 -> half duplex */
+	uint16_t link_autoneg : 1;  /**< 1 -> link speed has been autoneg */
+	uint16_t link_status  : 1;  /**< 1 -> link up, 0 -> link down */
+} __attribute__((aligned(8)));      /**< aligned for atomic64 read/write */
 
-#define ETH_LINK_AUTONEG_DUPLEX 0       /**< Auto-negotiate duplex. */
-#define ETH_LINK_HALF_DUPLEX    1       /**< Half-duplex connection. */
-#define ETH_LINK_FULL_DUPLEX    2       /**< Full-duplex connection. */
+/* Utility constants */
+#define ETH_LINK_HALF_DUPLEX    0	/**< Half-duplex connection. */
+#define ETH_LINK_FULL_DUPLEX    1	/**< Full-duplex connection. */
+#define ETH_LINK_SPEED_FIXED    0	/**< Link speed was not autonegociated. */
+#define ETH_LINK_SPEED_NEG      1	/**< Link speed was autonegociated. */
+#define ETH_LINK_DOWN		0	/**< Link is down. */
+#define ETH_LINK_UP		1	/**< Link is up. */
 
 /**
  * A structure used to configure the ring threshold registers of an RX/TX
@@ -760,10 +793,14 @@ struct rte_intr_conf {
  * configuration settings may be needed.
  */
 struct rte_eth_conf {
-	uint16_t link_speed;
-	/**< ETH_LINK_SPEED_10[0|00|000], or 0 for autonegotation */
-	uint16_t link_duplex;
-	/**< ETH_LINK_[HALF_DUPLEX|FULL_DUPLEX], or 0 for autonegotation */
+	uint32_t link_speeds; /**< bitmap of ETH_LINK_SPEED_XXX of speeds to be
+				used. ETH_LINK_SPEED_NO_AUTONEG disables link
+				autonegociation, and a unique speed shall be
+				set. Otherwise, the bitmap defines the set of
+				speeds to be advertised. If the special value
+				ETH_LINK_SPEED_AUTONEG (0) is used, all speeds
+				supported are advertised.
+				*/
 	struct rte_eth_rxmode rxmode; /**< Port RX configuration. */
 	struct rte_eth_txmode txmode; /**< Port TX configuration. */
 	uint32_t lpbk_mode; /**< Loopback operation mode. By default the value
@@ -825,26 +862,6 @@ struct rte_eth_conf {
 #define DEV_TX_OFFLOAD_QINQ_INSERT 0x00000100
 
 /**
- * Device supported speeds
- */
-#define ETH_SPEED_CAP_NOT_PHY	(0)  /*< No phy media > */
-#define ETH_SPEED_CAP_10M_HD	(1 << 0)  /*< 10 Mbps half-duplex> */
-#define ETH_SPEED_CAP_10M_FD	(1 << 1)  /*< 10 Mbps full-duplex> */
-#define ETH_SPEED_CAP_100M_HD	(1 << 2)  /*< 100 Mbps half-duplex> */
-#define ETH_SPEED_CAP_100M_FD	(1 << 3)  /*< 100 Mbps full-duplex> */
-#define ETH_SPEED_CAP_1G	(1 << 4)  /*< 1 Gbps > */
-#define ETH_SPEED_CAP_2_5G	(1 << 5)  /*< 2.5 Gbps > */
-#define ETH_SPEED_CAP_5G	(1 << 6)  /*< 5 Gbps > */
-#define ETH_SPEED_CAP_10G	(1 << 7)  /*< 10 Mbps > */
-#define ETH_SPEED_CAP_20G	(1 << 8)  /*< 20 Gbps > */
-#define ETH_SPEED_CAP_25G	(1 << 9)  /*< 25 Gbps > */
-#define ETH_SPEED_CAP_40G	(1 << 10)  /*< 40 Gbps > */
-#define ETH_SPEED_CAP_50G	(1 << 11)  /*< 50 Gbps > */
-#define ETH_SPEED_CAP_56G	(1 << 12)  /*< 56 Gbps > */
-#define ETH_SPEED_CAP_100G	(1 << 13)  /*< 100 Gbps > */
-
-
-/**
  * Ethernet device information
  */
 struct rte_eth_dev_info {
@@ -1811,6 +1828,22 @@ struct eth_driver {
 void rte_eth_driver_register(struct eth_driver *eth_drv);
 
 /**
+ * Convert a numerical speed in Mbps to a bitmap flag that can be used in
+ * the bitmap link_speeds of the struct rte_eth_conf
+ *
+ * @param
+ *   Numerical speed value in Mbps
+ * @param
+ *   Boolean is duplex (only for 10/100 speeds)
+ * @param
+ *   On success, the converted speed into a bitmap flag
+ * @return
+ *   0 on success, -EINVAL if the speed cannot be mapped
+ */
+extern int rte_eth_speed_to_bm_flag(uint32_t speed, int duplex,
+							uint32_t *flag);
+
+/**
  * Configure an Ethernet device.
  * This function must be invoked first before any other function in the
  * Ethernet API. This function can also be re-invoked when a device is in the
diff --git a/lib/librte_ether/rte_ether_version.map b/lib/librte_ether/rte_ether_version.map
index d8db24d..2c14ad7 100644
--- a/lib/librte_ether/rte_ether_version.map
+++ b/lib/librte_ether/rte_ether_version.map
@@ -117,3 +117,9 @@ DPDK_2.2 {
 
 	local: *;
 };
+
+DPDK_2.3 {
+	global:
+
+	rte_eth_speed_to_bm_flag;
+}DPDK_2.2;
-- 
2.1.4

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

* [PATCH v8 4/4] doc: update with link changes
  2016-02-14 22:17     ` [PATCH v8 0/4] ethdev: add speed capabilities and refactor link API Marc Sune
                         ` (2 preceding siblings ...)
  2016-02-14 22:17       ` [PATCH v8 3/4] ethdev: redesign link speed config API Marc Sune
@ 2016-02-14 22:17       ` Marc Sune
  2016-02-18 18:14         ` Mcnamara, John
  2016-03-01  0:45       ` [PATCH v9 0/4] ethdev: add speed capabilities and refactor link API Marc Sune
  4 siblings, 1 reply; 167+ messages in thread
From: Marc Sune @ 2016-02-14 22:17 UTC (permalink / raw)
  To: dev, Wenzhuo Lu, Helin Zhang, Harish Patil, Jing Chen

Add new features, ABI changes and resolved issues notice for
the refactored link patch.

Signed-off-by: Marc Sune <marcdevel@gmail.com>
---
 doc/guides/rel_notes/release_2_3.rst | 102 +++++++++++++++++++++++++++++++++++
 1 file changed, 102 insertions(+)
 create mode 100644 doc/guides/rel_notes/release_2_3.rst

diff --git a/doc/guides/rel_notes/release_2_3.rst b/doc/guides/rel_notes/release_2_3.rst
new file mode 100644
index 0000000..b10c3bb
--- /dev/null
+++ b/doc/guides/rel_notes/release_2_3.rst
@@ -0,0 +1,102 @@
+DPDK Release 2.3
+================
+
+New Features
+------------
+
+* **ethdev: define a set of advertised link speeds.**
+
+  Allowing to define a set of advertised speeds for auto-negociation,
+  explicitely disable link auto-negociation (single speed) and full
+  auto-negociation.
+
+* **ethdev: add speed_cap bitmap to recover eth device link speed capabilities
+  define a set of advertised link speeds.**
+
+  ``struct rte_eth_dev_info`` has now speed_cap bitmap, which allows the
+  application to recover the supported speeds for that ethernet device.
+
+
+Resolved Issues
+---------------
+
+* **ethdev: Fixed link_speed overflow in rte_eth_link for 100Gbps.**
+
+  100Gbps in Mbps (100000) exceeds 16 bit max value of ``link_speed`` in
+  ``rte_eth_link``.
+
+
+EAL
+~~~
+
+
+Drivers
+~~~~~~~
+
+
+Libraries
+~~~~~~~~~
+
+
+Examples
+~~~~~~~~
+
+* New API call, rte_eth_speed_to_bm_flag(), in ethdev to map numerical speeds
+  to bitmap fields.
+
+
+Other
+~~~~~
+
+
+Known Issues
+------------
+
+
+API Changes
+-----------
+
+
+ABI Changes
+-----------
+
+* The ethdev rte_eth_link and rte_eth_conf structures were changed to
+  support the new link API, as well as ETH_LINK_HALF/FULL_DUPLEX.
+
+* The ethdev rte_eth_dev_info was changed to support device speed capabilities.
+
+
+Shared Library Versions
+-----------------------
+
+The libraries prepended with a plus sign were incremented in this version.
+
+.. code-block:: diff
+
+     libethdev.so.2
+     librte_acl.so.2
+     librte_cfgfile.so.2
+     librte_cmdline.so.1
+     librte_distributor.so.1
+     librte_eal.so.2
+     librte_hash.so.2
+     librte_ip_frag.so.1
+     librte_ivshmem.so.1
+     librte_jobstats.so.1
+     librte_kni.so.2
+     librte_kvargs.so.1
+     librte_lpm.so.2
+     librte_mbuf.so.2
+     librte_mempool.so.1
+     librte_meter.so.1
+     librte_pipeline.so.2
+     librte_pmd_bond.so.1
+     librte_pmd_ring.so.2
+     librte_port.so.2
+     librte_power.so.1
+     librte_reorder.so.1
+     librte_ring.so.1
+     librte_sched.so.1
+     librte_table.so.2
+     librte_timer.so.1
+     librte_vhost.so.2
-- 
2.1.4

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

* Re: [PATCH v8 2/4] ethdev: Fill speed capability bitmaps in the PMDs
  2016-02-14 22:17       ` [PATCH v8 2/4] ethdev: Fill speed capability bitmaps in the PMDs Marc Sune
@ 2016-02-15  8:43         ` Nélio Laranjeiro
  2016-02-15  9:17           ` Chen, Jing D
  2016-02-15 14:43         ` Rahul Lakkireddy
  1 sibling, 1 reply; 167+ messages in thread
From: Nélio Laranjeiro @ 2016-02-15  8:43 UTC (permalink / raw)
  To: Marc Sune; +Cc: dev

On Sun, Feb 14, 2016 at 11:17:37PM +0100, Marc Sune wrote:
> Added speed capabilities to all pmds supporting physical NICs:
> 
> * e1000
> * ixgbe
> * i40
> * bnx2x
> * cxgbe
> * mlx4
> * mlx5
> * nfp
> * fm10k
>[...]
> diff --git a/drivers/net/mlx5/mlx5_ethdev.c b/drivers/net/mlx5/mlx5_ethdev.c
> index 1159fa3..99dac09 100644
> --- a/drivers/net/mlx5/mlx5_ethdev.c
> +++ b/drivers/net/mlx5/mlx5_ethdev.c
> @@ -523,6 +523,11 @@ mlx5_dev_infos_get(struct rte_eth_dev *dev, struct rte_eth_dev_info *info)
>  	 * size if it is not fixed.
>  	 * The API should be updated to solve this problem. */
>  	info->reta_size = priv->ind_table_max_size;
> +
> +	info->speed_capa = ETH_SPEED_CAP_1G | ETH_SPEED_CAP_10G |
> +					ETH_SPEED_CAP_10G | ETH_SPEED_CAP_40G |
> +					ETH_SPEED_CAP_56G;
> +
>  	priv_unlock(priv);
>  }

Hi Marc,

I have a question about this information, is it a list of the
capabilities of the family or the capability of the NIC?
Because with ConnectX4 family we have a range of NICs which does not
support all this kind of speeds.

The speeds above are not completed the range is 1/10/25/40/50/100G.

-- 
Nélio Laranjeiro
6WIND

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

* Re: [PATCH v8 3/4] ethdev: redesign link speed config API
  2016-02-14 22:17       ` [PATCH v8 3/4] ethdev: redesign link speed config API Marc Sune
@ 2016-02-15  8:46         ` Nélio Laranjeiro
  2016-02-15 11:00           ` Marc
  2016-02-16 10:28         ` Matej Vido
  1 sibling, 1 reply; 167+ messages in thread
From: Nélio Laranjeiro @ 2016-02-15  8:46 UTC (permalink / raw)
  To: Marc Sune; +Cc: dev

On Sun, Feb 14, 2016 at 11:17:38PM +0100, Marc Sune wrote:
> This patch redesigns the API to set the link speed/s configure
> for an ethernet port. Specifically:
> 
> - it allows to define a set of advertised speeds for
>   auto-negociation.
> - it allows to disable link auto-negociation (single fixed speed).
> - default: auto-negociate all supported speeds.
> 
>[...]
> diff --git a/drivers/net/mlx4/mlx4.c b/drivers/net/mlx4/mlx4.c
> index c5688a7..01c3a5c 100644
> --- a/drivers/net/mlx4/mlx4.c
> +++ b/drivers/net/mlx4/mlx4.c
> @@ -4265,8 +4265,8 @@ mlx4_dev_infos_get(struct rte_eth_dev *dev, struct rte_eth_dev_info *info)
>  	if (priv_get_ifname(priv, &ifname) == 0)
>  		info->if_index = if_nametoindex(ifname);
>  
> -	info->speed_capa = ETH_SPEED_CAP_10G |ETH_SPEED_CAP_40G |
> -					ETH_SPEED_CAP_56G;
> +	info->speed_capa = ETH_LINK_SPEED_10G |ETH_LINK_SPEED_40G |
> +					ETH_LINK_SPEED_56G;
>  
>  	priv_unlock(priv);
>  }
> @@ -4636,6 +4636,8 @@ mlx4_link_update_unlocked(struct rte_eth_dev *dev, int wait_to_complete)
>  		dev_link.link_speed = link_speed;
>  	dev_link.link_duplex = ((edata.duplex == DUPLEX_HALF) ?
>  				ETH_LINK_HALF_DUPLEX : ETH_LINK_FULL_DUPLEX);
> +	dev_link.link_autoneg = ~(dev->data->dev_conf.link_speeds &
> +						ETH_LINK_SPEED_NO_AUTONEG);
>  	if (memcmp(&dev_link, &dev->data->dev_link, sizeof(dev_link))) {
>  		/* Link status changed. */
>  		dev->data->dev_link = dev_link;
>[...]

The same modification are missing in mlx5.

-- 
Nélio Laranjeiro
6WIND

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

* Re: [PATCH v8 2/4] ethdev: Fill speed capability bitmaps in the PMDs
  2016-02-15  8:43         ` Nélio Laranjeiro
@ 2016-02-15  9:17           ` Chen, Jing D
  0 siblings, 0 replies; 167+ messages in thread
From: Chen, Jing D @ 2016-02-15  9:17 UTC (permalink / raw)
  To: Nélio Laranjeiro, Marc Sune; +Cc: dev

Hi, Marc,

Best Regards,
Mark

> -----Original Message-----
> From: Nélio Laranjeiro [mailto:nelio.laranjeiro@6wind.com]
> Sent: Monday, February 15, 2016 4:43 PM
> To: Marc Sune
> Cc: dev@dpdk.org; Lu, Wenzhuo; Zhang, Helin; Harish Patil; Chen, Jing D
> Subject: Re: [dpdk-dev] [PATCH v8 2/4] ethdev: Fill speed capability bitmaps
> in the PMDs
> 
> On Sun, Feb 14, 2016 at 11:17:37PM +0100, Marc Sune wrote:
> > Added speed capabilities to all pmds supporting physical NICs:
> >
> > * e1000
> > * ixgbe
> > * i40
> > * bnx2x
> > * cxgbe
> > * mlx4
> > * mlx5
> > * nfp
> > * fm10k
> >[...]
> > diff --git a/drivers/net/mlx5/mlx5_ethdev.c
> b/drivers/net/mlx5/mlx5_ethdev.c
> > index 1159fa3..99dac09 100644
> > --- a/drivers/net/mlx5/mlx5_ethdev.c
> > +++ b/drivers/net/mlx5/mlx5_ethdev.c
> > @@ -523,6 +523,11 @@ mlx5_dev_infos_get(struct rte_eth_dev *dev,
> struct rte_eth_dev_info *info)
> >  	 * size if it is not fixed.
> >  	 * The API should be updated to solve this problem. */
> >  	info->reta_size = priv->ind_table_max_size;
> > +
> > +	info->speed_capa = ETH_SPEED_CAP_1G | ETH_SPEED_CAP_10G |
> > +					ETH_SPEED_CAP_10G |
> ETH_SPEED_CAP_40G |
> > +					ETH_SPEED_CAP_56G;
> > +
> >  	priv_unlock(priv);
> >  }
> 
> Hi Marc,
> 
> I have a question about this information, is it a list of the
> capabilities of the family or the capability of the NIC?
> Because with ConnectX4 family we have a range of NICs which does not
> support all this kind of speeds.
> 
> The speeds above are not completed the range is 1/10/25/40/50/100G.
> 

Fm10k also includes several cards and different ones are designed to have different speed.
A better solution for fm10k is to acquire NIC type (like, BR card for 100G/40G, Atwood for 25/10G, etc)
Then, return proper speed.

> --
> Nélio Laranjeiro
> 6WIND

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

* Re: [PATCH v8 3/4] ethdev: redesign link speed config API
  2016-02-15  8:46         ` Nélio Laranjeiro
@ 2016-02-15 11:00           ` Marc
  2016-02-15 11:39             ` Olga Shern
  0 siblings, 1 reply; 167+ messages in thread
From: Marc @ 2016-02-15 11:00 UTC (permalink / raw)
  To: Nélio Laranjeiro; +Cc: dev

On 15 February 2016 at 09:46, Nélio Laranjeiro <nelio.laranjeiro@6wind.com>
wrote:

> On Sun, Feb 14, 2016 at 11:17:38PM +0100, Marc Sune wrote:
> > This patch redesigns the API to set the link speed/s configure
> > for an ethernet port. Specifically:
> >
> > - it allows to define a set of advertised speeds for
> >   auto-negociation.
> > - it allows to disable link auto-negociation (single fixed speed).
> > - default: auto-negociate all supported speeds.
> >
> >[...]
> > diff --git a/drivers/net/mlx4/mlx4.c b/drivers/net/mlx4/mlx4.c
> > index c5688a7..01c3a5c 100644
> > --- a/drivers/net/mlx4/mlx4.c
> > +++ b/drivers/net/mlx4/mlx4.c
> > @@ -4265,8 +4265,8 @@ mlx4_dev_infos_get(struct rte_eth_dev *dev, struct
> rte_eth_dev_info *info)
> >       if (priv_get_ifname(priv, &ifname) == 0)
> >               info->if_index = if_nametoindex(ifname);
> >
> > -     info->speed_capa = ETH_SPEED_CAP_10G |ETH_SPEED_CAP_40G |
> > -                                     ETH_SPEED_CAP_56G;
> > +     info->speed_capa = ETH_LINK_SPEED_10G |ETH_LINK_SPEED_40G |
> > +                                     ETH_LINK_SPEED_56G;
> >
> >       priv_unlock(priv);
> >  }
> > @@ -4636,6 +4636,8 @@ mlx4_link_update_unlocked(struct rte_eth_dev *dev,
> int wait_to_complete)
> >               dev_link.link_speed = link_speed;
> >       dev_link.link_duplex = ((edata.duplex == DUPLEX_HALF) ?
> >                               ETH_LINK_HALF_DUPLEX :
> ETH_LINK_FULL_DUPLEX);
> > +     dev_link.link_autoneg = ~(dev->data->dev_conf.link_speeds &
> > +                                             ETH_LINK_SPEED_NO_AUTONEG);
> >       if (memcmp(&dev_link, &dev->data->dev_link, sizeof(dev_link))) {
> >               /* Link status changed. */
> >               dev->data->dev_link = dev_link;
> >[...]
>
> The same modification are missing in mlx5.
>
>
Damn.. are the required closed-source libraries for MLX4/5 available
somewhere or is there a chance automatic builds can also compile drivers
that require external dependencies (like this MLX)?

It is very prone to errors having to guess what is going to happen without
being able to compile these drivers.

Marc

--
> Nélio Laranjeiro
> 6WIND
>

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

* Re: [PATCH v8 3/4] ethdev: redesign link speed config API
  2016-02-15 11:00           ` Marc
@ 2016-02-15 11:39             ` Olga Shern
  0 siblings, 0 replies; 167+ messages in thread
From: Olga Shern @ 2016-02-15 11:39 UTC (permalink / raw)
  To: Marc, Nélio Laranjeiro; +Cc: dev

Hi Marc, 

You can download MLNX_OFED from Mellanox web site:
http://www.mellanox.com/page/products_dyn?product_family=26&mtag=linux_sw_drivers

Best Regards,
Olga

-----Original Message-----
From: dev [mailto:dev-bounces@dpdk.org] On Behalf Of Marc
Sent: Monday, February 15, 2016 1:00 PM
To: Nélio Laranjeiro
Cc: dev@dpdk.org
Subject: Re: [dpdk-dev] [PATCH v8 3/4] ethdev: redesign link speed config API

On 15 February 2016 at 09:46, Nélio Laranjeiro <nelio.laranjeiro@6wind.com>
wrote:

> On Sun, Feb 14, 2016 at 11:17:38PM +0100, Marc Sune wrote:
> > This patch redesigns the API to set the link speed/s configure for 
> > an ethernet port. Specifically:
> >
> > - it allows to define a set of advertised speeds for
> >   auto-negociation.
> > - it allows to disable link auto-negociation (single fixed speed).
> > - default: auto-negociate all supported speeds.
> >
> >[...]
> > diff --git a/drivers/net/mlx4/mlx4.c b/drivers/net/mlx4/mlx4.c  
> >index c5688a7..01c3a5c 100644
> > --- a/drivers/net/mlx4/mlx4.c
> > +++ b/drivers/net/mlx4/mlx4.c
> > @@ -4265,8 +4265,8 @@ mlx4_dev_infos_get(struct rte_eth_dev *dev, 
> > struct
> rte_eth_dev_info *info)
> >       if (priv_get_ifname(priv, &ifname) == 0)
> >               info->if_index = if_nametoindex(ifname);
> >
> > -     info->speed_capa = ETH_SPEED_CAP_10G |ETH_SPEED_CAP_40G |
> > -                                     ETH_SPEED_CAP_56G;
> > +     info->speed_capa = ETH_LINK_SPEED_10G |ETH_LINK_SPEED_40G |
> > +                                     ETH_LINK_SPEED_56G;
> >
> >       priv_unlock(priv);
> >  }
> > @@ -4636,6 +4636,8 @@ mlx4_link_update_unlocked(struct rte_eth_dev 
> > *dev,
> int wait_to_complete)
> >               dev_link.link_speed = link_speed;
> >       dev_link.link_duplex = ((edata.duplex == DUPLEX_HALF) ?
> >                               ETH_LINK_HALF_DUPLEX :
> ETH_LINK_FULL_DUPLEX);
> > +     dev_link.link_autoneg = ~(dev->data->dev_conf.link_speeds &
> > +                                             
> > + ETH_LINK_SPEED_NO_AUTONEG);
> >       if (memcmp(&dev_link, &dev->data->dev_link, sizeof(dev_link))) {
> >               /* Link status changed. */
> >               dev->data->dev_link = dev_link; [...]
>
> The same modification are missing in mlx5.
>
>
Damn.. are the required closed-source libraries for MLX4/5 available somewhere or is there a chance automatic builds can also compile drivers that require external dependencies (like this MLX)?

It is very prone to errors having to guess what is going to happen without being able to compile these drivers.

Marc

--
> Nélio Laranjeiro
> 6WIND
>

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

* Re: [PATCH v8 2/4] ethdev: Fill speed capability bitmaps in the PMDs
  2016-02-14 22:17       ` [PATCH v8 2/4] ethdev: Fill speed capability bitmaps in the PMDs Marc Sune
  2016-02-15  8:43         ` Nélio Laranjeiro
@ 2016-02-15 14:43         ` Rahul Lakkireddy
  2016-02-15 17:14           ` Marc
  1 sibling, 1 reply; 167+ messages in thread
From: Rahul Lakkireddy @ 2016-02-15 14:43 UTC (permalink / raw)
  To: Marc Sune; +Cc: dev, Kumar Sanghvi, Nirranjan Kirubaharan

Hi Marc,

On Sunday, February 02/14/16, 2016 at 23:17:37 +0100, Marc Sune wrote:
> Added speed capabilities to all pmds supporting physical NICs:
> 
> * e1000
> * ixgbe
> * i40
> * bnx2x
> * cxgbe
> * mlx4
> * mlx5
> * nfp
> * fm10k
> 
> Signed-off-by: Marc Sune <marcdevel@gmail.com>
> ---
>  drivers/net/bnx2x/bnx2x_ethdev.c |  1 +
>  drivers/net/cxgbe/cxgbe_ethdev.c |  1 +
>  drivers/net/e1000/em_ethdev.c    |  6 ++++++
>  drivers/net/e1000/igb_ethdev.c   |  6 ++++++
>  drivers/net/fm10k/fm10k_ethdev.c |  4 ++++
>  drivers/net/i40e/i40e_ethdev.c   |  9 +++++++++
>  drivers/net/ixgbe/ixgbe_ethdev.c | 10 ++++++++++
>  drivers/net/mlx4/mlx4.c          |  4 ++++
>  drivers/net/mlx5/mlx5_ethdev.c   |  5 +++++
>  drivers/net/nfp/nfp_net.c        |  2 ++
>  10 files changed, 48 insertions(+)
> 

[...]

> diff --git a/drivers/net/cxgbe/cxgbe_ethdev.c b/drivers/net/cxgbe/cxgbe_ethdev.c
> index 97ef152..203e119 100644
> --- a/drivers/net/cxgbe/cxgbe_ethdev.c
> +++ b/drivers/net/cxgbe/cxgbe_ethdev.c
> @@ -171,6 +171,7 @@ static void cxgbe_dev_info_get(struct rte_eth_dev *eth_dev,
>  
>  	device_info->rx_desc_lim = cxgbe_desc_lim;
>  	device_info->tx_desc_lim = cxgbe_desc_lim;
> +	device_info->speed_capa = ETH_SPEED_CAP_10G | ETH_SPEED_CAP_40G;
>  }
>  

Not all Chelsio NICs support _both_ 10G and 40G speed capabilities on a
single card.  You can query pi->link_cfg.supported to get the supported
speeds.  Check out print_port_info() in cxgbe_main.c to help you fill
in your speed capabilities for Chelsio NICs.

Thanks,
Rahul

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

* Re: [PATCH v8 2/4] ethdev: Fill speed capability bitmaps in the PMDs
  2016-02-15 14:43         ` Rahul Lakkireddy
@ 2016-02-15 17:14           ` Marc
  2016-02-16 15:25             ` Nélio Laranjeiro
  0 siblings, 1 reply; 167+ messages in thread
From: Marc @ 2016-02-15 17:14 UTC (permalink / raw)
  To: Rahul Lakkireddy; +Cc: dev, Kumar Sanghvi, Nirranjan Kirubaharan

Rahul, Neilo, Jing D, et al

On 15 February 2016 at 15:43, Rahul Lakkireddy <rahul.lakkireddy@chelsio.com
> wrote:

> Hi Marc,
>
> On Sunday, February 02/14/16, 2016 at 23:17:37 +0100, Marc Sune wrote:
> > Added speed capabilities to all pmds supporting physical NICs:
> >
> > * e1000
> > * ixgbe
> > * i40
> > * bnx2x
> > * cxgbe
> > * mlx4
> > * mlx5
> > * nfp
> > * fm10k
> >
> > Signed-off-by: Marc Sune <marcdevel@gmail.com>
> > ---
> >  drivers/net/bnx2x/bnx2x_ethdev.c |  1 +
> >  drivers/net/cxgbe/cxgbe_ethdev.c |  1 +
> >  drivers/net/e1000/em_ethdev.c    |  6 ++++++
> >  drivers/net/e1000/igb_ethdev.c   |  6 ++++++
> >  drivers/net/fm10k/fm10k_ethdev.c |  4 ++++
> >  drivers/net/i40e/i40e_ethdev.c   |  9 +++++++++
> >  drivers/net/ixgbe/ixgbe_ethdev.c | 10 ++++++++++
> >  drivers/net/mlx4/mlx4.c          |  4 ++++
> >  drivers/net/mlx5/mlx5_ethdev.c   |  5 +++++
> >  drivers/net/nfp/nfp_net.c        |  2 ++
> >  10 files changed, 48 insertions(+)
> >
>
> [...]
>
> > diff --git a/drivers/net/cxgbe/cxgbe_ethdev.c
> b/drivers/net/cxgbe/cxgbe_ethdev.c
> > index 97ef152..203e119 100644
> > --- a/drivers/net/cxgbe/cxgbe_ethdev.c
> > +++ b/drivers/net/cxgbe/cxgbe_ethdev.c
> > @@ -171,6 +171,7 @@ static void cxgbe_dev_info_get(struct rte_eth_dev
> *eth_dev,
> >
> >       device_info->rx_desc_lim = cxgbe_desc_lim;
> >       device_info->tx_desc_lim = cxgbe_desc_lim;
> > +     device_info->speed_capa = ETH_SPEED_CAP_10G | ETH_SPEED_CAP_40G;
> >  }
> >
>
> Not all Chelsio NICs support _both_ 10G and 40G speed capabilities on a
> single card.  You can query pi->link_cfg.supported to get the supported
> speeds.  Check out print_port_info() in cxgbe_main.c to help you fill
> in your speed capabilities for Chelsio NICs.
>

This patch series has been long delayed, and I've been requested to merge
it for next release if possible. Most of the feedback has been coming late
(not for cxgbe, which is introduced in this new v8, but it did for most of
the rest of drivers).

My proposal is simply to add in this patch series ALL possible speeds for
that driver. Other patches can be later submitted to adjust speeds
according to specific device model.

marc


>
> Thanks,
> Rahul
>

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

* Re: [PATCH v8 3/4] ethdev: redesign link speed config API
  2016-02-14 22:17       ` [PATCH v8 3/4] ethdev: redesign link speed config API Marc Sune
  2016-02-15  8:46         ` Nélio Laranjeiro
@ 2016-02-16 10:28         ` Matej Vido
  2016-02-16 22:55           ` Marc
  1 sibling, 1 reply; 167+ messages in thread
From: Matej Vido @ 2016-02-16 10:28 UTC (permalink / raw)
  To: Marc Sune, dev, Wenzhuo Lu, Helin Zhang, Harish Patil, Jing Chen

Dňa 14.02.2016 o 23:17 Marc Sune napísal(a):
> This patch redesigns the API to set the link speed/s configure
> for an ethernet port. Specifically:
>
> - it allows to define a set of advertised speeds for
>    auto-negociation.
> - it allows to disable link auto-negociation (single fixed speed).
> - default: auto-negociate all supported speeds.
>
> Other changes:
>
> * Added utility MACROs ETH_SPEED_NUM_XXX with the numeric
>    values of all supported link speeds, in Mbps.
> * Converted link_speed to uint64_t to accomodate 100G speeds
>    and beyond (bug).
> * Added autoneg flag in struct rte_eth_link to indicate if
>    link speed was a result of auto-negociation or was fixed
>    by configuration.
> * Added utility function to convert numeric speeds to bitmap
>    fields.
> * Added rte_eth_speed_to_bm_flag() to version map.
>
> Signed-off-by: Marc Sune <marcdevel@gmail.com>
> ---
>   app/test-pipeline/init.c                  |   2 +-
>   app/test-pmd/cmdline.c                    | 124 +++++++++++++++---------------
>   app/test-pmd/config.c                     |   4 +-
>   app/test/virtual_pmd.c                    |   4 +-
>   drivers/net/af_packet/rte_eth_af_packet.c |   5 +-
>   drivers/net/bnx2x/bnx2x_ethdev.c          |   8 +-
>   drivers/net/bonding/rte_eth_bond_8023ad.c |  14 ++--
>   drivers/net/cxgbe/base/t4_hw.c            |   8 +-
>   drivers/net/cxgbe/cxgbe_ethdev.c          |   2 +-
>   drivers/net/e1000/em_ethdev.c             | 116 ++++++++++++++--------------
>   drivers/net/e1000/igb_ethdev.c            | 111 +++++++++++++-------------
>   drivers/net/fm10k/fm10k_ethdev.c          |   8 +-
>   drivers/net/i40e/i40e_ethdev.c            |  73 +++++++++---------
>   drivers/net/i40e/i40e_ethdev_vf.c         |  11 +--
>   drivers/net/ixgbe/ixgbe_ethdev.c          |  78 ++++++++-----------
>   drivers/net/mlx4/mlx4.c                   |   6 +-
>   drivers/net/mpipe/mpipe_tilegx.c          |   6 +-
>   drivers/net/nfp/nfp_net.c                 |   4 +-
>   drivers/net/null/rte_eth_null.c           |   5 +-
>   drivers/net/pcap/rte_eth_pcap.c           |   9 ++-
>   drivers/net/ring/rte_eth_ring.c           |   5 +-
>   drivers/net/virtio/virtio_ethdev.c        |   2 +-
>   drivers/net/virtio/virtio_ethdev.h        |   2 -
>   drivers/net/vmxnet3/vmxnet3_ethdev.c      |   5 +-
>   drivers/net/xenvirt/rte_eth_xenvirt.c     |   5 +-
>   examples/ip_pipeline/config_parse.c       |   3 +-
>   lib/librte_ether/rte_ethdev.c             |  49 ++++++++++++
>   lib/librte_ether/rte_ethdev.h             | 113 +++++++++++++++++----------
>   lib/librte_ether/rte_ether_version.map    |   6 ++
>   29 files changed, 443 insertions(+), 345 deletions(-)
>
> [...]

Hi,

some drivers (at least: e1000, i40e, ixgbe, mpipe, nfp, virtio, vmxnet3) 
use rte_atomic64_cmpset() to read and write link state like:

static inline int
rte_em_dev_atomic_read_link_status(struct rte_eth_dev *dev,
                                 struct rte_eth_link *link)
{
         struct rte_eth_link *dst = link;
         struct rte_eth_link *src = &(dev->data->dev_link);

         if (rte_atomic64_cmpset((uint64_t *)dst, *(uint64_t *)dst,
                                         *(uint64_t *)src) == 0)
                 return -1;

         return 0;
}

static inline int
rte_em_dev_atomic_write_link_status(struct rte_eth_dev *dev,
                                 struct rte_eth_link *link)
{
         struct rte_eth_link *dst = &(dev->data->dev_link);
         struct rte_eth_link *src = link;

         if (rte_atomic64_cmpset((uint64_t *)dst, *(uint64_t *)dst,
                                         *(uint64_t *)src) == 0)
                 return -1;

         return 0;
}


When link_speed is changed to uint64_t, struct rte_eth_link exceeds 64 
bits. Shouldn't these functions be adapted in this patch series?

Szedata2 PMD will also use rte_atomic64_cmpset() after patch [1].
I can take care of this change in szedata2 PMD when patch [1] is 
accepted together with adjusting speeds in szedata2 PMD.

[1] http://dpdk.org/ml/archives/dev/2016-January/032281.html

Regards,
Matej

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

* Re: [PATCH v8 2/4] ethdev: Fill speed capability bitmaps in the PMDs
  2016-02-15 17:14           ` Marc
@ 2016-02-16 15:25             ` Nélio Laranjeiro
  2016-02-16 22:49               ` Marc
  0 siblings, 1 reply; 167+ messages in thread
From: Nélio Laranjeiro @ 2016-02-16 15:25 UTC (permalink / raw)
  To: Marc; +Cc: dev, Nirranjan Kirubaharan, Kumar Sanghvi

Hi Marc,

On Mon, Feb 15, 2016 at 06:14:42PM +0100, Marc wrote:
> Rahul, Neilo, Jing D, et al
> 
> On 15 February 2016 at 15:43, Rahul Lakkireddy <rahul.lakkireddy@chelsio.com
> > wrote:
> 
> > Hi Marc,
> >
> > On Sunday, February 02/14/16, 2016 at 23:17:37 +0100, Marc Sune wrote:
> > > Added speed capabilities to all pmds supporting physical NICs:
> > >
> > > * e1000
> > > * ixgbe
> > > * i40
> > > * bnx2x
> > > * cxgbe
> > > * mlx4
> > > * mlx5
> > > * nfp
> > > * fm10k
> > >
> > > Signed-off-by: Marc Sune <marcdevel@gmail.com>
> > > ---
> > >  drivers/net/bnx2x/bnx2x_ethdev.c |  1 +
> > >  drivers/net/cxgbe/cxgbe_ethdev.c |  1 +
> > >  drivers/net/e1000/em_ethdev.c    |  6 ++++++
> > >  drivers/net/e1000/igb_ethdev.c   |  6 ++++++
> > >  drivers/net/fm10k/fm10k_ethdev.c |  4 ++++
> > >  drivers/net/i40e/i40e_ethdev.c   |  9 +++++++++
> > >  drivers/net/ixgbe/ixgbe_ethdev.c | 10 ++++++++++
> > >  drivers/net/mlx4/mlx4.c          |  4 ++++
> > >  drivers/net/mlx5/mlx5_ethdev.c   |  5 +++++
> > >  drivers/net/nfp/nfp_net.c        |  2 ++
> > >  10 files changed, 48 insertions(+)
> > >
> >
> > [...]
> >
> > > diff --git a/drivers/net/cxgbe/cxgbe_ethdev.c
> > b/drivers/net/cxgbe/cxgbe_ethdev.c
> > > index 97ef152..203e119 100644
> > > --- a/drivers/net/cxgbe/cxgbe_ethdev.c
> > > +++ b/drivers/net/cxgbe/cxgbe_ethdev.c
> > > @@ -171,6 +171,7 @@ static void cxgbe_dev_info_get(struct rte_eth_dev
> > *eth_dev,
> > >
> > >       device_info->rx_desc_lim = cxgbe_desc_lim;
> > >       device_info->tx_desc_lim = cxgbe_desc_lim;
> > > +     device_info->speed_capa = ETH_SPEED_CAP_10G | ETH_SPEED_CAP_40G;
> > >  }
> > >
> >
> > Not all Chelsio NICs support _both_ 10G and 40G speed capabilities on a
> > single card.  You can query pi->link_cfg.supported to get the supported
> > speeds.  Check out print_port_info() in cxgbe_main.c to help you fill
> > in your speed capabilities for Chelsio NICs.
> >
> 
> This patch series has been long delayed, and I've been requested to merge
> it for next release if possible. Most of the feedback has been coming late
> (not for cxgbe, which is introduced in this new v8, but it did for most of
> the rest of drivers).
> 
> My proposal is simply to add in this patch series ALL possible speeds for
> that driver. Other patches can be later submitted to adjust speeds
> according to specific device model.

I agree with this.  I was asking in order to understand what your were
expecting from this API, for me it is clear.

You should just maintain the current situation i.e.
rte_eth_link.link_speed.  This is already what your patches do.

For the link speed capability (aka device_info->speed_capa), you should
add a new line "speed capability" in the doc/guides/nics/overview.rst.
Those who think it is useful will implement it in their PMD.

Regards,

-- 
Nélio Laranjeiro
6WIND

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

* Re: [PATCH v8 1/4] ethdev: Added ETH_SPEED_CAP bitmap for ports
  2016-02-14 22:17       ` [PATCH v8 1/4] ethdev: Added ETH_SPEED_CAP bitmap for ports Marc Sune
@ 2016-02-16 20:42         ` Stephen Hemminger
  0 siblings, 0 replies; 167+ messages in thread
From: Stephen Hemminger @ 2016-02-16 20:42 UTC (permalink / raw)
  To: Marc Sune; +Cc: dev

On Sun, 14 Feb 2016 23:17:36 +0100
Marc Sune <marcdevel@gmail.com> wrote:

> Added constants and bitmap to struct rte_eth_dev_info to be used by PMDs.
> 
> Signed-off-by: Marc Sune <marcdevel@gmail.com>
> ---
>  lib/librte_ether/rte_ethdev.h | 24 ++++++++++++++++++++++++
>  1 file changed, 24 insertions(+)
> 
> diff --git a/lib/librte_ether/rte_ethdev.h b/lib/librte_ether/rte_ethdev.h
> index 16da821..83ddbb7 100644
> --- a/lib/librte_ether/rte_ethdev.h
> +++ b/lib/librte_ether/rte_ethdev.h
> @@ -824,6 +824,29 @@ struct rte_eth_conf {
>  #define DEV_TX_OFFLOAD_OUTER_IPV4_CKSUM 0x00000080 /**< Used for tunneling packet. */
>  #define DEV_TX_OFFLOAD_QINQ_INSERT 0x00000100
>  
> +/**
> + * Device supported speeds
> + */
> +#define ETH_SPEED_CAP_NOT_PHY	(0)  /*< No phy media > */
> +#define ETH_SPEED_CAP_10M_HD	(1 << 0)  /*< 10 Mbps half-duplex> */
> +#define ETH_SPEED_CAP_10M_FD	(1 << 1)  /*< 10 Mbps full-duplex> */
> +#define ETH_SPEED_CAP_100M_HD	(1 << 2)  /*< 100 Mbps half-duplex> */
> +#define ETH_SPEED_CAP_100M_FD	(1 << 3)  /*< 100 Mbps full-duplex> */
> +#define ETH_SPEED_CAP_1G	(1 << 4)  /*< 1 Gbps > */
> +#define ETH_SPEED_CAP_2_5G	(1 << 5)  /*< 2.5 Gbps > */
> +#define ETH_SPEED_CAP_5G	(1 << 6)  /*< 5 Gbps > */
> +#define ETH_SPEED_CAP_10G	(1 << 7)  /*< 10 Mbps > */
> +#define ETH_SPEED_CAP_20G	(1 << 8)  /*< 20 Gbps > */
> +#define ETH_SPEED_CAP_25G	(1 << 9)  /*< 25 Gbps > */
> +#define ETH_SPEED_CAP_40G	(1 << 10)  /*< 40 Gbps > */
> +#define ETH_SPEED_CAP_50G	(1 << 11)  /*< 50 Gbps > */
> +#define ETH_SPEED_CAP_56G	(1 << 12)  /*< 56 Gbps > */
> +#define ETH_SPEED_CAP_100G	(1 << 13)  /*< 100 Gbps > */

Have you been following recent discussion about updates to ethtool
in Linux https://lwn.net/Articles/667794/

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

* Re: [PATCH v8 2/4] ethdev: Fill speed capability bitmaps in the PMDs
  2016-02-16 15:25             ` Nélio Laranjeiro
@ 2016-02-16 22:49               ` Marc
  0 siblings, 0 replies; 167+ messages in thread
From: Marc @ 2016-02-16 22:49 UTC (permalink / raw)
  To: Nélio Laranjeiro; +Cc: dev, Nirranjan Kirubaharan, Kumar Sanghvi

On 16 February 2016 at 16:25, Nélio Laranjeiro <nelio.laranjeiro@6wind.com>
wrote:

> Hi Marc,
>
> On Mon, Feb 15, 2016 at 06:14:42PM +0100, Marc wrote:
> > Rahul, Neilo, Jing D, et al
> >
> > On 15 February 2016 at 15:43, Rahul Lakkireddy <
> rahul.lakkireddy@chelsio.com
> > > wrote:
> >
> > > Hi Marc,
> > >
> > > On Sunday, February 02/14/16, 2016 at 23:17:37 +0100, Marc Sune wrote:
> > > > Added speed capabilities to all pmds supporting physical NICs:
> > > >
> > > > * e1000
> > > > * ixgbe
> > > > * i40
> > > > * bnx2x
> > > > * cxgbe
> > > > * mlx4
> > > > * mlx5
> > > > * nfp
> > > > * fm10k
> > > >
> > > > Signed-off-by: Marc Sune <marcdevel@gmail.com>
> > > > ---
> > > >  drivers/net/bnx2x/bnx2x_ethdev.c |  1 +
> > > >  drivers/net/cxgbe/cxgbe_ethdev.c |  1 +
> > > >  drivers/net/e1000/em_ethdev.c    |  6 ++++++
> > > >  drivers/net/e1000/igb_ethdev.c   |  6 ++++++
> > > >  drivers/net/fm10k/fm10k_ethdev.c |  4 ++++
> > > >  drivers/net/i40e/i40e_ethdev.c   |  9 +++++++++
> > > >  drivers/net/ixgbe/ixgbe_ethdev.c | 10 ++++++++++
> > > >  drivers/net/mlx4/mlx4.c          |  4 ++++
> > > >  drivers/net/mlx5/mlx5_ethdev.c   |  5 +++++
> > > >  drivers/net/nfp/nfp_net.c        |  2 ++
> > > >  10 files changed, 48 insertions(+)
> > > >
> > >
> > > [...]
> > >
> > > > diff --git a/drivers/net/cxgbe/cxgbe_ethdev.c
> > > b/drivers/net/cxgbe/cxgbe_ethdev.c
> > > > index 97ef152..203e119 100644
> > > > --- a/drivers/net/cxgbe/cxgbe_ethdev.c
> > > > +++ b/drivers/net/cxgbe/cxgbe_ethdev.c
> > > > @@ -171,6 +171,7 @@ static void cxgbe_dev_info_get(struct rte_eth_dev
> > > *eth_dev,
> > > >
> > > >       device_info->rx_desc_lim = cxgbe_desc_lim;
> > > >       device_info->tx_desc_lim = cxgbe_desc_lim;
> > > > +     device_info->speed_capa = ETH_SPEED_CAP_10G |
> ETH_SPEED_CAP_40G;
> > > >  }
> > > >
> > >
> > > Not all Chelsio NICs support _both_ 10G and 40G speed capabilities on a
> > > single card.  You can query pi->link_cfg.supported to get the supported
> > > speeds.  Check out print_port_info() in cxgbe_main.c to help you fill
> > > in your speed capabilities for Chelsio NICs.
> > >
> >
> > This patch series has been long delayed, and I've been requested to merge
> > it for next release if possible. Most of the feedback has been coming
> late
> > (not for cxgbe, which is introduced in this new v8, but it did for most
> of
> > the rest of drivers).
> >
> > My proposal is simply to add in this patch series ALL possible speeds for
> > that driver. Other patches can be later submitted to adjust speeds
> > according to specific device model.
>
> I agree with this.  I was asking in order to understand what your were
> expecting from this API, for me it is clear.
>
> You should just maintain the current situation i.e.
> rte_eth_link.link_speed.  This is already what your patches do.
>
> For the link speed capability (aka device_info->speed_capa), you should
> add a new line "speed capability" in the doc/guides/nics/overview.rst.
> Those who think it is useful will implement it in their PMD.
>

Noted for v9.

marc


>
> Regards,
>
> --
> Nélio Laranjeiro
> 6WIND
>

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

* Re: [PATCH v8 3/4] ethdev: redesign link speed config API
  2016-02-16 10:28         ` Matej Vido
@ 2016-02-16 22:55           ` Marc
  0 siblings, 0 replies; 167+ messages in thread
From: Marc @ 2016-02-16 22:55 UTC (permalink / raw)
  To: Matej Vido; +Cc: dev

Matej,

On 16 February 2016 at 11:28, Matej Vido <vido@cesnet.cz> wrote:

> Dňa 14.02.2016 o 23:17 Marc Sune napísal(a):
>
>> This patch redesigns the API to set the link speed/s configure
>> for an ethernet port. Specifically:
>>
>> - it allows to define a set of advertised speeds for
>>    auto-negociation.
>> - it allows to disable link auto-negociation (single fixed speed).
>> - default: auto-negociate all supported speeds.
>>
>> Other changes:
>>
>> * Added utility MACROs ETH_SPEED_NUM_XXX with the numeric
>>    values of all supported link speeds, in Mbps.
>> * Converted link_speed to uint64_t to accomodate 100G speeds
>>    and beyond (bug).
>> * Added autoneg flag in struct rte_eth_link to indicate if
>>    link speed was a result of auto-negociation or was fixed
>>    by configuration.
>> * Added utility function to convert numeric speeds to bitmap
>>    fields.
>> * Added rte_eth_speed_to_bm_flag() to version map.
>>
>> Signed-off-by: Marc Sune <marcdevel@gmail.com>
>> ---
>>   app/test-pipeline/init.c                  |   2 +-
>>   app/test-pmd/cmdline.c                    | 124
>> +++++++++++++++---------------
>>   app/test-pmd/config.c                     |   4 +-
>>   app/test/virtual_pmd.c                    |   4 +-
>>   drivers/net/af_packet/rte_eth_af_packet.c |   5 +-
>>   drivers/net/bnx2x/bnx2x_ethdev.c          |   8 +-
>>   drivers/net/bonding/rte_eth_bond_8023ad.c |  14 ++--
>>   drivers/net/cxgbe/base/t4_hw.c            |   8 +-
>>   drivers/net/cxgbe/cxgbe_ethdev.c          |   2 +-
>>   drivers/net/e1000/em_ethdev.c             | 116
>> ++++++++++++++--------------
>>   drivers/net/e1000/igb_ethdev.c            | 111
>> +++++++++++++-------------
>>   drivers/net/fm10k/fm10k_ethdev.c          |   8 +-
>>   drivers/net/i40e/i40e_ethdev.c            |  73 +++++++++---------
>>   drivers/net/i40e/i40e_ethdev_vf.c         |  11 +--
>>   drivers/net/ixgbe/ixgbe_ethdev.c          |  78 ++++++++-----------
>>   drivers/net/mlx4/mlx4.c                   |   6 +-
>>   drivers/net/mpipe/mpipe_tilegx.c          |   6 +-
>>   drivers/net/nfp/nfp_net.c                 |   4 +-
>>   drivers/net/null/rte_eth_null.c           |   5 +-
>>   drivers/net/pcap/rte_eth_pcap.c           |   9 ++-
>>   drivers/net/ring/rte_eth_ring.c           |   5 +-
>>   drivers/net/virtio/virtio_ethdev.c        |   2 +-
>>   drivers/net/virtio/virtio_ethdev.h        |   2 -
>>   drivers/net/vmxnet3/vmxnet3_ethdev.c      |   5 +-
>>   drivers/net/xenvirt/rte_eth_xenvirt.c     |   5 +-
>>   examples/ip_pipeline/config_parse.c       |   3 +-
>>   lib/librte_ether/rte_ethdev.c             |  49 ++++++++++++
>>   lib/librte_ether/rte_ethdev.h             | 113
>> +++++++++++++++++----------
>>   lib/librte_ether/rte_ether_version.map    |   6 ++
>>   29 files changed, 443 insertions(+), 345 deletions(-)
>>
>> [...]
>>
>
> Hi,
>
> some drivers (at least: e1000, i40e, ixgbe, mpipe, nfp, virtio, vmxnet3)
> use rte_atomic64_cmpset() to read and write link state like:
>
> static inline int
> rte_em_dev_atomic_read_link_status(struct rte_eth_dev *dev,
>                                 struct rte_eth_link *link)
> {
>         struct rte_eth_link *dst = link;
>         struct rte_eth_link *src = &(dev->data->dev_link);
>
>         if (rte_atomic64_cmpset((uint64_t *)dst, *(uint64_t *)dst,
>                                         *(uint64_t *)src) == 0)
>                 return -1;
>
>         return 0;
> }
>
> static inline int
> rte_em_dev_atomic_write_link_status(struct rte_eth_dev *dev,
>                                 struct rte_eth_link *link)
> {
>         struct rte_eth_link *dst = &(dev->data->dev_link);
>         struct rte_eth_link *src = link;
>
>         if (rte_atomic64_cmpset((uint64_t *)dst, *(uint64_t *)dst,
>                                         *(uint64_t *)src) == 0)
>                 return -1;
>
>         return 0;
> }
>
>
> When link_speed is changed to uint64_t, struct rte_eth_link exceeds 64
> bits. Shouldn't these functions be adapted in this patch series?
>
> Szedata2 PMD will also use rte_atomic64_cmpset() after patch [1].
> I can take care of this change in szedata2 PMD when patch [1] is accepted
> together with adjusting speeds in szedata2 PMD.
>

Indeed, thanks. I will take care of them in v9 (incl. szedata2).

marc


> [1] http://dpdk.org/ml/archives/dev/2016-January/032281.html
>
> Regards,
> Matej
>

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

* Re: [PATCH v8 4/4] doc: update with link changes
  2016-02-14 22:17       ` [PATCH v8 4/4] doc: update with link changes Marc Sune
@ 2016-02-18 18:14         ` Mcnamara, John
  2016-02-28 22:17           ` Marc
  0 siblings, 1 reply; 167+ messages in thread
From: Mcnamara, John @ 2016-02-18 18:14 UTC (permalink / raw)
  To: Marc Sune, dev, Lu, Wenzhuo, Zhang, Helin, Harish Patil, Chen, Jing D

Hi,

Some minor comments below in order to get a consistent set of release notes.

> -----Original Message-----
> From: dev [mailto:dev-bounces@dpdk.org] On Behalf Of Marc Sune
> Sent: Sunday, February 14, 2016 10:18 PM
> To: dev@dpdk.org; Lu, Wenzhuo <wenzhuo.lu@intel.com>; Zhang, Helin
> <helin.zhang@intel.com>; Harish Patil <harish.patil@qlogic.com>; Chen,
> Jing D <jing.d.chen@intel.com>
> Subject: [dpdk-dev] [PATCH v8 4/4] doc: update with link changes
> 
> Add new features, ABI changes and resolved issues notice for the
> refactored link patch.
> 
> Signed-off-by: Marc Sune <marcdevel@gmail.com>
> ---
>  doc/guides/rel_notes/release_2_3.rst | 102

This should be rebased and the notes added to doc/guides/rel_notes/release_16_04.rst.


> +
> +* **ethdev: define a set of advertised link speeds.**

The title and the text should be in the past tense.


See the hints/guidelines in the updated release notes:

    http://dpdk.org/browse/dpdk/tree/doc/guides/rel_notes/release_16_04.rst


> +
> +  Allowing to define a set of advertised speeds for auto-negociation,

Maybe something like: Added functionality to allow the definition of advertised speeds for ...



> +* **ethdev: add speed_cap bitmap to recover eth device link speed
> +capabilities
> +  define a set of advertised link speeds.**

The title is a little long. Just give a brief overview here and more the detail
to the text sections.

> +
> +  ``struct rte_eth_dev_info`` has now speed_cap bitmap, which allows
> + the  application to recover the supported speeds for that ethernet
> device.

It would be good to use ```` quotes on speed_cap as well for consistency.


+
> +Examples
> +~~~~~~~~
> +
> +* New API call, rte_eth_speed_to_bm_flag(), in ethdev to map numerical
> +speeds  to bitmap fields.

I don't think this should be in the "Examples" section. Maybe as a sub-item
in the "New Featrues" or in "API Changes" if it is a change.

> +
> +ABI Changes
> +-----------
> +
> +* The ethdev rte_eth_link and rte_eth_conf structures were changed to
> +  support the new link API, as well as ETH_LINK_HALF/FULL_DUPLEX.
> +
> +* The ethdev rte_eth_dev_info was changed to support device speed
> capabilities.

Better to put the struct names and variables in ```` quotes.

Thanks,

John.
- 

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

* Re: [PATCH v8 4/4] doc: update with link changes
  2016-02-18 18:14         ` Mcnamara, John
@ 2016-02-28 22:17           ` Marc
  0 siblings, 0 replies; 167+ messages in thread
From: Marc @ 2016-02-28 22:17 UTC (permalink / raw)
  To: Mcnamara, John; +Cc: dev

On 18 February 2016 at 19:14, Mcnamara, John <john.mcnamara@intel.com>
wrote:

> Hi,
>
> Some minor comments below in order to get a consistent set of release
> notes.
>
> > -----Original Message-----
> > From: dev [mailto:dev-bounces@dpdk.org] On Behalf Of Marc Sune
> > Sent: Sunday, February 14, 2016 10:18 PM
> > To: dev@dpdk.org; Lu, Wenzhuo <wenzhuo.lu@intel.com>; Zhang, Helin
> > <helin.zhang@intel.com>; Harish Patil <harish.patil@qlogic.com>; Chen,
> > Jing D <jing.d.chen@intel.com>
> > Subject: [dpdk-dev] [PATCH v8 4/4] doc: update with link changes
> >
> > Add new features, ABI changes and resolved issues notice for the
> > refactored link patch.
> >
> > Signed-off-by: Marc Sune <marcdevel@gmail.com>
> > ---
> >  doc/guides/rel_notes/release_2_3.rst | 102
>
> This should be rebased and the notes added to
> doc/guides/rel_notes/release_16_04.rst.
>
>
> > +
> > +* **ethdev: define a set of advertised link speeds.**
>
> The title and the text should be in the past tense.
>
>
> See the hints/guidelines in the updated release notes:
>
>
> http://dpdk.org/browse/dpdk/tree/doc/guides/rel_notes/release_16_04.rst
>
>
> > +
> > +  Allowing to define a set of advertised speeds for auto-negociation,
>
> Maybe something like: Added functionality to allow the definition of
> advertised speeds for ...
>
>
>
> > +* **ethdev: add speed_cap bitmap to recover eth device link speed
> > +capabilities
> > +  define a set of advertised link speeds.**
>
> The title is a little long. Just give a brief overview here and more the
> detail
> to the text sections.
>
> > +
> > +  ``struct rte_eth_dev_info`` has now speed_cap bitmap, which allows
> > + the  application to recover the supported speeds for that ethernet
> > device.
>
> It would be good to use ```` quotes on speed_cap as well for consistency.
>
>
> +
> > +Examples
> > +~~~~~~~~
> > +
> > +* New API call, rte_eth_speed_to_bm_flag(), in ethdev to map numerical
> > +speeds  to bitmap fields.
>
> I don't think this should be in the "Examples" section. Maybe as a sub-item
> in the "New Featrues" or in "API Changes" if it is a change.
>
> > +
> > +ABI Changes
> > +-----------
> > +
> > +* The ethdev rte_eth_link and rte_eth_conf structures were changed to
> > +  support the new link API, as well as ETH_LINK_HALF/FULL_DUPLEX.
> > +
> > +* The ethdev rte_eth_dev_info was changed to support device speed
> > capabilities.
>
> Better to put the struct names and variables in ```` quotes.
>
> Thanks,
>

Noted and fixed in v9.

Thanks
marc


>
> John.
> -
>
>
>
>

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

* [PATCH v9 0/4] ethdev: add speed capabilities and refactor link API
  2016-02-14 22:17     ` [PATCH v8 0/4] ethdev: add speed capabilities and refactor link API Marc Sune
                         ` (3 preceding siblings ...)
  2016-02-14 22:17       ` [PATCH v8 4/4] doc: update with link changes Marc Sune
@ 2016-03-01  0:45       ` Marc Sune
  2016-03-01  0:45         ` [PATCH v9 1/4] ethdev: Added ETH_SPEED_CAP bitmap for ports Marc Sune
                           ` (5 more replies)
  4 siblings, 6 replies; 167+ messages in thread
From: Marc Sune @ 2016-03-01  0:45 UTC (permalink / raw)
  To: dev, Lu, Wenzhuo, Zhang, Helin, Harish Patil, Chen, Jing D

The current rte_eth_dev_info abstraction does not provide any mechanism to
get the supported speed(s) of an ethdev.

For some drivers (e.g. ixgbe), an educated guess could be done based on the
driver's name (driver_name in rte_eth_dev_info), see:

http://dpdk.org/ml/archives/dev/2013-August/000412.html

However, i) doing string comparisons is annoying, and can silently
break existing applications if PMDs change their names ii) it does not
provide all the supported capabilities of the ethdev iii) for some drivers it
is impossible determine correctly the (max) speed by the application
(e.g. in i40, distinguish between XL710 and X710).

In addition, the link APIs do not allow to define a set of advertised link
speeds for autonegociation.

This series of patches adds the following capabilities:

* speed_capa bitmap in rte_eth_dev_info, which is filled by the PMDs
  according to the physical device capabilities.
* refactors link API in ethdev to allow the definition of the advertised
  link speeds, fix speed (no auto-negociation) or advertise all supported
  speeds (default).

WARNING: this patch series, specifically 3/4, is NOT tested for most of the
PMDs, due to the lack of hardware. Only generic EM is tested (VM). Reviewing
and testing required by PMD maintainers.

* * * * *

v2: rebase, converted speed_capa into 32 bits bitmap, fixed alignment
    (checkpatch).

v3: rebase to v2.1. unified ETH_LINK_SPEED and ETH_SPEED_CAP into ETH_SPEED.
    Converted field speed in struct rte_eth_conf to speed, to allow a bitmap
    for defining the announced speeds, as suggested M. Brorup. Fixed spelling
    issues.

v4: fixed errata in the documentation of field speeds of rte_eth_conf, and
    commit 1/2 message. rebased to v2.1.0. v3 was incorrectly based on
    ~2.1.0-rc1.

v5: revert to v2 speed capabilities patch. Fixed MLX4 speed capabilities
    (thanks N. Laranjeiro). Refactored link speed API to allow setting
    advertised speeds (3/4). Added NO_AUTONEG option to explicitely disable
    auto-negociation. Updated 2.2 rel. notes (4/4). Rebased to current HEAD.

v6: Move link_duplex to be part of bitfield. Fixed i40 autoneg flag link
    update code. Added rte_eth_speed_to_bm_flag() to .map file. Fixed other
    spelling issues. Rebased to current HEAD.

v7: Rebased to current HEAD. Moved documentation to v2.3. Still needs testing
    from PMD maintainers.

v8: Rebased to current HEAD. Modified em driver impl. to not touch base files.
    Merged patch 5 into 3 (map file). Changed numeric speed to a 64 bit value.
    Filled-in speed capabilities for drivers bnx2x, cxgbe, mlx5 and nfp in
    addition to the ones of previous patch sets.

v9: rebased to current HEAD. Reverted numeric speed to 32 bit in struct
    rte_eth_link (no atomic link get > 64bit). Fixed mlx5 driver compilation
    and link speeds. Moved documentation to release_16_04.rst and fixed several
    issues. Upgrade NIC notes with speed capabilities.

Marc Sune (4):
  ethdev: Added ETH_SPEED_CAP bitmap for ports
  ethdev: Fill speed capability bitmaps in the PMDs
  ethdev: redesign link speed config API
  doc: update with link changes

 app/test-pipeline/init.c                  |   2 +-
 app/test-pmd/cmdline.c                    | 124 +++++++++++++++---------------
 app/test-pmd/config.c                     |   4 +-
 app/test/virtual_pmd.c                    |   4 +-
 doc/guides/nics/overview.rst              |   1 +
 doc/guides/rel_notes/release_16_04.rst    |  27 +++++++
 drivers/net/af_packet/rte_eth_af_packet.c |   5 +-
 drivers/net/bnx2x/bnx2x_ethdev.c          |   7 +-
 drivers/net/bonding/rte_eth_bond_8023ad.c |  14 ++--
 drivers/net/cxgbe/base/t4_hw.c            |   8 +-
 drivers/net/cxgbe/cxgbe_ethdev.c          |   1 +
 drivers/net/e1000/em_ethdev.c             | 112 ++++++++++++++-------------
 drivers/net/e1000/igb_ethdev.c            | 107 +++++++++++++++-----------
 drivers/net/fm10k/fm10k_ethdev.c          |   6 +-
 drivers/net/i40e/i40e_ethdev.c            |  78 +++++++++++--------
 drivers/net/i40e/i40e_ethdev_vf.c         |  11 +--
 drivers/net/ixgbe/ixgbe_ethdev.c          |  80 +++++++++----------
 drivers/net/mlx4/mlx4.c                   |   6 ++
 drivers/net/mlx5/mlx5_ethdev.c            |   7 ++
 drivers/net/mpipe/mpipe_tilegx.c          |   6 +-
 drivers/net/nfp/nfp_net.c                 |   4 +-
 drivers/net/null/rte_eth_null.c           |   5 +-
 drivers/net/pcap/rte_eth_pcap.c           |   9 ++-
 drivers/net/ring/rte_eth_ring.c           |   5 +-
 drivers/net/virtio/virtio_ethdev.c        |   2 +-
 drivers/net/virtio/virtio_ethdev.h        |   2 -
 drivers/net/vmxnet3/vmxnet3_ethdev.c      |   5 +-
 drivers/net/xenvirt/rte_eth_xenvirt.c     |   5 +-
 examples/ip_pipeline/config_parse.c       |   3 +-
 lib/librte_ether/rte_ethdev.c             |  49 ++++++++++++
 lib/librte_ether/rte_ethdev.h             |  97 ++++++++++++++++++-----
 lib/librte_ether/rte_ether_version.map    |   6 ++
 32 files changed, 501 insertions(+), 301 deletions(-)

-- 
2.1.4

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

* [PATCH v9 1/4] ethdev: Added ETH_SPEED_CAP bitmap for ports
  2016-03-01  0:45       ` [PATCH v9 0/4] ethdev: add speed capabilities and refactor link API Marc Sune
@ 2016-03-01  0:45         ` Marc Sune
  2016-03-01  0:45         ` [PATCH v9 2/4] ethdev: Fill speed capability bitmaps in the PMDs Marc Sune
                           ` (4 subsequent siblings)
  5 siblings, 0 replies; 167+ messages in thread
From: Marc Sune @ 2016-03-01  0:45 UTC (permalink / raw)
  To: dev, Lu, Wenzhuo, Zhang, Helin, Harish Patil, Chen, Jing D

Added constants and bitmap to struct rte_eth_dev_info to be used by PMDs.

Signed-off-by: Marc Sune <marcdevel@gmail.com>
---
 lib/librte_ether/rte_ethdev.h | 24 ++++++++++++++++++++++++
 1 file changed, 24 insertions(+)

diff --git a/lib/librte_ether/rte_ethdev.h b/lib/librte_ether/rte_ethdev.h
index 16da821..83ddbb7 100644
--- a/lib/librte_ether/rte_ethdev.h
+++ b/lib/librte_ether/rte_ethdev.h
@@ -824,6 +824,29 @@ struct rte_eth_conf {
 #define DEV_TX_OFFLOAD_OUTER_IPV4_CKSUM 0x00000080 /**< Used for tunneling packet. */
 #define DEV_TX_OFFLOAD_QINQ_INSERT 0x00000100
 
+/**
+ * Device supported speeds
+ */
+#define ETH_SPEED_CAP_NOT_PHY	(0)  /*< No phy media > */
+#define ETH_SPEED_CAP_10M_HD	(1 << 0)  /*< 10 Mbps half-duplex> */
+#define ETH_SPEED_CAP_10M_FD	(1 << 1)  /*< 10 Mbps full-duplex> */
+#define ETH_SPEED_CAP_100M_HD	(1 << 2)  /*< 100 Mbps half-duplex> */
+#define ETH_SPEED_CAP_100M_FD	(1 << 3)  /*< 100 Mbps full-duplex> */
+#define ETH_SPEED_CAP_1G	(1 << 4)  /*< 1 Gbps > */
+#define ETH_SPEED_CAP_2_5G	(1 << 5)  /*< 2.5 Gbps > */
+#define ETH_SPEED_CAP_5G	(1 << 6)  /*< 5 Gbps > */
+#define ETH_SPEED_CAP_10G	(1 << 7)  /*< 10 Mbps > */
+#define ETH_SPEED_CAP_20G	(1 << 8)  /*< 20 Gbps > */
+#define ETH_SPEED_CAP_25G	(1 << 9)  /*< 25 Gbps > */
+#define ETH_SPEED_CAP_40G	(1 << 10)  /*< 40 Gbps > */
+#define ETH_SPEED_CAP_50G	(1 << 11)  /*< 50 Gbps > */
+#define ETH_SPEED_CAP_56G	(1 << 12)  /*< 56 Gbps > */
+#define ETH_SPEED_CAP_100G	(1 << 13)  /*< 100 Gbps > */
+
+
+/**
+ * Ethernet device information
+ */
 struct rte_eth_dev_info {
 	struct rte_pci_device *pci_dev; /**< Device PCI information. */
 	const char *driver_name; /**< Device Driver name. */
@@ -852,6 +875,7 @@ struct rte_eth_dev_info {
 	uint16_t vmdq_pool_base;  /**< First ID of VMDQ pools. */
 	struct rte_eth_desc_lim rx_desc_lim;  /**< RX descriptors limits */
 	struct rte_eth_desc_lim tx_desc_lim;  /**< TX descriptors limits */
+	uint32_t speed_capa;  /**< Supported speeds bitmap (ETH_SPEED_CAP_). */
 };
 
 /**
-- 
2.1.4

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

* [PATCH v9 2/4] ethdev: Fill speed capability bitmaps in the PMDs
  2016-03-01  0:45       ` [PATCH v9 0/4] ethdev: add speed capabilities and refactor link API Marc Sune
  2016-03-01  0:45         ` [PATCH v9 1/4] ethdev: Added ETH_SPEED_CAP bitmap for ports Marc Sune
@ 2016-03-01  0:45         ` Marc Sune
  2016-03-01  0:45         ` [PATCH v9 3/4] ethdev: redesign link speed config API Marc Sune
                           ` (3 subsequent siblings)
  5 siblings, 0 replies; 167+ messages in thread
From: Marc Sune @ 2016-03-01  0:45 UTC (permalink / raw)
  To: dev, Lu, Wenzhuo, Zhang, Helin, Harish Patil, Chen, Jing D

Added speed capabilities to all pmds supporting physical NICs:

* e1000
* ixgbe
* i40
* bnx2x
* cxgbe
* mlx4
* mlx5
* nfp
* fm10k

Signed-off-by: Marc Sune <marcdevel@gmail.com>
---
 drivers/net/bnx2x/bnx2x_ethdev.c |  1 +
 drivers/net/cxgbe/cxgbe_ethdev.c |  1 +
 drivers/net/e1000/em_ethdev.c    |  6 ++++++
 drivers/net/e1000/igb_ethdev.c   |  6 ++++++
 drivers/net/fm10k/fm10k_ethdev.c |  4 ++++
 drivers/net/i40e/i40e_ethdev.c   |  9 +++++++++
 drivers/net/ixgbe/ixgbe_ethdev.c | 10 ++++++++++
 drivers/net/mlx4/mlx4.c          |  4 ++++
 drivers/net/mlx5/mlx5_ethdev.c   |  7 +++++++
 drivers/net/nfp/nfp_net.c        |  2 ++
 10 files changed, 50 insertions(+)

diff --git a/drivers/net/bnx2x/bnx2x_ethdev.c b/drivers/net/bnx2x/bnx2x_ethdev.c
index 69df02e..b547ac3 100644
--- a/drivers/net/bnx2x/bnx2x_ethdev.c
+++ b/drivers/net/bnx2x/bnx2x_ethdev.c
@@ -347,6 +347,7 @@ bnx2x_dev_infos_get(struct rte_eth_dev *dev, __rte_unused struct rte_eth_dev_inf
 	dev_info->min_rx_bufsize = BNX2X_MIN_RX_BUF_SIZE;
 	dev_info->max_rx_pktlen  = BNX2X_MAX_RX_PKT_LEN;
 	dev_info->max_mac_addrs  = BNX2X_MAX_MAC_ADDRS;
+	dev_info->speed_capa = ETH_SPEED_CAP_10G | ETH_SPEED_CAP_20G;
 }
 
 static void
diff --git a/drivers/net/cxgbe/cxgbe_ethdev.c b/drivers/net/cxgbe/cxgbe_ethdev.c
index 97ef152..203e119 100644
--- a/drivers/net/cxgbe/cxgbe_ethdev.c
+++ b/drivers/net/cxgbe/cxgbe_ethdev.c
@@ -171,6 +171,7 @@ static void cxgbe_dev_info_get(struct rte_eth_dev *eth_dev,
 
 	device_info->rx_desc_lim = cxgbe_desc_lim;
 	device_info->tx_desc_lim = cxgbe_desc_lim;
+	device_info->speed_capa = ETH_SPEED_CAP_10G | ETH_SPEED_CAP_40G;
 }
 
 static void cxgbe_dev_promiscuous_enable(struct rte_eth_dev *eth_dev)
diff --git a/drivers/net/e1000/em_ethdev.c b/drivers/net/e1000/em_ethdev.c
index 4a843fe..e40dc37 100644
--- a/drivers/net/e1000/em_ethdev.c
+++ b/drivers/net/e1000/em_ethdev.c
@@ -1023,6 +1023,12 @@ eth_em_infos_get(struct rte_eth_dev *dev, struct rte_eth_dev_info *dev_info)
 		.nb_min = E1000_MIN_RING_DESC,
 		.nb_align = EM_TXD_ALIGN,
 	};
+
+	dev_info->speed_capa = ETH_SPEED_CAP_10M_HD |
+					ETH_SPEED_CAP_10M_FD |
+					ETH_SPEED_CAP_100M_HD |
+					ETH_SPEED_CAP_100M_FD |
+					ETH_SPEED_CAP_1G;
 }
 
 /* return 0 means link status changed, -1 means not changed */
diff --git a/drivers/net/e1000/igb_ethdev.c b/drivers/net/e1000/igb_ethdev.c
index 4ed5e95..7eac8ea 100644
--- a/drivers/net/e1000/igb_ethdev.c
+++ b/drivers/net/e1000/igb_ethdev.c
@@ -1908,6 +1908,12 @@ eth_igb_infos_get(struct rte_eth_dev *dev, struct rte_eth_dev_info *dev_info)
 
 	dev_info->rx_desc_lim = rx_desc_lim;
 	dev_info->tx_desc_lim = tx_desc_lim;
+
+	dev_info->speed_capa = ETH_SPEED_CAP_10M_HD |
+					ETH_SPEED_CAP_10M_FD |
+					ETH_SPEED_CAP_100M_HD |
+					ETH_SPEED_CAP_100M_FD |
+					ETH_SPEED_CAP_1G;
 }
 
 static void
diff --git a/drivers/net/fm10k/fm10k_ethdev.c b/drivers/net/fm10k/fm10k_ethdev.c
index 421266b..2e6ec60 100644
--- a/drivers/net/fm10k/fm10k_ethdev.c
+++ b/drivers/net/fm10k/fm10k_ethdev.c
@@ -1333,6 +1333,10 @@ fm10k_dev_infos_get(struct rte_eth_dev *dev,
 		.nb_min = FM10K_MIN_TX_DESC,
 		.nb_align = FM10K_MULT_TX_DESC,
 	};
+
+	dev_info->speed_capa = ETH_SPEED_CAP_1G | ETH_SPEED_CAP_2_5G |
+					ETH_SPEED_CAP_10G | ETH_SPEED_CAP_25G |
+					ETH_SPEED_CAP_40G | ETH_SPEED_CAP_100G;
 }
 
 static int
diff --git a/drivers/net/i40e/i40e_ethdev.c b/drivers/net/i40e/i40e_ethdev.c
index ef24122..78a0cbd 100644
--- a/drivers/net/i40e/i40e_ethdev.c
+++ b/drivers/net/i40e/i40e_ethdev.c
@@ -2233,6 +2233,7 @@ static void
 i40e_dev_info_get(struct rte_eth_dev *dev, struct rte_eth_dev_info *dev_info)
 {
 	struct i40e_pf *pf = I40E_DEV_PRIVATE_TO_PF(dev->data->dev_private);
+	struct i40e_hw *hw = I40E_DEV_PRIVATE_TO_HW(dev->data->dev_private);
 	struct i40e_vsi *vsi = pf->main_vsi;
 
 	dev_info->max_rx_queues = vsi->nb_qps;
@@ -2304,6 +2305,14 @@ i40e_dev_info_get(struct rte_eth_dev *dev, struct rte_eth_dev_info *dev_info)
 		dev_info->max_rx_queues += dev_info->vmdq_queue_num;
 		dev_info->max_tx_queues += dev_info->vmdq_queue_num;
 	}
+
+	if (i40e_is_40G_device(hw->device_id))
+		/* For XL710 */
+		dev_info->speed_capa = ETH_SPEED_CAP_1G | ETH_SPEED_CAP_10G;
+	else
+		/* For X710 */
+		dev_info->speed_capa = ETH_SPEED_CAP_10G | ETH_SPEED_CAP_40G;
+
 }
 
 static int
diff --git a/drivers/net/ixgbe/ixgbe_ethdev.c b/drivers/net/ixgbe/ixgbe_ethdev.c
index 3e6fe86..7e29c18 100644
--- a/drivers/net/ixgbe/ixgbe_ethdev.c
+++ b/drivers/net/ixgbe/ixgbe_ethdev.c
@@ -2827,6 +2827,16 @@ ixgbe_dev_info_get(struct rte_eth_dev *dev, struct rte_eth_dev_info *dev_info)
 	dev_info->hash_key_size = IXGBE_HKEY_MAX_INDEX * sizeof(uint32_t);
 	dev_info->reta_size = ixgbe_reta_size_get(hw->mac.type);
 	dev_info->flow_type_rss_offloads = IXGBE_RSS_OFFLOAD_ALL;
+
+	dev_info->speed_capa = ETH_SPEED_CAP_1G | ETH_SPEED_CAP_10G;
+
+	if (hw->mac.type == ixgbe_mac_X540 ||
+	    hw->mac.type == ixgbe_mac_X540_vf ||
+	    hw->mac.type == ixgbe_mac_X550 ||
+	    hw->mac.type == ixgbe_mac_X550_vf)
+
+		dev_info->speed_capa |= ETH_SPEED_CAP_100M_FD /*|
+					ETH_SPEED_CAP_100M_HD*/;
 }
 
 static void
diff --git a/drivers/net/mlx4/mlx4.c b/drivers/net/mlx4/mlx4.c
index ee00151..c5688a7 100644
--- a/drivers/net/mlx4/mlx4.c
+++ b/drivers/net/mlx4/mlx4.c
@@ -4264,6 +4264,10 @@ mlx4_dev_infos_get(struct rte_eth_dev *dev, struct rte_eth_dev_info *info)
 		 0);
 	if (priv_get_ifname(priv, &ifname) == 0)
 		info->if_index = if_nametoindex(ifname);
+
+	info->speed_capa = ETH_SPEED_CAP_10G |ETH_SPEED_CAP_40G |
+					ETH_SPEED_CAP_56G;
+
 	priv_unlock(priv);
 }
 
diff --git a/drivers/net/mlx5/mlx5_ethdev.c b/drivers/net/mlx5/mlx5_ethdev.c
index 1159fa3..9c997c5 100644
--- a/drivers/net/mlx5/mlx5_ethdev.c
+++ b/drivers/net/mlx5/mlx5_ethdev.c
@@ -523,6 +523,13 @@ mlx5_dev_infos_get(struct rte_eth_dev *dev, struct rte_eth_dev_info *info)
 	 * size if it is not fixed.
 	 * The API should be updated to solve this problem. */
 	info->reta_size = priv->ind_table_max_size;
+
+	info->speed_capa = ETH_SPEED_CAP_1G | ETH_SPEED_CAP_10G |
+					ETH_SPEED_CAP_25G |
+					ETH_SPEED_CAP_40G |
+					ETH_SPEED_CAP_50G |
+					ETH_SPEED_CAP_100G;
+
 	priv_unlock(priv);
 }
 
diff --git a/drivers/net/nfp/nfp_net.c b/drivers/net/nfp/nfp_net.c
index fd4dd39..98a957a 100644
--- a/drivers/net/nfp/nfp_net.c
+++ b/drivers/net/nfp/nfp_net.c
@@ -1071,6 +1071,8 @@ nfp_net_infos_get(struct rte_eth_dev *dev, struct rte_eth_dev_info *dev_info)
 
 	dev_info->reta_size = NFP_NET_CFG_RSS_ITBL_SZ;
 	dev_info->hash_key_size = NFP_NET_CFG_RSS_KEY_SZ;
+
+	dev_info->speed_capa = ETH_SPEED_CAP_50G | ETH_SPEED_CAP_100G;
 }
 
 static uint32_t
-- 
2.1.4

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

* [PATCH v9 3/4] ethdev: redesign link speed config API
  2016-03-01  0:45       ` [PATCH v9 0/4] ethdev: add speed capabilities and refactor link API Marc Sune
  2016-03-01  0:45         ` [PATCH v9 1/4] ethdev: Added ETH_SPEED_CAP bitmap for ports Marc Sune
  2016-03-01  0:45         ` [PATCH v9 2/4] ethdev: Fill speed capability bitmaps in the PMDs Marc Sune
@ 2016-03-01  0:45         ` Marc Sune
  2016-03-09  8:45           ` Nélio Laranjeiro
  2016-03-01  0:45         ` [PATCH v9 4/4] doc: update with link changes Marc Sune
                           ` (2 subsequent siblings)
  5 siblings, 1 reply; 167+ messages in thread
From: Marc Sune @ 2016-03-01  0:45 UTC (permalink / raw)
  To: dev, Lu, Wenzhuo, Zhang, Helin, Harish Patil, Chen, Jing D

This patch redesigns the API to set the link speed/s configure
for an ethernet port. Specifically:

- it allows to define a set of advertised speeds for
  auto-negociation.
- it allows to disable link auto-negociation (single fixed speed).
- default: auto-negociate all supported speeds.

Other changes:

* Added utility MACROs ETH_SPEED_NUM_XXX with the numeric
  values of all supported link speeds, in Mbps.
* Converted link_speed to uint32_t to accomodate 100G speeds
  and beyond (bug).
* Added autoneg flag in struct rte_eth_link to indicate if
  link speed was a result of auto-negociation or was fixed
  by configuration.
* Added utility function to convert numeric speeds to bitmap
  fields.
* Added rte_eth_speed_to_bm_flag() to version map.

Signed-off-by: Marc Sune <marcdevel@gmail.com>
---
 app/test-pipeline/init.c                  |   2 +-
 app/test-pmd/cmdline.c                    | 124 +++++++++++++++---------------
 app/test-pmd/config.c                     |   4 +-
 app/test/virtual_pmd.c                    |   4 +-
 drivers/net/af_packet/rte_eth_af_packet.c |   5 +-
 drivers/net/bnx2x/bnx2x_ethdev.c          |   8 +-
 drivers/net/bonding/rte_eth_bond_8023ad.c |  14 ++--
 drivers/net/cxgbe/base/t4_hw.c            |   8 +-
 drivers/net/cxgbe/cxgbe_ethdev.c          |   2 +-
 drivers/net/e1000/em_ethdev.c             | 116 ++++++++++++++--------------
 drivers/net/e1000/igb_ethdev.c            | 111 +++++++++++++-------------
 drivers/net/fm10k/fm10k_ethdev.c          |   8 +-
 drivers/net/i40e/i40e_ethdev.c            |  73 +++++++++---------
 drivers/net/i40e/i40e_ethdev_vf.c         |  11 +--
 drivers/net/ixgbe/ixgbe_ethdev.c          |  78 ++++++++-----------
 drivers/net/mlx4/mlx4.c                   |   6 +-
 drivers/net/mlx5/mlx5_ethdev.c            |  10 +--
 drivers/net/mpipe/mpipe_tilegx.c          |   6 +-
 drivers/net/nfp/nfp_net.c                 |   4 +-
 drivers/net/null/rte_eth_null.c           |   5 +-
 drivers/net/pcap/rte_eth_pcap.c           |   9 ++-
 drivers/net/ring/rte_eth_ring.c           |   5 +-
 drivers/net/virtio/virtio_ethdev.c        |   2 +-
 drivers/net/virtio/virtio_ethdev.h        |   2 -
 drivers/net/vmxnet3/vmxnet3_ethdev.c      |   5 +-
 drivers/net/xenvirt/rte_eth_xenvirt.c     |   5 +-
 examples/ip_pipeline/config_parse.c       |   3 +-
 lib/librte_ether/rte_ethdev.c             |  49 ++++++++++++
 lib/librte_ether/rte_ethdev.h             | 113 +++++++++++++++++----------
 lib/librte_ether/rte_ether_version.map    |   6 ++
 30 files changed, 448 insertions(+), 350 deletions(-)

diff --git a/app/test-pipeline/init.c b/app/test-pipeline/init.c
index db2196b..6a69fe2 100644
--- a/app/test-pipeline/init.c
+++ b/app/test-pipeline/init.c
@@ -200,7 +200,7 @@ app_ports_check_link(void)
 		port = (uint8_t) app.ports[i];
 		memset(&link, 0, sizeof(link));
 		rte_eth_link_get_nowait(port, &link);
-		RTE_LOG(INFO, USER1, "Port %u (%u Gbps) %s\n",
+		RTE_LOG(INFO, USER1, "Port %u (%d Gbps) %s\n",
 			port,
 			link.link_speed / 1000,
 			link.link_status ? "UP" : "DOWN");
diff --git a/app/test-pmd/cmdline.c b/app/test-pmd/cmdline.c
index 52e9f5f..57ad25f 100644
--- a/app/test-pmd/cmdline.c
+++ b/app/test-pmd/cmdline.c
@@ -956,14 +956,65 @@ struct cmd_config_speed_all {
 	cmdline_fixed_string_t value2;
 };
 
+static int
+parse_and_check_speed_duplex(char *value1, char *value2, uint32_t *link_speed)
+{
+
+	int duplex;
+
+	if (!strcmp(value2, "half")) {
+		duplex = 0;
+	} else if (!strcmp(value2, "full")) {
+		duplex = 1;
+	} else if (!strcmp(value2, "auto")) {
+		duplex = 1;
+	} else {
+		printf("Unknown parameter\n");
+		return -1;
+	}
+
+	if (!strcmp(value1, "10")) {
+		*link_speed = (duplex) ? ETH_LINK_SPEED_10M :
+							ETH_LINK_SPEED_10M_HD;
+	} else if (!strcmp(value1, "100")) {
+		*link_speed = (duplex) ? ETH_LINK_SPEED_100M :
+							ETH_LINK_SPEED_100M_HD;
+	} else if (!strcmp(value1, "1000")) {
+		if (!duplex)
+			goto invalid_speed_param;
+		*link_speed = ETH_LINK_SPEED_1G;
+	} else if (!strcmp(value1, "10000")) {
+		if (!duplex)
+			goto invalid_speed_param;
+		*link_speed = ETH_LINK_SPEED_10G;
+	} else if (!strcmp(value1, "40000")) {
+		if (!duplex)
+			goto invalid_speed_param;
+		*link_speed = ETH_LINK_SPEED_40G;
+	} else if (!strcmp(value1, "auto")) {
+		if (!duplex)
+			goto invalid_speed_param;
+		*link_speed = ETH_LINK_SPEED_AUTONEG;
+	} else {
+		printf("Unknown parameter\n");
+		return -1;
+	}
+
+	return 0;
+
+invalid_speed_param:
+
+	printf("Invalid speed parameter\n");
+	return -1;
+}
+
 static void
 cmd_config_speed_all_parsed(void *parsed_result,
 			__attribute__((unused)) struct cmdline *cl,
 			__attribute__((unused)) void *data)
 {
 	struct cmd_config_speed_all *res = parsed_result;
-	uint16_t link_speed = ETH_LINK_SPEED_AUTONEG;
-	uint16_t link_duplex = 0;
+	uint32_t link_speed;
 	portid_t pid;
 
 	if (!all_ports_stopped()) {
@@ -971,40 +1022,18 @@ cmd_config_speed_all_parsed(void *parsed_result,
 		return;
 	}
 
-	if (!strcmp(res->value1, "10"))
-		link_speed = ETH_LINK_SPEED_10;
-	else if (!strcmp(res->value1, "100"))
-		link_speed = ETH_LINK_SPEED_100;
-	else if (!strcmp(res->value1, "1000"))
-		link_speed = ETH_LINK_SPEED_1000;
-	else if (!strcmp(res->value1, "10000"))
-		link_speed = ETH_LINK_SPEED_10G;
-	else if (!strcmp(res->value1, "40000"))
-		link_speed = ETH_LINK_SPEED_40G;
-	else if (!strcmp(res->value1, "auto"))
-		link_speed = ETH_LINK_SPEED_AUTONEG;
-	else {
-		printf("Unknown parameter\n");
+	if (parse_and_check_speed_duplex(res->value1,
+						res->value2,
+						&link_speed) < 0)
 		return;
-	}
-
-	if (!strcmp(res->value2, "half"))
-		link_duplex = ETH_LINK_HALF_DUPLEX;
-	else if (!strcmp(res->value2, "full"))
-		link_duplex = ETH_LINK_FULL_DUPLEX;
-	else if (!strcmp(res->value2, "auto"))
-		link_duplex = ETH_LINK_AUTONEG_DUPLEX;
-	else {
-		printf("Unknown parameter\n");
-		return;
-	}
 
 	FOREACH_PORT(pid, ports) {
-		ports[pid].dev_conf.link_speed = link_speed;
-		ports[pid].dev_conf.link_duplex = link_duplex;
+		ports[pid].dev_conf.link_speeds = link_speed;
 	}
 
 	cmd_reconfig_device_queue(RTE_PORT_ALL, 1, 1);
+
+	return;
 }
 
 cmdline_parse_token_string_t cmd_config_speed_all_port =
@@ -1059,8 +1088,7 @@ cmd_config_speed_specific_parsed(void *parsed_result,
 				__attribute__((unused)) void *data)
 {
 	struct cmd_config_speed_specific *res = parsed_result;
-	uint16_t link_speed = ETH_LINK_SPEED_AUTONEG;
-	uint16_t link_duplex = 0;
+	uint32_t link_speed;
 
 	if (!all_ports_stopped()) {
 		printf("Please stop all ports first\n");
@@ -1070,36 +1098,12 @@ cmd_config_speed_specific_parsed(void *parsed_result,
 	if (port_id_is_invalid(res->id, ENABLED_WARN))
 		return;
 
-	if (!strcmp(res->value1, "10"))
-		link_speed = ETH_LINK_SPEED_10;
-	else if (!strcmp(res->value1, "100"))
-		link_speed = ETH_LINK_SPEED_100;
-	else if (!strcmp(res->value1, "1000"))
-		link_speed = ETH_LINK_SPEED_1000;
-	else if (!strcmp(res->value1, "10000"))
-		link_speed = ETH_LINK_SPEED_10000;
-	else if (!strcmp(res->value1, "40000"))
-		link_speed = ETH_LINK_SPEED_40G;
-	else if (!strcmp(res->value1, "auto"))
-		link_speed = ETH_LINK_SPEED_AUTONEG;
-	else {
-		printf("Unknown parameter\n");
+	if (parse_and_check_speed_duplex(res->value1,
+						res->value2,
+						&link_speed) < 0)
 		return;
-	}
-
-	if (!strcmp(res->value2, "half"))
-		link_duplex = ETH_LINK_HALF_DUPLEX;
-	else if (!strcmp(res->value2, "full"))
-		link_duplex = ETH_LINK_FULL_DUPLEX;
-	else if (!strcmp(res->value2, "auto"))
-		link_duplex = ETH_LINK_AUTONEG_DUPLEX;
-	else {
-		printf("Unknown parameter\n");
-		return;
-	}
 
-	ports[res->id].dev_conf.link_speed = link_speed;
-	ports[res->id].dev_conf.link_duplex = link_duplex;
+	ports[res->id].dev_conf.link_speeds = link_speed;
 
 	cmd_reconfig_device_queue(RTE_PORT_ALL, 1, 1);
 }
diff --git a/app/test-pmd/config.c b/app/test-pmd/config.c
index 0062484..d43f64f 100644
--- a/app/test-pmd/config.c
+++ b/app/test-pmd/config.c
@@ -2241,7 +2241,7 @@ set_queue_rate_limit(portid_t port_id, uint16_t queue_idx, uint16_t rate)
 		return 1;
 	rte_eth_link_get_nowait(port_id, &link);
 	if (rate > link.link_speed) {
-		printf("Invalid rate value:%u bigger than link speed: %u\n",
+		printf("Invalid rate value:%u bigger than link speed: %d\n",
 			rate, link.link_speed);
 		return 1;
 	}
@@ -2266,7 +2266,7 @@ set_vf_rate_limit(portid_t port_id, uint16_t vf, uint16_t rate, uint64_t q_msk)
 		return 1;
 	rte_eth_link_get_nowait(port_id, &link);
 	if (rate > link.link_speed) {
-		printf("Invalid rate value:%u bigger than link speed: %u\n",
+		printf("Invalid rate value:%u bigger than link speed: %d\n",
 			rate, link.link_speed);
 		return 1;
 	}
diff --git a/app/test/virtual_pmd.c b/app/test/virtual_pmd.c
index a538c8a..3c4040b 100644
--- a/app/test/virtual_pmd.c
+++ b/app/test/virtual_pmd.c
@@ -603,8 +603,8 @@ virtual_ethdev_create(const char *name, struct ether_addr *mac_addr,
 
 	TAILQ_INIT(&(eth_dev->link_intr_cbs));
 
-	eth_dev->data->dev_link.link_status = 0;
-	eth_dev->data->dev_link.link_speed = ETH_LINK_SPEED_10000;
+	eth_dev->data->dev_link.link_status = ETH_LINK_DOWN;
+	eth_dev->data->dev_link.link_speed = ETH_SPEED_NUM_10G;
 	eth_dev->data->dev_link.link_duplex = ETH_LINK_FULL_DUPLEX;
 
 	eth_dev->data->mac_addrs = rte_zmalloc(name, ETHER_ADDR_LEN, 0);
diff --git a/drivers/net/af_packet/rte_eth_af_packet.c b/drivers/net/af_packet/rte_eth_af_packet.c
index 767f36b..5db1db2 100644
--- a/drivers/net/af_packet/rte_eth_af_packet.c
+++ b/drivers/net/af_packet/rte_eth_af_packet.c
@@ -116,9 +116,10 @@ static const char *valid_arguments[] = {
 static const char *drivername = "AF_PACKET PMD";
 
 static struct rte_eth_link pmd_link = {
-	.link_speed = 10000,
+	.link_speed = ETH_SPEED_NUM_10G,
 	.link_duplex = ETH_LINK_FULL_DUPLEX,
-	.link_status = 0
+	.link_status = ETH_LINK_DOWN,
+	.link_autoneg = ETH_LINK_SPEED_NEG
 };
 
 static uint16_t
diff --git a/drivers/net/bnx2x/bnx2x_ethdev.c b/drivers/net/bnx2x/bnx2x_ethdev.c
index b547ac3..efefae6 100644
--- a/drivers/net/bnx2x/bnx2x_ethdev.c
+++ b/drivers/net/bnx2x/bnx2x_ethdev.c
@@ -45,8 +45,12 @@ bnx2x_link_update(struct rte_eth_dev *dev)
 			dev->data->dev_link.link_duplex = ETH_LINK_HALF_DUPLEX;
 			break;
 		default:
-			dev->data->dev_link.link_duplex = ETH_LINK_AUTONEG_DUPLEX;
+			break;
 	}
+
+	dev->data->dev_link.link_autoneg = ~(dev->data->dev_conf.link_speeds &
+						ETH_LINK_SPEED_NO_AUTONEG);
+
 	dev->data->dev_link.link_status = sc->link_vars.link_up;
 }
 
@@ -347,7 +351,7 @@ bnx2x_dev_infos_get(struct rte_eth_dev *dev, __rte_unused struct rte_eth_dev_inf
 	dev_info->min_rx_bufsize = BNX2X_MIN_RX_BUF_SIZE;
 	dev_info->max_rx_pktlen  = BNX2X_MAX_RX_PKT_LEN;
 	dev_info->max_mac_addrs  = BNX2X_MAX_MAC_ADDRS;
-	dev_info->speed_capa = ETH_SPEED_CAP_10G | ETH_SPEED_CAP_20G;
+	dev_info->speed_capa = ETH_LINK_SPEED_10G | ETH_LINK_SPEED_20G;
 }
 
 static void
diff --git a/drivers/net/bonding/rte_eth_bond_8023ad.c b/drivers/net/bonding/rte_eth_bond_8023ad.c
index b3b30f6..3b446e1 100644
--- a/drivers/net/bonding/rte_eth_bond_8023ad.c
+++ b/drivers/net/bonding/rte_eth_bond_8023ad.c
@@ -708,25 +708,25 @@ link_speed_key(uint16_t speed) {
 	uint16_t key_speed;
 
 	switch (speed) {
-	case ETH_LINK_SPEED_AUTONEG:
+	case ETH_SPEED_NUM_NONE:
 		key_speed = 0x00;
 		break;
-	case ETH_LINK_SPEED_10:
+	case ETH_SPEED_NUM_10M:
 		key_speed = BOND_LINK_SPEED_KEY_10M;
 		break;
-	case ETH_LINK_SPEED_100:
+	case ETH_SPEED_NUM_100M:
 		key_speed = BOND_LINK_SPEED_KEY_100M;
 		break;
-	case ETH_LINK_SPEED_1000:
+	case ETH_SPEED_NUM_1G:
 		key_speed = BOND_LINK_SPEED_KEY_1000M;
 		break;
-	case ETH_LINK_SPEED_10G:
+	case ETH_SPEED_NUM_10G:
 		key_speed = BOND_LINK_SPEED_KEY_10G;
 		break;
-	case ETH_LINK_SPEED_20G:
+	case ETH_SPEED_NUM_20G:
 		key_speed = BOND_LINK_SPEED_KEY_20G;
 		break;
-	case ETH_LINK_SPEED_40G:
+	case ETH_SPEED_NUM_40G:
 		key_speed = BOND_LINK_SPEED_KEY_40G;
 		break;
 	default:
diff --git a/drivers/net/cxgbe/base/t4_hw.c b/drivers/net/cxgbe/base/t4_hw.c
index 884d2cf..79af806 100644
--- a/drivers/net/cxgbe/base/t4_hw.c
+++ b/drivers/net/cxgbe/base/t4_hw.c
@@ -2159,13 +2159,13 @@ int t4_handle_fw_rpl(struct adapter *adap, const __be64 *rpl)
 		if (stat & F_FW_PORT_CMD_TXPAUSE)
 			fc |= PAUSE_TX;
 		if (stat & V_FW_PORT_CMD_LSPEED(FW_PORT_CAP_SPEED_100M))
-			speed = ETH_LINK_SPEED_100;
+			speed = ETH_SPEED_NUM_100M;
 		else if (stat & V_FW_PORT_CMD_LSPEED(FW_PORT_CAP_SPEED_1G))
-			speed = ETH_LINK_SPEED_1000;
+			speed = ETH_SPEED_NUM_1G;
 		else if (stat & V_FW_PORT_CMD_LSPEED(FW_PORT_CAP_SPEED_10G))
-			speed = ETH_LINK_SPEED_10000;
+			speed = ETH_SPEED_NUM_10G;
 		else if (stat & V_FW_PORT_CMD_LSPEED(FW_PORT_CAP_SPEED_40G))
-			speed = ETH_LINK_SPEED_40G;
+			speed = ETH_SPEED_NUM_40G;
 
 		for_each_port(adap, i) {
 			pi = adap2pinfo(adap, i);
diff --git a/drivers/net/cxgbe/cxgbe_ethdev.c b/drivers/net/cxgbe/cxgbe_ethdev.c
index 203e119..05b954d 100644
--- a/drivers/net/cxgbe/cxgbe_ethdev.c
+++ b/drivers/net/cxgbe/cxgbe_ethdev.c
@@ -171,7 +171,7 @@ static void cxgbe_dev_info_get(struct rte_eth_dev *eth_dev,
 
 	device_info->rx_desc_lim = cxgbe_desc_lim;
 	device_info->tx_desc_lim = cxgbe_desc_lim;
-	device_info->speed_capa = ETH_SPEED_CAP_10G | ETH_SPEED_CAP_40G;
+	device_info->speed_capa = ETH_LINK_SPEED_10G | ETH_LINK_SPEED_40G;
 }
 
 static void cxgbe_dev_promiscuous_enable(struct rte_eth_dev *eth_dev)
diff --git a/drivers/net/e1000/em_ethdev.c b/drivers/net/e1000/em_ethdev.c
index e40dc37..12c4c63 100644
--- a/drivers/net/e1000/em_ethdev.c
+++ b/drivers/net/e1000/em_ethdev.c
@@ -509,6 +509,9 @@ eth_em_start(struct rte_eth_dev *dev)
 	struct rte_intr_handle *intr_handle = &dev->pci_dev->intr_handle;
 	int ret, mask;
 	uint32_t intr_vector = 0;
+	uint32_t *speeds;
+	int num_speeds;
+	bool autoneg;
 
 	PMD_INIT_FUNC_TRACE();
 
@@ -583,56 +586,46 @@ eth_em_start(struct rte_eth_dev *dev)
 	E1000_WRITE_REG(hw, E1000_ITR, UINT16_MAX);
 
 	/* Setup link speed and duplex */
-	switch (dev->data->dev_conf.link_speed) {
-	case ETH_LINK_SPEED_AUTONEG:
-		if (dev->data->dev_conf.link_duplex == ETH_LINK_AUTONEG_DUPLEX)
-			hw->phy.autoneg_advertised = E1000_ALL_SPEED_DUPLEX;
-		else if (dev->data->dev_conf.link_duplex ==
-					ETH_LINK_HALF_DUPLEX)
-			hw->phy.autoneg_advertised = E1000_ALL_HALF_DUPLEX;
-		else if (dev->data->dev_conf.link_duplex ==
-					ETH_LINK_FULL_DUPLEX)
-			hw->phy.autoneg_advertised = E1000_ALL_FULL_DUPLEX;
-		else
-			goto error_invalid_config;
-		break;
-	case ETH_LINK_SPEED_10:
-		if (dev->data->dev_conf.link_duplex == ETH_LINK_AUTONEG_DUPLEX)
-			hw->phy.autoneg_advertised = E1000_ALL_10_SPEED;
-		else if (dev->data->dev_conf.link_duplex ==
-					ETH_LINK_HALF_DUPLEX)
-			hw->phy.autoneg_advertised = ADVERTISE_10_HALF;
-		else if (dev->data->dev_conf.link_duplex ==
-					ETH_LINK_FULL_DUPLEX)
-			hw->phy.autoneg_advertised = ADVERTISE_10_FULL;
-		else
-			goto error_invalid_config;
-		break;
-	case ETH_LINK_SPEED_100:
-		if (dev->data->dev_conf.link_duplex == ETH_LINK_AUTONEG_DUPLEX)
-			hw->phy.autoneg_advertised = E1000_ALL_100_SPEED;
-		else if (dev->data->dev_conf.link_duplex ==
-					ETH_LINK_HALF_DUPLEX)
-			hw->phy.autoneg_advertised = ADVERTISE_100_HALF;
-		else if (dev->data->dev_conf.link_duplex ==
-					ETH_LINK_FULL_DUPLEX)
-			hw->phy.autoneg_advertised = ADVERTISE_100_FULL;
-		else
+	speeds = &dev->data->dev_conf.link_speeds;
+	if (*speeds == ETH_LINK_SPEED_AUTONEG) {
+		hw->phy.autoneg_advertised = E1000_ALL_SPEED_DUPLEX;
+	} else {
+		num_speeds = 0;
+		autoneg = ~(*speeds & ETH_LINK_SPEED_NO_AUTONEG);
+
+		/* Reset */
+		hw->phy.autoneg_advertised = 0;
+
+		if (*speeds & ~(ETH_LINK_SPEED_10M_HD | ETH_LINK_SPEED_10M |
+				ETH_LINK_SPEED_100M_HD | ETH_LINK_SPEED_100M |
+				ETH_LINK_SPEED_1G)) {
+			num_speeds = -1;
 			goto error_invalid_config;
-		break;
-	case ETH_LINK_SPEED_1000:
-		if ((dev->data->dev_conf.link_duplex ==
-				ETH_LINK_AUTONEG_DUPLEX) ||
-			(dev->data->dev_conf.link_duplex ==
-					ETH_LINK_FULL_DUPLEX))
-			hw->phy.autoneg_advertised = ADVERTISE_1000_FULL;
-		else
+		}
+		if (*speeds & ETH_LINK_SPEED_10M_HD) {
+			hw->phy.autoneg_advertised |= ADVERTISE_10_HALF;
+			num_speeds++;
+		}
+		if (*speeds & ETH_LINK_SPEED_10M) {
+			hw->phy.autoneg_advertised |= ADVERTISE_10_FULL;
+			num_speeds++;
+		}
+		if (*speeds & ETH_LINK_SPEED_100M_HD) {
+			hw->phy.autoneg_advertised |= ADVERTISE_100_HALF;
+			num_speeds++;
+		}
+		if (*speeds & ETH_LINK_SPEED_100M) {
+			hw->phy.autoneg_advertised |= ADVERTISE_100_FULL;
+			num_speeds++;
+		}
+		if (*speeds & ETH_LINK_SPEED_1G) {
+			hw->phy.autoneg_advertised |= ADVERTISE_1000_FULL;
+			num_speeds++;
+		}
+		if (num_speeds == 0 || (!autoneg && (num_speeds > 2)))
 			goto error_invalid_config;
-		break;
-	case ETH_LINK_SPEED_10000:
-	default:
-		goto error_invalid_config;
 	}
+
 	e1000_setup_link(hw);
 
 	if (rte_intr_allow_others(intr_handle)) {
@@ -665,9 +658,8 @@ eth_em_start(struct rte_eth_dev *dev)
 	return 0;
 
 error_invalid_config:
-	PMD_INIT_LOG(ERR, "Invalid link_speed/link_duplex (%u/%u) for port %u",
-		     dev->data->dev_conf.link_speed,
-		     dev->data->dev_conf.link_duplex, dev->data->port_id);
+	PMD_INIT_LOG(ERR, "Invalid advertised speeds (%u) for port %u",
+		     dev->data->dev_conf.link_speeds, dev->data->port_id);
 	em_dev_clear_queues(dev);
 	return -EINVAL;
 }
@@ -1024,11 +1016,11 @@ eth_em_infos_get(struct rte_eth_dev *dev, struct rte_eth_dev_info *dev_info)
 		.nb_align = EM_TXD_ALIGN,
 	};
 
-	dev_info->speed_capa = ETH_SPEED_CAP_10M_HD |
-					ETH_SPEED_CAP_10M_FD |
-					ETH_SPEED_CAP_100M_HD |
-					ETH_SPEED_CAP_100M_FD |
-					ETH_SPEED_CAP_1G;
+	dev_info->speed_capa = ETH_LINK_SPEED_10M_HD |
+					ETH_LINK_SPEED_10M |
+					ETH_LINK_SPEED_100M_HD |
+					ETH_LINK_SPEED_100M |
+					ETH_LINK_SPEED_1G;
 }
 
 /* return 0 means link status changed, -1 means not changed */
@@ -1077,13 +1069,17 @@ eth_em_link_update(struct rte_eth_dev *dev, int wait_to_complete)
 
 	/* Now we check if a transition has happened */
 	if (link_check && (link.link_status == 0)) {
-		hw->mac.ops.get_link_up_info(hw, &link.link_speed,
-			&link.link_duplex);
-		link.link_status = 1;
+		uint16_t duplex, speed;
+		hw->mac.ops.get_link_up_info(hw, &speed, &duplex);
+
+		link.link_duplex = (duplex) ? ETH_LINK_FULL_DUPLEX :
+						ETH_LINK_HALF_DUPLEX;
+		link.link_speed = speed;
+		link.link_status = ETH_LINK_UP;
 	} else if (!link_check && (link.link_status == 1)) {
 		link.link_speed = 0;
-		link.link_duplex = 0;
-		link.link_status = 0;
+		link.link_duplex = ETH_LINK_HALF_DUPLEX;
+		link.link_status = ETH_LINK_DOWN;
 	}
 	rte_em_dev_atomic_write_link_status(dev, &link);
 
diff --git a/drivers/net/e1000/igb_ethdev.c b/drivers/net/e1000/igb_ethdev.c
index 7eac8ea..6682df5 100644
--- a/drivers/net/e1000/igb_ethdev.c
+++ b/drivers/net/e1000/igb_ethdev.c
@@ -1119,6 +1119,9 @@ eth_igb_start(struct rte_eth_dev *dev)
 	int ret, mask;
 	uint32_t intr_vector = 0;
 	uint32_t ctrl_ext;
+	uint32_t *speeds;
+	int num_speeds;
+	bool autoneg;
 
 	PMD_INIT_FUNC_TRACE();
 
@@ -1219,48 +1222,46 @@ eth_igb_start(struct rte_eth_dev *dev)
 	}
 
 	/* Setup link speed and duplex */
-	switch (dev->data->dev_conf.link_speed) {
-	case ETH_LINK_SPEED_AUTONEG:
-		if (dev->data->dev_conf.link_duplex == ETH_LINK_AUTONEG_DUPLEX)
-			hw->phy.autoneg_advertised = E1000_ALL_SPEED_DUPLEX;
-		else if (dev->data->dev_conf.link_duplex == ETH_LINK_HALF_DUPLEX)
-			hw->phy.autoneg_advertised = E1000_ALL_HALF_DUPLEX;
-		else if (dev->data->dev_conf.link_duplex == ETH_LINK_FULL_DUPLEX)
-			hw->phy.autoneg_advertised = E1000_ALL_FULL_DUPLEX;
-		else
-			goto error_invalid_config;
-		break;
-	case ETH_LINK_SPEED_10:
-		if (dev->data->dev_conf.link_duplex == ETH_LINK_AUTONEG_DUPLEX)
-			hw->phy.autoneg_advertised = E1000_ALL_10_SPEED;
-		else if (dev->data->dev_conf.link_duplex == ETH_LINK_HALF_DUPLEX)
-			hw->phy.autoneg_advertised = ADVERTISE_10_HALF;
-		else if (dev->data->dev_conf.link_duplex == ETH_LINK_FULL_DUPLEX)
-			hw->phy.autoneg_advertised = ADVERTISE_10_FULL;
-		else
-			goto error_invalid_config;
-		break;
-	case ETH_LINK_SPEED_100:
-		if (dev->data->dev_conf.link_duplex == ETH_LINK_AUTONEG_DUPLEX)
-			hw->phy.autoneg_advertised = E1000_ALL_100_SPEED;
-		else if (dev->data->dev_conf.link_duplex == ETH_LINK_HALF_DUPLEX)
-			hw->phy.autoneg_advertised = ADVERTISE_100_HALF;
-		else if (dev->data->dev_conf.link_duplex == ETH_LINK_FULL_DUPLEX)
-			hw->phy.autoneg_advertised = ADVERTISE_100_FULL;
-		else
+	speeds = &dev->data->dev_conf.link_speeds;
+	if (*speeds == ETH_LINK_SPEED_AUTONEG) {
+		hw->phy.autoneg_advertised = E1000_ALL_SPEED_DUPLEX;
+	} else {
+		num_speeds = 0;
+		autoneg = ~(*speeds & ETH_LINK_SPEED_NO_AUTONEG);
+
+		/* Reset */
+		hw->phy.autoneg_advertised = 0;
+
+		if (*speeds & ~(ETH_LINK_SPEED_10M_HD | ETH_LINK_SPEED_10M |
+				ETH_LINK_SPEED_100M_HD | ETH_LINK_SPEED_100M |
+				ETH_LINK_SPEED_1G)) {
+			num_speeds = -1;
 			goto error_invalid_config;
-		break;
-	case ETH_LINK_SPEED_1000:
-		if ((dev->data->dev_conf.link_duplex == ETH_LINK_AUTONEG_DUPLEX) ||
-				(dev->data->dev_conf.link_duplex == ETH_LINK_FULL_DUPLEX))
-			hw->phy.autoneg_advertised = ADVERTISE_1000_FULL;
-		else
+		}
+		if (*speeds & ETH_LINK_SPEED_10M_HD) {
+			hw->phy.autoneg_advertised |= ADVERTISE_10_HALF;
+			num_speeds++;
+		}
+		if (*speeds & ETH_LINK_SPEED_10M) {
+			hw->phy.autoneg_advertised |= ADVERTISE_10_FULL;
+			num_speeds++;
+		}
+		if (*speeds & ETH_LINK_SPEED_100M_HD) {
+			hw->phy.autoneg_advertised |= ADVERTISE_100_HALF;
+			num_speeds++;
+		}
+		if (*speeds & ETH_LINK_SPEED_100M) {
+			hw->phy.autoneg_advertised |= ADVERTISE_100_FULL;
+			num_speeds++;
+		}
+		if (*speeds & ETH_LINK_SPEED_1G) {
+			hw->phy.autoneg_advertised |= ADVERTISE_1000_FULL;
+			num_speeds++;
+		}
+		if (num_speeds == 0 || (!autoneg && (num_speeds > 2)))
 			goto error_invalid_config;
-		break;
-	case ETH_LINK_SPEED_10000:
-	default:
-		goto error_invalid_config;
 	}
+
 	e1000_setup_link(hw);
 
 	if (rte_intr_allow_others(intr_handle)) {
@@ -1292,9 +1293,8 @@ eth_igb_start(struct rte_eth_dev *dev)
 	return 0;
 
 error_invalid_config:
-	PMD_INIT_LOG(ERR, "Invalid link_speed/link_duplex (%u/%u) for port %u",
-		     dev->data->dev_conf.link_speed,
-		     dev->data->dev_conf.link_duplex, dev->data->port_id);
+	PMD_INIT_LOG(ERR, "Invalid advertised speeds (%u) for port %u",
+		     dev->data->dev_conf.link_speeds, dev->data->port_id);
 	igb_dev_clear_queues(dev);
 	return -EINVAL;
 }
@@ -1909,11 +1909,11 @@ eth_igb_infos_get(struct rte_eth_dev *dev, struct rte_eth_dev_info *dev_info)
 	dev_info->rx_desc_lim = rx_desc_lim;
 	dev_info->tx_desc_lim = tx_desc_lim;
 
-	dev_info->speed_capa = ETH_SPEED_CAP_10M_HD |
-					ETH_SPEED_CAP_10M_FD |
-					ETH_SPEED_CAP_100M_HD |
-					ETH_SPEED_CAP_100M_FD |
-					ETH_SPEED_CAP_1G;
+	dev_info->speed_capa = ETH_LINK_SPEED_10M_HD |
+					ETH_LINK_SPEED_10M |
+					ETH_LINK_SPEED_100M_HD |
+					ETH_LINK_SPEED_100M |
+					ETH_LINK_SPEED_1G;
 }
 
 static void
@@ -2023,13 +2023,20 @@ eth_igb_link_update(struct rte_eth_dev *dev, int wait_to_complete)
 
 	/* Now we check if a transition has happened */
 	if (link_check) {
-		hw->mac.ops.get_link_up_info(hw, &link.link_speed,
-					  &link.link_duplex);
-		link.link_status = 1;
+		uint16_t duplex, speed;
+		hw->mac.ops.get_link_up_info(hw, &speed, &duplex);
+
+		link.link_duplex = (duplex) ? ETH_LINK_FULL_DUPLEX :
+							ETH_LINK_HALF_DUPLEX;
+		link.link_speed = speed;
+		link.link_status = ETH_LINK_UP;
+		link.link_autoneg = ~(dev->data->dev_conf.link_speeds &
+						ETH_LINK_SPEED_NO_AUTONEG);
 	} else if (!link_check) {
 		link.link_speed = 0;
-		link.link_duplex = 0;
-		link.link_status = 0;
+		link.link_duplex = ETH_LINK_HALF_DUPLEX;
+		link.link_status = ETH_LINK_DOWN;
+		link.link_autoneg = ETH_LINK_SPEED_FIXED;
 	}
 	rte_igb_dev_atomic_write_link_status(dev, &link);
 
diff --git a/drivers/net/fm10k/fm10k_ethdev.c b/drivers/net/fm10k/fm10k_ethdev.c
index 2e6ec60..f44818f 100644
--- a/drivers/net/fm10k/fm10k_ethdev.c
+++ b/drivers/net/fm10k/fm10k_ethdev.c
@@ -1172,7 +1172,7 @@ fm10k_link_update(struct rte_eth_dev *dev,
 	 * is no 50Gbps Ethernet. */
 	dev->data->dev_link.link_speed  = 0;
 	dev->data->dev_link.link_duplex = ETH_LINK_FULL_DUPLEX;
-	dev->data->dev_link.link_status = 1;
+	dev->data->dev_link.link_status = ETH_LINK_UP;
 
 	return 0;
 }
@@ -1334,9 +1334,9 @@ fm10k_dev_infos_get(struct rte_eth_dev *dev,
 		.nb_align = FM10K_MULT_TX_DESC,
 	};
 
-	dev_info->speed_capa = ETH_SPEED_CAP_1G | ETH_SPEED_CAP_2_5G |
-					ETH_SPEED_CAP_10G | ETH_SPEED_CAP_25G |
-					ETH_SPEED_CAP_40G | ETH_SPEED_CAP_100G;
+	dev_info->speed_capa = ETH_LINK_SPEED_1G | ETH_LINK_SPEED_2_5G |
+				ETH_LINK_SPEED_10G | ETH_LINK_SPEED_25G |
+				ETH_LINK_SPEED_40G | ETH_LINK_SPEED_100G;
 }
 
 static int
diff --git a/drivers/net/i40e/i40e_ethdev.c b/drivers/net/i40e/i40e_ethdev.c
index 78a0cbd..e440dcf 100644
--- a/drivers/net/i40e/i40e_ethdev.c
+++ b/drivers/net/i40e/i40e_ethdev.c
@@ -1326,27 +1326,20 @@ i40e_vsi_disable_queues_intr(struct i40e_vsi *vsi)
 }
 
 static inline uint8_t
-i40e_parse_link_speed(uint16_t eth_link_speed)
+i40e_parse_link_speeds(uint16_t link_speeds)
 {
 	uint8_t link_speed = I40E_LINK_SPEED_UNKNOWN;
 
-	switch (eth_link_speed) {
-	case ETH_LINK_SPEED_40G:
-		link_speed = I40E_LINK_SPEED_40GB;
-		break;
-	case ETH_LINK_SPEED_20G:
-		link_speed = I40E_LINK_SPEED_20GB;
-		break;
-	case ETH_LINK_SPEED_10G:
-		link_speed = I40E_LINK_SPEED_10GB;
-		break;
-	case ETH_LINK_SPEED_1000:
-		link_speed = I40E_LINK_SPEED_1GB;
-		break;
-	case ETH_LINK_SPEED_100:
-		link_speed = I40E_LINK_SPEED_100MB;
-		break;
-	}
+	if (link_speeds & ETH_LINK_SPEED_40G)
+		link_speed |= I40E_LINK_SPEED_40GB;
+	if (link_speeds & ETH_LINK_SPEED_20G)
+		link_speed |= I40E_LINK_SPEED_20GB;
+	if (link_speeds & ETH_LINK_SPEED_10G)
+		link_speed |= I40E_LINK_SPEED_10GB;
+	if (link_speeds & ETH_LINK_SPEED_1G)
+		link_speed |= I40E_LINK_SPEED_1GB;
+	if (link_speeds & ETH_LINK_SPEED_100M)
+		link_speed |= I40E_LINK_SPEED_100MB;
 
 	return link_speed;
 }
@@ -1372,9 +1365,9 @@ i40e_apply_link_speed(struct rte_eth_dev *dev)
 	struct i40e_hw *hw = I40E_DEV_PRIVATE_TO_HW(dev->data->dev_private);
 	struct rte_eth_conf *conf = &dev->data->dev_conf;
 
-	speed = i40e_parse_link_speed(conf->link_speed);
+	speed = i40e_parse_link_speeds(conf->link_speeds);
 	abilities |= I40E_AQ_PHY_ENABLE_ATOMIC_LINK;
-	if (conf->link_speed == ETH_LINK_SPEED_AUTONEG)
+	if (conf->link_speeds & ETH_LINK_SPEED_AUTONEG)
 		abilities |= I40E_AQ_PHY_AN_ENABLED;
 	else
 		abilities |= I40E_AQ_PHY_LINK_ENABLED;
@@ -1394,10 +1387,8 @@ i40e_dev_start(struct rte_eth_dev *dev)
 
 	hw->adapter_stopped = 0;
 
-	if ((dev->data->dev_conf.link_duplex != ETH_LINK_AUTONEG_DUPLEX) &&
-		(dev->data->dev_conf.link_duplex != ETH_LINK_FULL_DUPLEX)) {
-		PMD_INIT_LOG(ERR, "Invalid link_duplex (%hu) for port %hhu",
-			     dev->data->dev_conf.link_duplex,
+	if (dev->data->dev_conf.link_speeds & ETH_LINK_SPEED_NO_AUTONEG) {
+		PMD_INIT_LOG(ERR, "Invalid link_speeds for port %hhu; autonegociation disabled",
 			     dev->data->port_id);
 		return -EINVAL;
 	}
@@ -1470,6 +1461,13 @@ i40e_dev_start(struct rte_eth_dev *dev)
 	}
 
 	/* Apply link configure */
+	if (dev->data->dev_conf.link_speeds & ~(ETH_LINK_SPEED_100M |
+				ETH_LINK_SPEED_1G | ETH_LINK_SPEED_10G |
+				ETH_LINK_SPEED_20G | ETH_LINK_SPEED_40G)) {
+		PMD_DRV_LOG(ERR, "Invalid link setting");
+		goto err_up;
+	}
+
 	ret = i40e_apply_link_speed(dev);
 	if (I40E_SUCCESS != ret) {
 		PMD_DRV_LOG(ERR, "Fail to apply link setting");
@@ -1713,7 +1711,7 @@ i40e_dev_link_update(struct rte_eth_dev *dev,
 		/* Get link status information from hardware */
 		status = i40e_aq_get_link_info(hw, false, &link_status, NULL);
 		if (status != I40E_SUCCESS) {
-			link.link_speed = ETH_LINK_SPEED_100;
+			link.link_speed = ETH_SPEED_NUM_100M;
 			link.link_duplex = ETH_LINK_FULL_DUPLEX;
 			PMD_DRV_LOG(ERR, "Failed to get link info");
 			goto out;
@@ -1735,25 +1733,28 @@ i40e_dev_link_update(struct rte_eth_dev *dev,
 	/* Parse the link status */
 	switch (link_status.link_speed) {
 	case I40E_LINK_SPEED_100MB:
-		link.link_speed = ETH_LINK_SPEED_100;
+		link.link_speed = ETH_SPEED_NUM_100M;
 		break;
 	case I40E_LINK_SPEED_1GB:
-		link.link_speed = ETH_LINK_SPEED_1000;
+		link.link_speed = ETH_SPEED_NUM_1G;
 		break;
 	case I40E_LINK_SPEED_10GB:
-		link.link_speed = ETH_LINK_SPEED_10G;
+		link.link_speed = ETH_SPEED_NUM_10G;
 		break;
 	case I40E_LINK_SPEED_20GB:
-		link.link_speed = ETH_LINK_SPEED_20G;
+		link.link_speed = ETH_SPEED_NUM_20G;
 		break;
 	case I40E_LINK_SPEED_40GB:
-		link.link_speed = ETH_LINK_SPEED_40G;
+		link.link_speed = ETH_SPEED_NUM_40G;
 		break;
 	default:
-		link.link_speed = ETH_LINK_SPEED_100;
+		link.link_speed = ETH_SPEED_NUM_100M;
 		break;
 	}
 
+	link.link_autoneg = ~(dev->data->dev_conf.link_speeds &
+						ETH_LINK_SPEED_NO_AUTONEG);
+
 out:
 	rte_i40e_dev_atomic_write_link_status(dev, &link);
 	if (link.link_status == old.link_status)
@@ -2308,10 +2309,10 @@ i40e_dev_info_get(struct rte_eth_dev *dev, struct rte_eth_dev_info *dev_info)
 
 	if (i40e_is_40G_device(hw->device_id))
 		/* For XL710 */
-		dev_info->speed_capa = ETH_SPEED_CAP_1G | ETH_SPEED_CAP_10G;
+		dev_info->speed_capa = ETH_LINK_SPEED_1G | ETH_LINK_SPEED_10G;
 	else
 		/* For X710 */
-		dev_info->speed_capa = ETH_SPEED_CAP_10G | ETH_SPEED_CAP_40G;
+		dev_info->speed_capa = ETH_LINK_SPEED_10G | ETH_LINK_SPEED_40G;
 
 }
 
@@ -7835,15 +7836,15 @@ i40e_start_timecounters(struct rte_eth_dev *dev)
 	rte_i40e_dev_atomic_read_link_status(dev, &link);
 
 	switch (link.link_speed) {
-	case ETH_LINK_SPEED_40G:
+	case ETH_SPEED_NUM_40G:
 		tsync_inc_l = I40E_PTP_40GB_INCVAL & 0xFFFFFFFF;
 		tsync_inc_h = I40E_PTP_40GB_INCVAL >> 32;
 		break;
-	case ETH_LINK_SPEED_10G:
+	case ETH_SPEED_NUM_10G:
 		tsync_inc_l = I40E_PTP_10GB_INCVAL & 0xFFFFFFFF;
 		tsync_inc_h = I40E_PTP_10GB_INCVAL >> 32;
 		break;
-	case ETH_LINK_SPEED_1000:
+	case ETH_SPEED_NUM_1G:
 		tsync_inc_l = I40E_PTP_1GB_INCVAL & 0xFFFFFFFF;
 		tsync_inc_h = I40E_PTP_1GB_INCVAL >> 32;
 		break;
diff --git a/drivers/net/i40e/i40e_ethdev_vf.c b/drivers/net/i40e/i40e_ethdev_vf.c
index 13c5b3d..dd8f1e2 100644
--- a/drivers/net/i40e/i40e_ethdev_vf.c
+++ b/drivers/net/i40e/i40e_ethdev_vf.c
@@ -1911,13 +1911,14 @@ i40evf_dev_link_update(struct rte_eth_dev *dev,
 	 * DPDK pf host provide interfacet to acquire link status
 	 * while Linux driver does not
 	 */
-	if (vf->version_major == I40E_DPDK_VERSION_MAJOR)
+	if (vf->version_major == I40E_DPDK_VERSION_MAJOR) {
 		i40evf_get_link_status(dev, &new_link);
-	else {
+	} else {
 		/* Always assume it's up, for Linux driver PF host */
-		new_link.link_duplex = ETH_LINK_AUTONEG_DUPLEX;
-		new_link.link_speed  = ETH_LINK_SPEED_10000;
-		new_link.link_status = 1;
+		new_link.link_speed  = ETH_SPEED_NUM_10G;
+		new_link.link_duplex = ETH_LINK_FULL_DUPLEX;
+		new_link.link_autoneg = ETH_LINK_SPEED_NEG;
+		new_link.link_status = ETH_LINK_UP;
 	}
 	i40evf_dev_atomic_write_link_status(dev, &new_link);
 
diff --git a/drivers/net/ixgbe/ixgbe_ethdev.c b/drivers/net/ixgbe/ixgbe_ethdev.c
index 7e29c18..4fa07b6 100644
--- a/drivers/net/ixgbe/ixgbe_ethdev.c
+++ b/drivers/net/ixgbe/ixgbe_ethdev.c
@@ -1979,14 +1979,13 @@ ixgbe_dev_start(struct rte_eth_dev *dev)
 	int mask = 0;
 	int status;
 	uint16_t vf, idx;
+	uint32_t *link_speeds;
 
 	PMD_INIT_FUNC_TRACE();
 
 	/* IXGBE devices don't support half duplex */
-	if ((dev->data->dev_conf.link_duplex != ETH_LINK_AUTONEG_DUPLEX) &&
-			(dev->data->dev_conf.link_duplex != ETH_LINK_FULL_DUPLEX)) {
-		PMD_INIT_LOG(ERR, "Invalid link_duplex (%hu) for port %hhu",
-			     dev->data->dev_conf.link_duplex,
+	if (dev->data->dev_conf.link_speeds & ETH_LINK_SPEED_NO_AUTONEG) {
+		PMD_INIT_LOG(ERR, "Invalid link_speeds for port %hhu; autonegociation disabled",
 			     dev->data->port_id);
 		return -EINVAL;
 	}
@@ -2076,32 +2075,22 @@ ixgbe_dev_start(struct rte_eth_dev *dev)
 	if (err)
 		goto error;
 
-	switch(dev->data->dev_conf.link_speed) {
-	case ETH_LINK_SPEED_AUTONEG:
-		speed = (hw->mac.type != ixgbe_mac_82598EB) ?
-				IXGBE_LINK_SPEED_82599_AUTONEG :
-				IXGBE_LINK_SPEED_82598_AUTONEG;
-		break;
-	case ETH_LINK_SPEED_100:
-		/*
-		 * Invalid for 82598 but error will be detected by
-		 * ixgbe_setup_link()
-		 */
-		speed = IXGBE_LINK_SPEED_100_FULL;
-		break;
-	case ETH_LINK_SPEED_1000:
-		speed = IXGBE_LINK_SPEED_1GB_FULL;
-		break;
-	case ETH_LINK_SPEED_10000:
-		speed = IXGBE_LINK_SPEED_10GB_FULL;
-		break;
-	default:
-		PMD_INIT_LOG(ERR, "Invalid link_speed (%hu) for port %hhu",
-			     dev->data->dev_conf.link_speed,
-			     dev->data->port_id);
+	link_speeds = &dev->data->dev_conf.link_speeds;
+	if (*link_speeds & ~(ETH_LINK_SPEED_100M | ETH_LINK_SPEED_1G |
+							ETH_LINK_SPEED_10G)) {
+		PMD_INIT_LOG(ERR, "Invalid link setting");
 		goto error;
 	}
 
+	speed = 0x0;
+
+	if (*link_speeds & ETH_LINK_SPEED_10G)
+		speed |= IXGBE_LINK_SPEED_10GB_FULL;
+	if (*link_speeds & ETH_LINK_SPEED_1G)
+		speed |= IXGBE_LINK_SPEED_1GB_FULL;
+	if (*link_speeds & ETH_LINK_SPEED_100M)
+		speed |= IXGBE_LINK_SPEED_100_FULL;
+
 	err = ixgbe_setup_link(hw, speed, link_up);
 	if (err)
 		goto error;
@@ -2828,15 +2817,16 @@ ixgbe_dev_info_get(struct rte_eth_dev *dev, struct rte_eth_dev_info *dev_info)
 	dev_info->reta_size = ixgbe_reta_size_get(hw->mac.type);
 	dev_info->flow_type_rss_offloads = IXGBE_RSS_OFFLOAD_ALL;
 
-	dev_info->speed_capa = ETH_SPEED_CAP_1G | ETH_SPEED_CAP_10G;
+	dev_info->speed_capa = ETH_LINK_SPEED_1G | ETH_LINK_SPEED_10G;
 
 	if (hw->mac.type == ixgbe_mac_X540 ||
 	    hw->mac.type == ixgbe_mac_X540_vf ||
 	    hw->mac.type == ixgbe_mac_X550 ||
-	    hw->mac.type == ixgbe_mac_X550_vf)
+	    hw->mac.type == ixgbe_mac_X550_vf) {
 
-		dev_info->speed_capa |= ETH_SPEED_CAP_100M_FD /*|
-					ETH_SPEED_CAP_100M_HD*/;
+		dev_info->speed_capa |= ETH_LINK_SPEED_100M /*|
+					ETH_LINK_SPEED_100M_HD*/;
+	}
 }
 
 static void
@@ -2903,9 +2893,9 @@ ixgbe_dev_link_update(struct rte_eth_dev *dev, int wait_to_complete)
 	int link_up;
 	int diag;
 
-	link.link_status = 0;
+	link.link_status = ETH_LINK_DOWN;
 	link.link_speed = 0;
-	link.link_duplex = 0;
+	link.link_duplex = ETH_LINK_HALF_DUPLEX;
 	memset(&old, 0, sizeof(old));
 	rte_ixgbe_dev_atomic_read_link_status(dev, &old);
 
@@ -2918,8 +2908,8 @@ ixgbe_dev_link_update(struct rte_eth_dev *dev, int wait_to_complete)
 		diag = ixgbe_check_link(hw, &link_speed, &link_up, 1);
 
 	if (diag != 0) {
-		link.link_speed = ETH_LINK_SPEED_100;
-		link.link_duplex = ETH_LINK_HALF_DUPLEX;
+		link.link_speed = ETH_SPEED_NUM_100M;
+		link.link_duplex = ETH_LINK_FULL_DUPLEX;
 		rte_ixgbe_dev_atomic_write_link_status(dev, &link);
 		if (link.link_status == old.link_status)
 			return -1;
@@ -2932,26 +2922,26 @@ ixgbe_dev_link_update(struct rte_eth_dev *dev, int wait_to_complete)
 			return -1;
 		return 0;
 	}
-	link.link_status = 1;
+	link.link_status = ETH_LINK_UP;
 	link.link_duplex = ETH_LINK_FULL_DUPLEX;
 
 	switch (link_speed) {
 	default:
 	case IXGBE_LINK_SPEED_UNKNOWN:
-		link.link_duplex = ETH_LINK_HALF_DUPLEX;
-		link.link_speed = ETH_LINK_SPEED_100;
+		link.link_duplex = ETH_LINK_FULL_DUPLEX;
+		link.link_speed = ETH_SPEED_NUM_100M;
 		break;
 
 	case IXGBE_LINK_SPEED_100_FULL:
-		link.link_speed = ETH_LINK_SPEED_100;
+		link.link_speed = ETH_SPEED_NUM_100M;
 		break;
 
 	case IXGBE_LINK_SPEED_1GB_FULL:
-		link.link_speed = ETH_LINK_SPEED_1000;
+		link.link_speed = ETH_SPEED_NUM_1G;
 		break;
 
 	case IXGBE_LINK_SPEED_10GB_FULL:
-		link.link_speed = ETH_LINK_SPEED_10000;
+		link.link_speed = ETH_SPEED_NUM_10G;
 		break;
 	}
 	rte_ixgbe_dev_atomic_write_link_status(dev, &link);
@@ -5725,15 +5715,15 @@ ixgbe_start_timecounters(struct rte_eth_dev *dev)
 	rte_ixgbe_dev_atomic_read_link_status(dev, &link);
 
 	switch (link.link_speed) {
-	case ETH_LINK_SPEED_100:
+	case ETH_SPEED_NUM_100M:
 		incval = IXGBE_INCVAL_100;
 		shift = IXGBE_INCVAL_SHIFT_100;
 		break;
-	case ETH_LINK_SPEED_1000:
+	case ETH_SPEED_NUM_1G:
 		incval = IXGBE_INCVAL_1GB;
 		shift = IXGBE_INCVAL_SHIFT_1GB;
 		break;
-	case ETH_LINK_SPEED_10000:
+	case ETH_SPEED_NUM_10G:
 	default:
 		incval = IXGBE_INCVAL_10GB;
 		shift = IXGBE_INCVAL_SHIFT_10GB;
diff --git a/drivers/net/mlx4/mlx4.c b/drivers/net/mlx4/mlx4.c
index c5688a7..01c3a5c 100644
--- a/drivers/net/mlx4/mlx4.c
+++ b/drivers/net/mlx4/mlx4.c
@@ -4265,8 +4265,8 @@ mlx4_dev_infos_get(struct rte_eth_dev *dev, struct rte_eth_dev_info *info)
 	if (priv_get_ifname(priv, &ifname) == 0)
 		info->if_index = if_nametoindex(ifname);
 
-	info->speed_capa = ETH_SPEED_CAP_10G |ETH_SPEED_CAP_40G |
-					ETH_SPEED_CAP_56G;
+	info->speed_capa = ETH_LINK_SPEED_10G |ETH_LINK_SPEED_40G |
+					ETH_LINK_SPEED_56G;
 
 	priv_unlock(priv);
 }
@@ -4636,6 +4636,8 @@ mlx4_link_update_unlocked(struct rte_eth_dev *dev, int wait_to_complete)
 		dev_link.link_speed = link_speed;
 	dev_link.link_duplex = ((edata.duplex == DUPLEX_HALF) ?
 				ETH_LINK_HALF_DUPLEX : ETH_LINK_FULL_DUPLEX);
+	dev_link.link_autoneg = ~(dev->data->dev_conf.link_speeds &
+						ETH_LINK_SPEED_NO_AUTONEG);
 	if (memcmp(&dev_link, &dev->data->dev_link, sizeof(dev_link))) {
 		/* Link status changed. */
 		dev->data->dev_link = dev_link;
diff --git a/drivers/net/mlx5/mlx5_ethdev.c b/drivers/net/mlx5/mlx5_ethdev.c
index 9c997c5..48de24e 100644
--- a/drivers/net/mlx5/mlx5_ethdev.c
+++ b/drivers/net/mlx5/mlx5_ethdev.c
@@ -524,11 +524,11 @@ mlx5_dev_infos_get(struct rte_eth_dev *dev, struct rte_eth_dev_info *info)
 	 * The API should be updated to solve this problem. */
 	info->reta_size = priv->ind_table_max_size;
 
-	info->speed_capa = ETH_SPEED_CAP_1G | ETH_SPEED_CAP_10G |
-					ETH_SPEED_CAP_25G |
-					ETH_SPEED_CAP_40G |
-					ETH_SPEED_CAP_50G |
-					ETH_SPEED_CAP_100G;
+	info->speed_capa = ETH_LINK_SPEED_1G | ETH_LINK_SPEED_10G |
+						ETH_LINK_SPEED_25G |
+						ETH_LINK_SPEED_40G |
+						ETH_LINK_SPEED_50G |
+						ETH_LINK_SPEED_100G;
 
 	priv_unlock(priv);
 }
diff --git a/drivers/net/mpipe/mpipe_tilegx.c b/drivers/net/mpipe/mpipe_tilegx.c
index 04f3c9f..ecb69b1 100644
--- a/drivers/net/mpipe/mpipe_tilegx.c
+++ b/drivers/net/mpipe/mpipe_tilegx.c
@@ -388,14 +388,16 @@ mpipe_link_update(struct rte_eth_dev *dev, int wait_to_complete)
 
 		speed = state & GXIO_MPIPE_LINK_SPEED_MASK;
 
+		new.link_autoneg = ~(dev->data->dev_conf.link_speeds &
+						ETH_LINK_SPEED_NO_AUTONEG);
 		if (speed == GXIO_MPIPE_LINK_1G) {
 			new.link_speed = ETH_LINK_SPEED_1000;
 			new.link_duplex = ETH_LINK_FULL_DUPLEX;
-			new.link_status = 1;
+			new.link_status = ETH_LINK_UP;
 		} else if (speed == GXIO_MPIPE_LINK_10G) {
 			new.link_speed = ETH_LINK_SPEED_10000;
 			new.link_duplex = ETH_LINK_FULL_DUPLEX;
-			new.link_status = 1;
+			new.link_status = ETH_LINK_UP;
 		}
 
 		rc = mpipe_link_compare(&old, &new);
diff --git a/drivers/net/nfp/nfp_net.c b/drivers/net/nfp/nfp_net.c
index 98a957a..adde1a2 100644
--- a/drivers/net/nfp/nfp_net.c
+++ b/drivers/net/nfp/nfp_net.c
@@ -831,7 +831,7 @@ nfp_net_link_update(struct rte_eth_dev *dev, __rte_unused int wait_to_complete)
 
 	link.link_duplex = ETH_LINK_FULL_DUPLEX;
 	/* Other cards can limit the tx and rx rate per VF */
-	link.link_speed = ETH_LINK_SPEED_40G;
+	link.link_speed = ETH_SPEED_NUM_40G;
 
 	if (old.link_status != link.link_status) {
 		nfp_net_dev_atomic_write_link_status(dev, &link);
@@ -1072,7 +1072,7 @@ nfp_net_infos_get(struct rte_eth_dev *dev, struct rte_eth_dev_info *dev_info)
 	dev_info->reta_size = NFP_NET_CFG_RSS_ITBL_SZ;
 	dev_info->hash_key_size = NFP_NET_CFG_RSS_KEY_SZ;
 
-	dev_info->speed_capa = ETH_SPEED_CAP_50G | ETH_SPEED_CAP_100G;
+	dev_info->speed_capa = ETH_LINK_SPEED_50G | ETH_LINK_SPEED_100G;
 }
 
 static uint32_t
diff --git a/drivers/net/null/rte_eth_null.c b/drivers/net/null/rte_eth_null.c
index 77fc988..55e1fc8 100644
--- a/drivers/net/null/rte_eth_null.c
+++ b/drivers/net/null/rte_eth_null.c
@@ -93,9 +93,10 @@ struct pmd_internals {
 static struct ether_addr eth_addr = { .addr_bytes = {0} };
 static const char *drivername = "Null PMD";
 static struct rte_eth_link pmd_link = {
-	.link_speed = 10000,
+	.link_speed = ETH_SPEED_NUM_10G,
 	.link_duplex = ETH_LINK_FULL_DUPLEX,
-	.link_status = 0
+	.link_status = ETH_LINK_DOWN,
+	.link_autoneg = ETH_LINK_SPEED_NEG,
 };
 
 static uint16_t
diff --git a/drivers/net/pcap/rte_eth_pcap.c b/drivers/net/pcap/rte_eth_pcap.c
index f9230eb..650b521 100644
--- a/drivers/net/pcap/rte_eth_pcap.c
+++ b/drivers/net/pcap/rte_eth_pcap.c
@@ -125,9 +125,10 @@ static int open_single_iface(const char *iface, pcap_t **pcap);
 static struct ether_addr eth_addr = { .addr_bytes = { 0, 0, 0, 0x1, 0x2, 0x3 } };
 static const char *drivername = "Pcap PMD";
 static struct rte_eth_link pmd_link = {
-		.link_speed = 10000,
+		.link_speed = ETH_SPEED_NUM_10G,
 		.link_duplex = ETH_LINK_FULL_DUPLEX,
-		.link_status = 0
+		.link_status = ETH_LINK_DOWN,
+		.link_autoneg = ETH_LINK_SPEED_FIXED,
 };
 
 static int
@@ -430,7 +431,7 @@ eth_dev_start(struct rte_eth_dev *dev)
 
 status_up:
 
-	dev->data->dev_link.link_status = 1;
+	dev->data->dev_link.link_status = ETH_LINK_UP;
 	return 0;
 }
 
@@ -481,7 +482,7 @@ eth_dev_stop(struct rte_eth_dev *dev)
 	}
 
 status_down:
-	dev->data->dev_link.link_status = 0;
+	dev->data->dev_link.link_status = ETH_LINK_DOWN;
 }
 
 static int
diff --git a/drivers/net/ring/rte_eth_ring.c b/drivers/net/ring/rte_eth_ring.c
index d92b088..043175a 100644
--- a/drivers/net/ring/rte_eth_ring.c
+++ b/drivers/net/ring/rte_eth_ring.c
@@ -71,9 +71,10 @@ struct pmd_internals {
 
 static const char *drivername = "Rings PMD";
 static struct rte_eth_link pmd_link = {
-		.link_speed = 10000,
+		.link_speed = ETH_SPEED_NUM_10G,
 		.link_duplex = ETH_LINK_FULL_DUPLEX,
-		.link_status = 0
+		.link_status = ETH_LINK_DOWN,
+		.link_autoneg = ETH_LINK_SPEED_NEG
 };
 
 static uint16_t
diff --git a/drivers/net/virtio/virtio_ethdev.c b/drivers/net/virtio/virtio_ethdev.c
index caa970c..12e71af 100644
--- a/drivers/net/virtio/virtio_ethdev.c
+++ b/drivers/net/virtio/virtio_ethdev.c
@@ -1381,7 +1381,7 @@ virtio_dev_link_update(struct rte_eth_dev *dev, __rte_unused int wait_to_complet
 	memset(&link, 0, sizeof(link));
 	virtio_dev_atomic_read_link_status(dev, &link);
 	old = link;
-	link.link_duplex = FULL_DUPLEX;
+	link.link_duplex = ETH_LINK_FULL_DUPLEX;
 	link.link_speed  = SPEED_10G;
 
 	if (vtpci_with_feature(hw, VIRTIO_NET_F_STATUS)) {
diff --git a/drivers/net/virtio/virtio_ethdev.h b/drivers/net/virtio/virtio_ethdev.h
index fed9571..66423a0 100644
--- a/drivers/net/virtio/virtio_ethdev.h
+++ b/drivers/net/virtio/virtio_ethdev.h
@@ -42,8 +42,6 @@
 #define SPEED_100	100
 #define SPEED_1000	1000
 #define SPEED_10G	10000
-#define HALF_DUPLEX	1
-#define FULL_DUPLEX	2
 
 #ifndef PAGE_SIZE
 #define PAGE_SIZE 4096
diff --git a/drivers/net/vmxnet3/vmxnet3_ethdev.c b/drivers/net/vmxnet3/vmxnet3_ethdev.c
index c363bf6..2bb6ee9 100644
--- a/drivers/net/vmxnet3/vmxnet3_ethdev.c
+++ b/drivers/net/vmxnet3/vmxnet3_ethdev.c
@@ -736,9 +736,10 @@ vmxnet3_dev_link_update(struct rte_eth_dev *dev, __attribute__((unused)) int wai
 	ret = VMXNET3_READ_BAR1_REG(hw, VMXNET3_REG_CMD);
 
 	if (ret & 0x1) {
-		link.link_status = 1;
+		link.link_status = ETH_LINK_UP;
 		link.link_duplex = ETH_LINK_FULL_DUPLEX;
-		link.link_speed = ETH_LINK_SPEED_10000;
+		link.link_speed = ETH_SPEED_NUM_10G;
+		link.link_autoneg = ETH_LINK_SPEED_FIXED;
 	}
 
 	vmxnet3_dev_atomic_write_link_status(dev, &link);
diff --git a/drivers/net/xenvirt/rte_eth_xenvirt.c b/drivers/net/xenvirt/rte_eth_xenvirt.c
index 3f31806..0fcf5d3 100644
--- a/drivers/net/xenvirt/rte_eth_xenvirt.c
+++ b/drivers/net/xenvirt/rte_eth_xenvirt.c
@@ -70,9 +70,10 @@ static int virtio_idx = 0;
 static const char *drivername = "xen virtio PMD";
 
 static struct rte_eth_link pmd_link = {
-		.link_speed = 10000,
+		.link_speed = ETH_SPEED_NUM_10G,
 		.link_duplex = ETH_LINK_FULL_DUPLEX,
-		.link_status = 0
+		.link_status = ETH_LINK_DOWN,
+		.link_autoneg = ETH_LINK_SPEED_FIXED
 };
 
 static void
diff --git a/examples/ip_pipeline/config_parse.c b/examples/ip_pipeline/config_parse.c
index 1bedbe4..c581d41 100644
--- a/examples/ip_pipeline/config_parse.c
+++ b/examples/ip_pipeline/config_parse.c
@@ -84,8 +84,7 @@ static const struct app_link_params link_params_default = {
 	.mac_addr = 0,
 
 	.conf = {
-		.link_speed = 0,
-		.link_duplex = 0,
+		.link_speeds = 0,
 		.rxmode = {
 			.mq_mode = ETH_MQ_RX_NONE,
 
diff --git a/lib/librte_ether/rte_ethdev.c b/lib/librte_ether/rte_ethdev.c
index 1257965..d42b021 100644
--- a/lib/librte_ether/rte_ethdev.c
+++ b/lib/librte_ether/rte_ethdev.c
@@ -863,6 +863,55 @@ rte_eth_dev_tx_queue_config(struct rte_eth_dev *dev, uint16_t nb_queues)
 }
 
 int
+rte_eth_speed_to_bm_flag(uint32_t speed, int duplex, uint32_t *flag)
+{
+	switch (speed) {
+	case ETH_SPEED_NUM_10M:
+		*flag = (duplex) ? ETH_LINK_SPEED_10M :
+							ETH_LINK_SPEED_10M_HD;
+		break;
+	case ETH_SPEED_NUM_100M:
+		*flag = (duplex) ? ETH_LINK_SPEED_100M :
+							ETH_LINK_SPEED_100M_HD;
+		break;
+	case ETH_SPEED_NUM_1G:
+		*flag = ETH_LINK_SPEED_1G;
+		break;
+	case ETH_SPEED_NUM_2_5G:
+		*flag = ETH_LINK_SPEED_2_5G;
+		break;
+	case ETH_SPEED_NUM_5G:
+		*flag = ETH_LINK_SPEED_5G;
+		break;
+	case ETH_SPEED_NUM_10G:
+		*flag = ETH_LINK_SPEED_10G;
+		break;
+	case ETH_SPEED_NUM_20G:
+		*flag = ETH_LINK_SPEED_20G;
+		break;
+	case ETH_SPEED_NUM_25G:
+		*flag = ETH_LINK_SPEED_25G;
+		break;
+	case ETH_SPEED_NUM_40G:
+		*flag = ETH_LINK_SPEED_40G;
+		break;
+	case ETH_SPEED_NUM_50G:
+		*flag = ETH_LINK_SPEED_50G;
+		break;
+	case ETH_SPEED_NUM_56G:
+		*flag = ETH_LINK_SPEED_56G;
+		break;
+	case ETH_SPEED_NUM_100G:
+		*flag = ETH_LINK_SPEED_100G;
+		break;
+	default:
+		return -EINVAL;
+	}
+
+	return 0;
+}
+
+int
 rte_eth_dev_configure(uint8_t port_id, uint16_t nb_rx_q, uint16_t nb_tx_q,
 		      const struct rte_eth_conf *dev_conf)
 {
diff --git a/lib/librte_ether/rte_ethdev.h b/lib/librte_ether/rte_ethdev.h
index 83ddbb7..14a0438 100644
--- a/lib/librte_ether/rte_ethdev.h
+++ b/lib/librte_ether/rte_ethdev.h
@@ -242,26 +242,59 @@ struct rte_eth_stats {
 };
 
 /**
+ * Device supported speeds bitmap flags
+ */
+#define ETH_LINK_SPEED_AUTONEG		(0 << 0)  /*< Autonegociate (all speeds)  */
+#define ETH_LINK_SPEED_NO_AUTONEG	(1 << 0)  /*< Disable autoneg (fixed speed)  */
+#define ETH_LINK_SPEED_10M_HD		(1 << 1)  /*< 10 Mbps half-duplex */
+#define ETH_LINK_SPEED_10M		(1 << 2)  /*< 10 Mbps full-duplex */
+#define ETH_LINK_SPEED_100M_HD		(1 << 3)  /*< 100 Mbps half-duplex */
+#define ETH_LINK_SPEED_100M		(1 << 4)  /*< 100 Mbps full-duplex */
+#define ETH_LINK_SPEED_1G		(1 << 5)  /*< 1 Gbps */
+#define ETH_LINK_SPEED_2_5G		(1 << 6)  /*< 2.5 Gbps */
+#define ETH_LINK_SPEED_5G		(1 << 7)  /*< 5 Gbps */
+#define ETH_LINK_SPEED_10G		(1 << 8)  /*< 10 Mbps */
+#define ETH_LINK_SPEED_20G		(1 << 9)  /*< 20 Gbps */
+#define ETH_LINK_SPEED_25G		(1 << 10)  /*< 25 Gbps */
+#define ETH_LINK_SPEED_40G		(1 << 11)  /*< 40 Gbps */
+#define ETH_LINK_SPEED_50G		(1 << 12)  /*< 50 Gbps */
+#define ETH_LINK_SPEED_56G		(1 << 13)  /*< 56 Gbps */
+#define ETH_LINK_SPEED_100G		(1 << 14)  /*< 100 Gbps */
+
+/**
+ * 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 Mbps */
+#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 */
+
+/**
  * A structure used to retrieve link-level information of an Ethernet port.
  */
 struct rte_eth_link {
-	uint16_t link_speed;      /**< ETH_LINK_SPEED_[10, 100, 1000, 10000] */
-	uint16_t link_duplex;     /**< ETH_LINK_[HALF_DUPLEX, FULL_DUPLEX] */
-	uint8_t  link_status : 1; /**< 1 -> link up, 0 -> link down */
-}__attribute__((aligned(8)));     /**< aligned for atomic64 read/write */
-
-#define ETH_LINK_SPEED_AUTONEG  0       /**< Auto-negotiate link speed. */
-#define ETH_LINK_SPEED_10       10      /**< 10 megabits/second. */
-#define ETH_LINK_SPEED_100      100     /**< 100 megabits/second. */
-#define ETH_LINK_SPEED_1000     1000    /**< 1 gigabits/second. */
-#define ETH_LINK_SPEED_10000    10000   /**< 10 gigabits/second. */
-#define ETH_LINK_SPEED_10G      10000   /**< alias of 10 gigabits/second. */
-#define ETH_LINK_SPEED_20G      20000   /**< 20 gigabits/second. */
-#define ETH_LINK_SPEED_40G      40000   /**< 40 gigabits/second. */
+	uint32_t link_speed;        /**< Link speed (ETH_SPEED_NUM_) */
+	uint16_t link_duplex  : 1;  /**< 1 -> full duplex, 0 -> half duplex */
+	uint16_t link_autoneg : 1;  /**< 1 -> link speed has been autoneg */
+	uint16_t link_status  : 1;  /**< 1 -> link up, 0 -> link down */
+} __attribute__((aligned(8)));      /**< aligned for atomic64 read/write */
 
-#define ETH_LINK_AUTONEG_DUPLEX 0       /**< Auto-negotiate duplex. */
-#define ETH_LINK_HALF_DUPLEX    1       /**< Half-duplex connection. */
-#define ETH_LINK_FULL_DUPLEX    2       /**< Full-duplex connection. */
+/* Utility constants */
+#define ETH_LINK_HALF_DUPLEX    0	/**< Half-duplex connection. */
+#define ETH_LINK_FULL_DUPLEX    1	/**< Full-duplex connection. */
+#define ETH_LINK_SPEED_FIXED    0	/**< Link speed was not autonegociated. */
+#define ETH_LINK_SPEED_NEG      1	/**< Link speed was autonegociated. */
+#define ETH_LINK_DOWN		0	/**< Link is down. */
+#define ETH_LINK_UP		1	/**< Link is up. */
 
 /**
  * A structure used to configure the ring threshold registers of an RX/TX
@@ -760,10 +793,14 @@ struct rte_intr_conf {
  * configuration settings may be needed.
  */
 struct rte_eth_conf {
-	uint16_t link_speed;
-	/**< ETH_LINK_SPEED_10[0|00|000], or 0 for autonegotation */
-	uint16_t link_duplex;
-	/**< ETH_LINK_[HALF_DUPLEX|FULL_DUPLEX], or 0 for autonegotation */
+	uint32_t link_speeds; /**< bitmap of ETH_LINK_SPEED_XXX of speeds to be
+				used. ETH_LINK_SPEED_NO_AUTONEG disables link
+				autonegociation, and a unique speed shall be
+				set. Otherwise, the bitmap defines the set of
+				speeds to be advertised. If the special value
+				ETH_LINK_SPEED_AUTONEG (0) is used, all speeds
+				supported are advertised.
+				*/
 	struct rte_eth_rxmode rxmode; /**< Port RX configuration. */
 	struct rte_eth_txmode txmode; /**< Port TX configuration. */
 	uint32_t lpbk_mode; /**< Loopback operation mode. By default the value
@@ -825,26 +862,6 @@ struct rte_eth_conf {
 #define DEV_TX_OFFLOAD_QINQ_INSERT 0x00000100
 
 /**
- * Device supported speeds
- */
-#define ETH_SPEED_CAP_NOT_PHY	(0)  /*< No phy media > */
-#define ETH_SPEED_CAP_10M_HD	(1 << 0)  /*< 10 Mbps half-duplex> */
-#define ETH_SPEED_CAP_10M_FD	(1 << 1)  /*< 10 Mbps full-duplex> */
-#define ETH_SPEED_CAP_100M_HD	(1 << 2)  /*< 100 Mbps half-duplex> */
-#define ETH_SPEED_CAP_100M_FD	(1 << 3)  /*< 100 Mbps full-duplex> */
-#define ETH_SPEED_CAP_1G	(1 << 4)  /*< 1 Gbps > */
-#define ETH_SPEED_CAP_2_5G	(1 << 5)  /*< 2.5 Gbps > */
-#define ETH_SPEED_CAP_5G	(1 << 6)  /*< 5 Gbps > */
-#define ETH_SPEED_CAP_10G	(1 << 7)  /*< 10 Mbps > */
-#define ETH_SPEED_CAP_20G	(1 << 8)  /*< 20 Gbps > */
-#define ETH_SPEED_CAP_25G	(1 << 9)  /*< 25 Gbps > */
-#define ETH_SPEED_CAP_40G	(1 << 10)  /*< 40 Gbps > */
-#define ETH_SPEED_CAP_50G	(1 << 11)  /*< 50 Gbps > */
-#define ETH_SPEED_CAP_56G	(1 << 12)  /*< 56 Gbps > */
-#define ETH_SPEED_CAP_100G	(1 << 13)  /*< 100 Gbps > */
-
-
-/**
  * Ethernet device information
  */
 struct rte_eth_dev_info {
@@ -1811,6 +1828,22 @@ struct eth_driver {
 void rte_eth_driver_register(struct eth_driver *eth_drv);
 
 /**
+ * Convert a numerical speed in Mbps to a bitmap flag that can be used in
+ * the bitmap link_speeds of the struct rte_eth_conf
+ *
+ * @param
+ *   Numerical speed value in Mbps
+ * @param
+ *   Boolean is duplex (only for 10/100 speeds)
+ * @param
+ *   On success, the converted speed into a bitmap flag
+ * @return
+ *   0 on success, -EINVAL if the speed cannot be mapped
+ */
+extern int rte_eth_speed_to_bm_flag(uint32_t speed, int duplex,
+							uint32_t *flag);
+
+/**
  * Configure an Ethernet device.
  * This function must be invoked first before any other function in the
  * Ethernet API. This function can also be re-invoked when a device is in the
diff --git a/lib/librte_ether/rte_ether_version.map b/lib/librte_ether/rte_ether_version.map
index d8db24d..2c14ad7 100644
--- a/lib/librte_ether/rte_ether_version.map
+++ b/lib/librte_ether/rte_ether_version.map
@@ -117,3 +117,9 @@ DPDK_2.2 {
 
 	local: *;
 };
+
+DPDK_2.3 {
+	global:
+
+	rte_eth_speed_to_bm_flag;
+}DPDK_2.2;
-- 
2.1.4

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

* [PATCH v9 4/4] doc: update with link changes
  2016-03-01  0:45       ` [PATCH v9 0/4] ethdev: add speed capabilities and refactor link API Marc Sune
                           ` (2 preceding siblings ...)
  2016-03-01  0:45         ` [PATCH v9 3/4] ethdev: redesign link speed config API Marc Sune
@ 2016-03-01  0:45         ` Marc Sune
  2016-03-08 15:00         ` [PATCH v9 0/4] ethdev: add speed capabilities and refactor link API Marc Sune
  2016-03-14 21:55         ` [PATCH v10 0/8] ethdev: 100G and link speed API refactoring Thomas Monjalon
  5 siblings, 0 replies; 167+ messages in thread
From: Marc Sune @ 2016-03-01  0:45 UTC (permalink / raw)
  To: dev, Lu, Wenzhuo, Zhang, Helin, Harish Patil, Chen, Jing D

Add new features, ABI changes and resolved issues notice for
the refactored link patch.

Signed-off-by: Marc Sune <marcdevel@gmail.com>
---
 doc/guides/nics/overview.rst           |  1 +
 doc/guides/rel_notes/release_16_04.rst | 27 +++++++++++++++++++++++++++
 2 files changed, 28 insertions(+)

diff --git a/doc/guides/nics/overview.rst b/doc/guides/nics/overview.rst
index d4c6ff4..6c1ae33 100644
--- a/doc/guides/nics/overview.rst
+++ b/doc/guides/nics/overview.rst
@@ -88,6 +88,7 @@ Most of these differences are summarized below.
    ==================== = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
    link status
    link status event
+   Speed capabilities
    Rx interrupt
    queue start/stop
    MTU update
diff --git a/doc/guides/rel_notes/release_16_04.rst b/doc/guides/rel_notes/release_16_04.rst
index 64e913d..fd2d3cc 100644
--- a/doc/guides/rel_notes/release_16_04.rst
+++ b/doc/guides/rel_notes/release_16_04.rst
@@ -20,6 +20,18 @@ Build the docs and view the output file to ensure the changes are correct::
 New Features
 ------------
 
+* **ethdev: define a set of advertised link speeds.**
+
+  Added functionality to Allow defining a set of advertised speeds for
+  auto-negociation, explicitely disabling link auto-negociation (single speed)
+  and full auto-negociation.
+
+* **ethdev: add speed_cap bitmap for link speed capabilities.**
+
+  ``struct rte_eth_dev_info`` has now ``speed_cap`` bitmap, which allows the
+  application to recover the supported speeds for that ethernet device.
+
+
 This section should contain new features added in this release. Sample format:
 
 * **Add a title in the past tense with a full stop.**
@@ -55,6 +67,11 @@ This section should contain new features added in this release. Sample format:
 Resolved Issues
 ---------------
 
+* **ethdev: Fixed link_speed overflow in rte_eth_link for 100Gbps.**
+
+  100Gbps in Mbps (100000) exceeds 16 bit max value of ``link_speed`` in
+  ``rte_eth_link``.
+
 This section should contain bug fixes added to the relevant sections. Sample format:
 
 * **code/section Fixed issue in the past tense with a full stop.**
@@ -87,6 +104,9 @@ Drivers
 Libraries
 ~~~~~~~~~
 
+* New API call, ``rte_eth_speed_to_bm_flag`` in ethdev to, map numerical speeds
+  to bitmap fields.
+
 
 Examples
 ~~~~~~~~
@@ -119,6 +139,13 @@ This section should contain API changes. Sample format:
 ABI Changes
 -----------
 
+* The ethdev ``rte_eth_link`` and ``rte_eth_conf`` structures were changed to
+  support the new link API, as well as ``ETH_LINK_HALF``/``FULL_DUPLEX``.
+
+* The ethdev ``rte_eth_dev_info`` was changed to support device speed
+  capabilities.
+
+
 * Add a short 1-2 sentence description of the ABI change that was announced in
   the previous releases and made in this release. Use fixed width quotes for
   ``rte_function_names`` or ``rte_struct_names``. Use the past tense.
-- 
2.1.4

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

* Re: [PATCH v9 0/4] ethdev: add speed capabilities and refactor link API
  2016-03-01  0:45       ` [PATCH v9 0/4] ethdev: add speed capabilities and refactor link API Marc Sune
                           ` (3 preceding siblings ...)
  2016-03-01  0:45         ` [PATCH v9 4/4] doc: update with link changes Marc Sune
@ 2016-03-08 15:00         ` Marc Sune
  2016-03-08 16:53           ` Nélio Laranjeiro
  2016-03-14 21:55         ` [PATCH v10 0/8] ethdev: 100G and link speed API refactoring Thomas Monjalon
  5 siblings, 1 reply; 167+ messages in thread
From: Marc Sune @ 2016-03-08 15:00 UTC (permalink / raw)
  To: dev, Lu, Wenzhuo, Zhang, Helin, Harish Patil, Chen, Jing D

2016-03-01 1:45 GMT+01:00 Marc Sune <marcdevel@gmail.com>:

> The current rte_eth_dev_info abstraction does not provide any mechanism to
> get the supported speed(s) of an ethdev.
>
> For some drivers (e.g. ixgbe), an educated guess could be done based on the
> driver's name (driver_name in rte_eth_dev_info), see:
>
> http://dpdk.org/ml/archives/dev/2013-August/000412.html
>
> However, i) doing string comparisons is annoying, and can silently
> break existing applications if PMDs change their names ii) it does not
> provide all the supported capabilities of the ethdev iii) for some drivers
> it
> is impossible determine correctly the (max) speed by the application
> (e.g. in i40, distinguish between XL710 and X710).
>
> In addition, the link APIs do not allow to define a set of advertised link
> speeds for autonegociation.
>
> This series of patches adds the following capabilities:
>
> * speed_capa bitmap in rte_eth_dev_info, which is filled by the PMDs
>   according to the physical device capabilities.
> * refactors link API in ethdev to allow the definition of the advertised
>   link speeds, fix speed (no auto-negociation) or advertise all supported
>   speeds (default).
>
> WARNING: this patch series, specifically 3/4, is NOT tested for most of the
> PMDs, due to the lack of hardware. Only generic EM is tested (VM).
> Reviewing
> and testing required by PMD maintainers.
>
> * * * * *
>
> v2: rebase, converted speed_capa into 32 bits bitmap, fixed alignment
>     (checkpatch).
>
> v3: rebase to v2.1. unified ETH_LINK_SPEED and ETH_SPEED_CAP into
> ETH_SPEED.
>     Converted field speed in struct rte_eth_conf to speed, to allow a
> bitmap
>     for defining the announced speeds, as suggested M. Brorup. Fixed
> spelling
>     issues.
>
> v4: fixed errata in the documentation of field speeds of rte_eth_conf, and
>     commit 1/2 message. rebased to v2.1.0. v3 was incorrectly based on
>     ~2.1.0-rc1.
>
> v5: revert to v2 speed capabilities patch. Fixed MLX4 speed capabilities
>     (thanks N. Laranjeiro). Refactored link speed API to allow setting
>     advertised speeds (3/4). Added NO_AUTONEG option to explicitely disable
>     auto-negociation. Updated 2.2 rel. notes (4/4). Rebased to current
> HEAD.
>
> v6: Move link_duplex to be part of bitfield. Fixed i40 autoneg flag link
>     update code. Added rte_eth_speed_to_bm_flag() to .map file. Fixed other
>     spelling issues. Rebased to current HEAD.
>
> v7: Rebased to current HEAD. Moved documentation to v2.3. Still needs
> testing
>     from PMD maintainers.
>
> v8: Rebased to current HEAD. Modified em driver impl. to not touch base
> files.
>     Merged patch 5 into 3 (map file). Changed numeric speed to a 64 bit
> value.
>     Filled-in speed capabilities for drivers bnx2x, cxgbe, mlx5 and nfp in
>     addition to the ones of previous patch sets.
>
> v9: rebased to current HEAD. Reverted numeric speed to 32 bit in struct
>     rte_eth_link (no atomic link get > 64bit). Fixed mlx5 driver
> compilation
>     and link speeds. Moved documentation to release_16_04.rst and fixed
> several
>     issues. Upgrade NIC notes with speed capabilities.
>

Anyone interested in reviewing and _testing_ this series?

Thank you
Marc


>
> Marc Sune (4):
>   ethdev: Added ETH_SPEED_CAP bitmap for ports
>   ethdev: Fill speed capability bitmaps in the PMDs
>   ethdev: redesign link speed config API
>   doc: update with link changes
>
>  app/test-pipeline/init.c                  |   2 +-
>  app/test-pmd/cmdline.c                    | 124
> +++++++++++++++---------------
>  app/test-pmd/config.c                     |   4 +-
>  app/test/virtual_pmd.c                    |   4 +-
>  doc/guides/nics/overview.rst              |   1 +
>  doc/guides/rel_notes/release_16_04.rst    |  27 +++++++
>  drivers/net/af_packet/rte_eth_af_packet.c |   5 +-
>  drivers/net/bnx2x/bnx2x_ethdev.c          |   7 +-
>  drivers/net/bonding/rte_eth_bond_8023ad.c |  14 ++--
>  drivers/net/cxgbe/base/t4_hw.c            |   8 +-
>  drivers/net/cxgbe/cxgbe_ethdev.c          |   1 +
>  drivers/net/e1000/em_ethdev.c             | 112
> ++++++++++++++-------------
>  drivers/net/e1000/igb_ethdev.c            | 107 +++++++++++++++-----------
>  drivers/net/fm10k/fm10k_ethdev.c          |   6 +-
>  drivers/net/i40e/i40e_ethdev.c            |  78 +++++++++++--------
>  drivers/net/i40e/i40e_ethdev_vf.c         |  11 +--
>  drivers/net/ixgbe/ixgbe_ethdev.c          |  80 +++++++++----------
>  drivers/net/mlx4/mlx4.c                   |   6 ++
>  drivers/net/mlx5/mlx5_ethdev.c            |   7 ++
>  drivers/net/mpipe/mpipe_tilegx.c          |   6 +-
>  drivers/net/nfp/nfp_net.c                 |   4 +-
>  drivers/net/null/rte_eth_null.c           |   5 +-
>  drivers/net/pcap/rte_eth_pcap.c           |   9 ++-
>  drivers/net/ring/rte_eth_ring.c           |   5 +-
>  drivers/net/virtio/virtio_ethdev.c        |   2 +-
>  drivers/net/virtio/virtio_ethdev.h        |   2 -
>  drivers/net/vmxnet3/vmxnet3_ethdev.c      |   5 +-
>  drivers/net/xenvirt/rte_eth_xenvirt.c     |   5 +-
>  examples/ip_pipeline/config_parse.c       |   3 +-
>  lib/librte_ether/rte_ethdev.c             |  49 ++++++++++++
>  lib/librte_ether/rte_ethdev.h             |  97 ++++++++++++++++++-----
>  lib/librte_ether/rte_ether_version.map    |   6 ++
>  32 files changed, 501 insertions(+), 301 deletions(-)
>
> --
> 2.1.4
>
>

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

* Re: [PATCH v9 0/4] ethdev: add speed capabilities and refactor link API
  2016-03-08 15:00         ` [PATCH v9 0/4] ethdev: add speed capabilities and refactor link API Marc Sune
@ 2016-03-08 16:53           ` Nélio Laranjeiro
  2016-03-09  9:29             ` Nélio Laranjeiro
  0 siblings, 1 reply; 167+ messages in thread
From: Nélio Laranjeiro @ 2016-03-08 16:53 UTC (permalink / raw)
  To: Marc Sune; +Cc: dev

On Tue, Mar 08, 2016 at 04:00:29PM +0100, Marc Sune wrote:
> 2016-03-01 1:45 GMT+01:00 Marc Sune <marcdevel@gmail.com>:
> 
> > The current rte_eth_dev_info abstraction does not provide any mechanism to
> > get the supported speed(s) of an ethdev.
> >
> > For some drivers (e.g. ixgbe), an educated guess could be done based on the
> > driver's name (driver_name in rte_eth_dev_info), see:
> >
> > http://dpdk.org/ml/archives/dev/2013-August/000412.html
> >
> > However, i) doing string comparisons is annoying, and can silently
> > break existing applications if PMDs change their names ii) it does not
> > provide all the supported capabilities of the ethdev iii) for some drivers
> > it
> > is impossible determine correctly the (max) speed by the application
> > (e.g. in i40, distinguish between XL710 and X710).
> >
> > In addition, the link APIs do not allow to define a set of advertised link
> > speeds for autonegociation.
> >
> > This series of patches adds the following capabilities:
> >
> > * speed_capa bitmap in rte_eth_dev_info, which is filled by the PMDs
> >   according to the physical device capabilities.
> > * refactors link API in ethdev to allow the definition of the advertised
> >   link speeds, fix speed (no auto-negociation) or advertise all supported
> >   speeds (default).
> >
> > WARNING: this patch series, specifically 3/4, is NOT tested for most of the
> > PMDs, due to the lack of hardware. Only generic EM is tested (VM).
> > Reviewing
> > and testing required by PMD maintainers.
> >
> > * * * * *
> >
> > v2: rebase, converted speed_capa into 32 bits bitmap, fixed alignment
> >     (checkpatch).
> >
> > v3: rebase to v2.1. unified ETH_LINK_SPEED and ETH_SPEED_CAP into
> > ETH_SPEED.
> >     Converted field speed in struct rte_eth_conf to speed, to allow a
> > bitmap
> >     for defining the announced speeds, as suggested M. Brorup. Fixed
> > spelling
> >     issues.
> >
> > v4: fixed errata in the documentation of field speeds of rte_eth_conf, and
> >     commit 1/2 message. rebased to v2.1.0. v3 was incorrectly based on
> >     ~2.1.0-rc1.
> >
> > v5: revert to v2 speed capabilities patch. Fixed MLX4 speed capabilities
> >     (thanks N. Laranjeiro). Refactored link speed API to allow setting
> >     advertised speeds (3/4). Added NO_AUTONEG option to explicitely disable
> >     auto-negociation. Updated 2.2 rel. notes (4/4). Rebased to current
> > HEAD.
> >
> > v6: Move link_duplex to be part of bitfield. Fixed i40 autoneg flag link
> >     update code. Added rte_eth_speed_to_bm_flag() to .map file. Fixed other
> >     spelling issues. Rebased to current HEAD.
> >
> > v7: Rebased to current HEAD. Moved documentation to v2.3. Still needs
> > testing
> >     from PMD maintainers.
> >
> > v8: Rebased to current HEAD. Modified em driver impl. to not touch base
> > files.
> >     Merged patch 5 into 3 (map file). Changed numeric speed to a 64 bit
> > value.
> >     Filled-in speed capabilities for drivers bnx2x, cxgbe, mlx5 and nfp in
> >     addition to the ones of previous patch sets.
> >
> > v9: rebased to current HEAD. Reverted numeric speed to 32 bit in struct
> >     rte_eth_link (no atomic link get > 64bit). Fixed mlx5 driver
> > compilation
> >     and link speeds. Moved documentation to release_16_04.rst and fixed
> > several
> >     issues. Upgrade NIC notes with speed capabilities.
> >
> 
> Anyone interested in reviewing and _testing_ this series?
> 
> Thank you
> Marc

Hi Marc,

I will take a look tomorrow morning and run test on Mellanox NICs
(ConnectX 3 and 4).

I do not have access to the others NICs, if those who have can do
it, could be really great.

Regards,

-- 
Nélio Laranjeiro
6WIND

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

* Re: [PATCH v9 3/4] ethdev: redesign link speed config API
  2016-03-01  0:45         ` [PATCH v9 3/4] ethdev: redesign link speed config API Marc Sune
@ 2016-03-09  8:45           ` Nélio Laranjeiro
  2016-03-09 10:09             ` Marc
  0 siblings, 1 reply; 167+ messages in thread
From: Nélio Laranjeiro @ 2016-03-09  8:45 UTC (permalink / raw)
  To: Marc Sune; +Cc: dev

Hi Marc,

A small remark bellow.

On Tue, Mar 01, 2016 at 01:45:50AM +0100, Marc Sune wrote:
> This patch redesigns the API to set the link speed/s configure
> for an ethernet port. Specifically:
> 
> - it allows to define a set of advertised speeds for
>   auto-negociation.
> - it allows to disable link auto-negociation (single fixed speed).
> - default: auto-negociate all supported speeds.
> 
> Other changes:
> 
> * Added utility MACROs ETH_SPEED_NUM_XXX with the numeric
>   values of all supported link speeds, in Mbps.
> * Converted link_speed to uint32_t to accomodate 100G speeds
>   and beyond (bug).
> * Added autoneg flag in struct rte_eth_link to indicate if
>   link speed was a result of auto-negociation or was fixed
>   by configuration.
> * Added utility function to convert numeric speeds to bitmap
>   fields.
> * Added rte_eth_speed_to_bm_flag() to version map.
> 
> Signed-off-by: Marc Sune <marcdevel@gmail.com>
> ---
>  app/test-pipeline/init.c                  |   2 +-
>  app/test-pmd/cmdline.c                    | 124 +++++++++++++++---------------
>  app/test-pmd/config.c                     |   4 +-
>  app/test/virtual_pmd.c                    |   4 +-
>  drivers/net/af_packet/rte_eth_af_packet.c |   5 +-
>  drivers/net/bnx2x/bnx2x_ethdev.c          |   8 +-
>  drivers/net/bonding/rte_eth_bond_8023ad.c |  14 ++--
>  drivers/net/cxgbe/base/t4_hw.c            |   8 +-
>  drivers/net/cxgbe/cxgbe_ethdev.c          |   2 +-
>  drivers/net/e1000/em_ethdev.c             | 116 ++++++++++++++--------------
>  drivers/net/e1000/igb_ethdev.c            | 111 +++++++++++++-------------
>  drivers/net/fm10k/fm10k_ethdev.c          |   8 +-
>  drivers/net/i40e/i40e_ethdev.c            |  73 +++++++++---------
>  drivers/net/i40e/i40e_ethdev_vf.c         |  11 +--
>  drivers/net/ixgbe/ixgbe_ethdev.c          |  78 ++++++++-----------
>  drivers/net/mlx4/mlx4.c                   |   6 +-
>  drivers/net/mlx5/mlx5_ethdev.c            |  10 +--
>  drivers/net/mpipe/mpipe_tilegx.c          |   6 +-
>  drivers/net/nfp/nfp_net.c                 |   4 +-
>  drivers/net/null/rte_eth_null.c           |   5 +-
>  drivers/net/pcap/rte_eth_pcap.c           |   9 ++-
>  drivers/net/ring/rte_eth_ring.c           |   5 +-
>  drivers/net/virtio/virtio_ethdev.c        |   2 +-
>  drivers/net/virtio/virtio_ethdev.h        |   2 -
>  drivers/net/vmxnet3/vmxnet3_ethdev.c      |   5 +-
>  drivers/net/xenvirt/rte_eth_xenvirt.c     |   5 +-
>  examples/ip_pipeline/config_parse.c       |   3 +-
>  lib/librte_ether/rte_ethdev.c             |  49 ++++++++++++
>  lib/librte_ether/rte_ethdev.h             | 113 +++++++++++++++++----------
>  lib/librte_ether/rte_ether_version.map    |   6 ++
>  30 files changed, 448 insertions(+), 350 deletions(-)
> 
> diff --git a/app/test-pipeline/init.c b/app/test-pipeline/init.c
> index db2196b..6a69fe2 100644
> --- a/app/test-pipeline/init.c
> +++ b/app/test-pipeline/init.c
> @@ -200,7 +200,7 @@ app_ports_check_link(void)
>  		port = (uint8_t) app.ports[i];
>  		memset(&link, 0, sizeof(link));
>  		rte_eth_link_get_nowait(port, &link);
> -		RTE_LOG(INFO, USER1, "Port %u (%u Gbps) %s\n",
> +		RTE_LOG(INFO, USER1, "Port %u (%d Gbps) %s\n",
>  			port,
>  			link.link_speed / 1000,
>  			link.link_status ? "UP" : "DOWN");
> diff --git a/app/test-pmd/cmdline.c b/app/test-pmd/cmdline.c
> index 52e9f5f..57ad25f 100644
> --- a/app/test-pmd/cmdline.c
> +++ b/app/test-pmd/cmdline.c
> @@ -956,14 +956,65 @@ struct cmd_config_speed_all {
>  	cmdline_fixed_string_t value2;
>  };
>  
> +static int
> +parse_and_check_speed_duplex(char *value1, char *value2, uint32_t *link_speed)

"value" variables should have the more friendly name, we need to read the
code to understand what is value1 and value2.

>[...] 

-- 
Nélio Laranjeiro
6WIND

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

* Re: [PATCH v9 0/4] ethdev: add speed capabilities and refactor link API
  2016-03-08 16:53           ` Nélio Laranjeiro
@ 2016-03-09  9:29             ` Nélio Laranjeiro
  2016-03-09 10:09               ` Nélio Laranjeiro
  0 siblings, 1 reply; 167+ messages in thread
From: Nélio Laranjeiro @ 2016-03-09  9:29 UTC (permalink / raw)
  To: Marc Sune; +Cc: dev

On Tue, Mar 08, 2016 at 05:53:05PM +0100, Nélio Laranjeiro wrote:
> On Tue, Mar 08, 2016 at 04:00:29PM +0100, Marc Sune wrote:
> > 2016-03-01 1:45 GMT+01:00 Marc Sune <marcdevel@gmail.com>:
> > 
> > > The current rte_eth_dev_info abstraction does not provide any mechanism to
> > > get the supported speed(s) of an ethdev.
> > >
> > > For some drivers (e.g. ixgbe), an educated guess could be done based on the
> > > driver's name (driver_name in rte_eth_dev_info), see:
> > >
> > > http://dpdk.org/ml/archives/dev/2013-August/000412.html
> > >
> > > However, i) doing string comparisons is annoying, and can silently
> > > break existing applications if PMDs change their names ii) it does not
> > > provide all the supported capabilities of the ethdev iii) for some drivers
> > > it
> > > is impossible determine correctly the (max) speed by the application
> > > (e.g. in i40, distinguish between XL710 and X710).
> > >
> > > In addition, the link APIs do not allow to define a set of advertised link
> > > speeds for autonegociation.
> > >
> > > This series of patches adds the following capabilities:
> > >
> > > * speed_capa bitmap in rte_eth_dev_info, which is filled by the PMDs
> > >   according to the physical device capabilities.
> > > * refactors link API in ethdev to allow the definition of the advertised
> > >   link speeds, fix speed (no auto-negociation) or advertise all supported
> > >   speeds (default).
> > >
> > > WARNING: this patch series, specifically 3/4, is NOT tested for most of the
> > > PMDs, due to the lack of hardware. Only generic EM is tested (VM).
> > > Reviewing
> > > and testing required by PMD maintainers.
> > >
> > > * * * * *
> > >
> > > v2: rebase, converted speed_capa into 32 bits bitmap, fixed alignment
> > >     (checkpatch).
> > >
> > > v3: rebase to v2.1. unified ETH_LINK_SPEED and ETH_SPEED_CAP into
> > > ETH_SPEED.
> > >     Converted field speed in struct rte_eth_conf to speed, to allow a
> > > bitmap
> > >     for defining the announced speeds, as suggested M. Brorup. Fixed
> > > spelling
> > >     issues.
> > >
> > > v4: fixed errata in the documentation of field speeds of rte_eth_conf, and
> > >     commit 1/2 message. rebased to v2.1.0. v3 was incorrectly based on
> > >     ~2.1.0-rc1.
> > >
> > > v5: revert to v2 speed capabilities patch. Fixed MLX4 speed capabilities
> > >     (thanks N. Laranjeiro). Refactored link speed API to allow setting
> > >     advertised speeds (3/4). Added NO_AUTONEG option to explicitely disable
> > >     auto-negociation. Updated 2.2 rel. notes (4/4). Rebased to current
> > > HEAD.
> > >
> > > v6: Move link_duplex to be part of bitfield. Fixed i40 autoneg flag link
> > >     update code. Added rte_eth_speed_to_bm_flag() to .map file. Fixed other
> > >     spelling issues. Rebased to current HEAD.
> > >
> > > v7: Rebased to current HEAD. Moved documentation to v2.3. Still needs
> > > testing
> > >     from PMD maintainers.
> > >
> > > v8: Rebased to current HEAD. Modified em driver impl. to not touch base
> > > files.
> > >     Merged patch 5 into 3 (map file). Changed numeric speed to a 64 bit
> > > value.
> > >     Filled-in speed capabilities for drivers bnx2x, cxgbe, mlx5 and nfp in
> > >     addition to the ones of previous patch sets.
> > >
> > > v9: rebased to current HEAD. Reverted numeric speed to 32 bit in struct
> > >     rte_eth_link (no atomic link get > 64bit). Fixed mlx5 driver
> > > compilation
> > >     and link speeds. Moved documentation to release_16_04.rst and fixed
> > > several
> > >     issues. Upgrade NIC notes with speed capabilities.
> > >
> > 
> > Anyone interested in reviewing and _testing_ this series?
> > 
> > Thank you
> > Marc
> 
> Hi Marc,
> 
> I will take a look tomorrow morning and run test on Mellanox NICs
> (ConnectX 3 and 4).
> 
> I do not have access to the others NICs, if those who have can do
> it, could be really great.
> 
> Regards,

It works as expected with Mellanox NICs.

Regards,

-- 
Nélio Laranjeiro
6WIND

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

* Re: [PATCH v9 0/4] ethdev: add speed capabilities and refactor link API
  2016-03-09  9:29             ` Nélio Laranjeiro
@ 2016-03-09 10:09               ` Nélio Laranjeiro
  2016-03-09 20:57                 ` Marc
  0 siblings, 1 reply; 167+ messages in thread
From: Nélio Laranjeiro @ 2016-03-09 10:09 UTC (permalink / raw)
  To: Marc Sune; +Cc: dev

On Wed, Mar 09, 2016 at 10:29:38AM +0100, Nélio Laranjeiro wrote:
> On Tue, Mar 08, 2016 at 05:53:05PM +0100, Nélio Laranjeiro wrote:
> > On Tue, Mar 08, 2016 at 04:00:29PM +0100, Marc Sune wrote:
> > > 2016-03-01 1:45 GMT+01:00 Marc Sune <marcdevel@gmail.com>:
> > > 
> > > > The current rte_eth_dev_info abstraction does not provide any mechanism to
> > > > get the supported speed(s) of an ethdev.
> > > >
> > > > For some drivers (e.g. ixgbe), an educated guess could be done based on the
> > > > driver's name (driver_name in rte_eth_dev_info), see:
> > > >
> > > > http://dpdk.org/ml/archives/dev/2013-August/000412.html
> > > >
> > > > However, i) doing string comparisons is annoying, and can silently
> > > > break existing applications if PMDs change their names ii) it does not
> > > > provide all the supported capabilities of the ethdev iii) for some drivers
> > > > it
> > > > is impossible determine correctly the (max) speed by the application
> > > > (e.g. in i40, distinguish between XL710 and X710).
> > > >
> > > > In addition, the link APIs do not allow to define a set of advertised link
> > > > speeds for autonegociation.
> > > >
> > > > This series of patches adds the following capabilities:
> > > >
> > > > * speed_capa bitmap in rte_eth_dev_info, which is filled by the PMDs
> > > >   according to the physical device capabilities.
> > > > * refactors link API in ethdev to allow the definition of the advertised
> > > >   link speeds, fix speed (no auto-negociation) or advertise all supported
> > > >   speeds (default).
> > > >
> > > > WARNING: this patch series, specifically 3/4, is NOT tested for most of the
> > > > PMDs, due to the lack of hardware. Only generic EM is tested (VM).
> > > > Reviewing
> > > > and testing required by PMD maintainers.
> > > >
> > > > * * * * *
> > > >
> > > > v2: rebase, converted speed_capa into 32 bits bitmap, fixed alignment
> > > >     (checkpatch).
> > > >
> > > > v3: rebase to v2.1. unified ETH_LINK_SPEED and ETH_SPEED_CAP into
> > > > ETH_SPEED.
> > > >     Converted field speed in struct rte_eth_conf to speed, to allow a
> > > > bitmap
> > > >     for defining the announced speeds, as suggested M. Brorup. Fixed
> > > > spelling
> > > >     issues.
> > > >
> > > > v4: fixed errata in the documentation of field speeds of rte_eth_conf, and
> > > >     commit 1/2 message. rebased to v2.1.0. v3 was incorrectly based on
> > > >     ~2.1.0-rc1.
> > > >
> > > > v5: revert to v2 speed capabilities patch. Fixed MLX4 speed capabilities
> > > >     (thanks N. Laranjeiro). Refactored link speed API to allow setting
> > > >     advertised speeds (3/4). Added NO_AUTONEG option to explicitely disable
> > > >     auto-negociation. Updated 2.2 rel. notes (4/4). Rebased to current
> > > > HEAD.
> > > >
> > > > v6: Move link_duplex to be part of bitfield. Fixed i40 autoneg flag link
> > > >     update code. Added rte_eth_speed_to_bm_flag() to .map file. Fixed other
> > > >     spelling issues. Rebased to current HEAD.
> > > >
> > > > v7: Rebased to current HEAD. Moved documentation to v2.3. Still needs
> > > > testing
> > > >     from PMD maintainers.
> > > >
> > > > v8: Rebased to current HEAD. Modified em driver impl. to not touch base
> > > > files.
> > > >     Merged patch 5 into 3 (map file). Changed numeric speed to a 64 bit
> > > > value.
> > > >     Filled-in speed capabilities for drivers bnx2x, cxgbe, mlx5 and nfp in
> > > >     addition to the ones of previous patch sets.
> > > >
> > > > v9: rebased to current HEAD. Reverted numeric speed to 32 bit in struct
> > > >     rte_eth_link (no atomic link get > 64bit). Fixed mlx5 driver
> > > > compilation
> > > >     and link speeds. Moved documentation to release_16_04.rst and fixed
> > > > several
> > > >     issues. Upgrade NIC notes with speed capabilities.
> > > >
> > > 
> > > Anyone interested in reviewing and _testing_ this series?
> > > 
> > > Thank you
> > > Marc
> > 
> > Hi Marc,
> > 
> > I will take a look tomorrow morning and run test on Mellanox NICs
> > (ConnectX 3 and 4).
> > 
> > I do not have access to the others NICs, if those who have can do
> > it, could be really great.
> > 
> > Regards,
> 
> It works as expected with Mellanox NICs.
> 
> Regards,
> 
> -- 
> Nélio Laranjeiro
> 6WIND

Tested-by: Nelio Laranjeiro <nelio.laranjeiro@6wind.com>

- OS/Kernel: Debian 8/3.16.0-4-amd64
- GCC: gcc (Debian 4.9.2-10) 4.9.2
- CPU: Intel(R) Xeon(R) CPU E5-2697 v2 @ 2.70GHz
- MLNX OFED: 3.2-2.0.0.0
- NIC: ConnectX 4 100G

- OS/Kernel: Debian 7/3.16.0-0.bpo.4-amd64
- GCC: gcc (Debian 4.7.2-5) 4.7.2
- CPU: Intel(R) Xeon(R) CPU E5-2648L 0 @ 1.80GHz
- MLNX OFED: 3.2-2.0.0.0
- NIC: ConnectX 3 Pro


1. Link displayed at the correct negotiated speed:
   - 40Gbps for ConnectX3 Pro
   - 100Gbps for ConnectX4 100G
   - 40Gbps for ConnectX4 100G on a 40G link.

2. Configuring speed:
   - Not supported yet for Mellanox as expected.

-- 
Nélio Laranjeiro
6WIND

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

* Re: [PATCH v9 3/4] ethdev: redesign link speed config API
  2016-03-09  8:45           ` Nélio Laranjeiro
@ 2016-03-09 10:09             ` Marc
  2016-03-09 10:20               ` Nélio Laranjeiro
  0 siblings, 1 reply; 167+ messages in thread
From: Marc @ 2016-03-09 10:09 UTC (permalink / raw)
  To: Nélio Laranjeiro; +Cc: dev

On 9 March 2016 at 09:45, Nélio Laranjeiro <nelio.laranjeiro@6wind.com>
wrote:

> Hi Marc,
>
> A small remark bellow.
>
> On Tue, Mar 01, 2016 at 01:45:50AM +0100, Marc Sune wrote:
> > This patch redesigns the API to set the link speed/s configure
> > for an ethernet port. Specifically:
> >
> > - it allows to define a set of advertised speeds for
> >   auto-negociation.
> > - it allows to disable link auto-negociation (single fixed speed).
> > - default: auto-negociate all supported speeds.
> >
> > Other changes:
> >
> > * Added utility MACROs ETH_SPEED_NUM_XXX with the numeric
> >   values of all supported link speeds, in Mbps.
> > * Converted link_speed to uint32_t to accomodate 100G speeds
> >   and beyond (bug).
> > * Added autoneg flag in struct rte_eth_link to indicate if
> >   link speed was a result of auto-negociation or was fixed
> >   by configuration.
> > * Added utility function to convert numeric speeds to bitmap
> >   fields.
> > * Added rte_eth_speed_to_bm_flag() to version map.
> >
> > Signed-off-by: Marc Sune <marcdevel@gmail.com>
> > ---
> >  app/test-pipeline/init.c                  |   2 +-
> >  app/test-pmd/cmdline.c                    | 124
> +++++++++++++++---------------
> >  app/test-pmd/config.c                     |   4 +-
> >  app/test/virtual_pmd.c                    |   4 +-
> >  drivers/net/af_packet/rte_eth_af_packet.c |   5 +-
> >  drivers/net/bnx2x/bnx2x_ethdev.c          |   8 +-
> >  drivers/net/bonding/rte_eth_bond_8023ad.c |  14 ++--
> >  drivers/net/cxgbe/base/t4_hw.c            |   8 +-
> >  drivers/net/cxgbe/cxgbe_ethdev.c          |   2 +-
> >  drivers/net/e1000/em_ethdev.c             | 116
> ++++++++++++++--------------
> >  drivers/net/e1000/igb_ethdev.c            | 111
> +++++++++++++-------------
> >  drivers/net/fm10k/fm10k_ethdev.c          |   8 +-
> >  drivers/net/i40e/i40e_ethdev.c            |  73 +++++++++---------
> >  drivers/net/i40e/i40e_ethdev_vf.c         |  11 +--
> >  drivers/net/ixgbe/ixgbe_ethdev.c          |  78 ++++++++-----------
> >  drivers/net/mlx4/mlx4.c                   |   6 +-
> >  drivers/net/mlx5/mlx5_ethdev.c            |  10 +--
> >  drivers/net/mpipe/mpipe_tilegx.c          |   6 +-
> >  drivers/net/nfp/nfp_net.c                 |   4 +-
> >  drivers/net/null/rte_eth_null.c           |   5 +-
> >  drivers/net/pcap/rte_eth_pcap.c           |   9 ++-
> >  drivers/net/ring/rte_eth_ring.c           |   5 +-
> >  drivers/net/virtio/virtio_ethdev.c        |   2 +-
> >  drivers/net/virtio/virtio_ethdev.h        |   2 -
> >  drivers/net/vmxnet3/vmxnet3_ethdev.c      |   5 +-
> >  drivers/net/xenvirt/rte_eth_xenvirt.c     |   5 +-
> >  examples/ip_pipeline/config_parse.c       |   3 +-
> >  lib/librte_ether/rte_ethdev.c             |  49 ++++++++++++
> >  lib/librte_ether/rte_ethdev.h             | 113
> +++++++++++++++++----------
> >  lib/librte_ether/rte_ether_version.map    |   6 ++
> >  30 files changed, 448 insertions(+), 350 deletions(-)
> >
> > diff --git a/app/test-pipeline/init.c b/app/test-pipeline/init.c
> > index db2196b..6a69fe2 100644
> > --- a/app/test-pipeline/init.c
> > +++ b/app/test-pipeline/init.c
> > @@ -200,7 +200,7 @@ app_ports_check_link(void)
> >               port = (uint8_t) app.ports[i];
> >               memset(&link, 0, sizeof(link));
> >               rte_eth_link_get_nowait(port, &link);
> > -             RTE_LOG(INFO, USER1, "Port %u (%u Gbps) %s\n",
> > +             RTE_LOG(INFO, USER1, "Port %u (%d Gbps) %s\n",
> >                       port,
> >                       link.link_speed / 1000,
> >                       link.link_status ? "UP" : "DOWN");
> > diff --git a/app/test-pmd/cmdline.c b/app/test-pmd/cmdline.c
> > index 52e9f5f..57ad25f 100644
> > --- a/app/test-pmd/cmdline.c
> > +++ b/app/test-pmd/cmdline.c
> > @@ -956,14 +956,65 @@ struct cmd_config_speed_all {
> >       cmdline_fixed_string_t value2;
> >  };
> >
> > +static int
> > +parse_and_check_speed_duplex(char *value1, char *value2, uint32_t
> *link_speed)
>
> "value" variables should have the more friendly name, we need to read the
> code to understand what is value1 and value2.
>
>
Hello,

Ok, but note that the entire source code of cmdline.c uses value1 and
value2 to reference speed and duplex mode. This is not something I
introduced in this patch.

Marc


> >[...]
>
> --
> Nélio Laranjeiro
> 6WIND
>

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

* Re: [PATCH v9 3/4] ethdev: redesign link speed config API
  2016-03-09 10:09             ` Marc
@ 2016-03-09 10:20               ` Nélio Laranjeiro
  0 siblings, 0 replies; 167+ messages in thread
From: Nélio Laranjeiro @ 2016-03-09 10:20 UTC (permalink / raw)
  To: Marc; +Cc: dev

On Wed, Mar 09, 2016 at 11:09:55AM +0100, Marc wrote:
>    On 9 March 2016 at 09:45, Nélio Laranjeiro <[1]nelio.laranjeiro@6wind.com>
>    wrote:
> 
>      Hi Marc,
> 
>      A small remark bellow.
>      On Tue, Mar 01, 2016 at 01:45:50AM +0100, Marc Sune wrote:
>      > This patch redesigns the API to set the link speed/s configure
>      > for an ethernet port. Specifically:
>      >
>      > - it allows to define a set of advertised speeds for
>      >   auto-negociation.
>      > - it allows to disable link auto-negociation (single fixed speed).
>      > - default: auto-negociate all supported speeds.
>      >
>      > Other changes:
>      >
>      > * Added utility MACROs ETH_SPEED_NUM_XXX with the numeric
>      >   values of all supported link speeds, in Mbps.
>      > * Converted link_speed to uint32_t to accomodate 100G speeds
>      >   and beyond (bug).
>      > * Added autoneg flag in struct rte_eth_link to indicate if
>      >   link speed was a result of auto-negociation or was fixed
>      >   by configuration.
>      > * Added utility function to convert numeric speeds to bitmap
>      >   fields.
>      > * Added rte_eth_speed_to_bm_flag() to version map.
>      >
>      > Signed-off-by: Marc Sune <[2]marcdevel@gmail.com>
>      > ---
>      >  app/test-pipeline/init.c                  |   2 +-
>      >  app/test-pmd/cmdline.c                    | 124
>      +++++++++++++++---------------
>      >  app/test-pmd/config.c                     |   4 +-
>      >  app/test/virtual_pmd.c                    |   4 +-
>      >  drivers/net/af_packet/rte_eth_af_packet.c |   5 +-
>      >  drivers/net/bnx2x/bnx2x_ethdev.c          |   8 +-
>      >  drivers/net/bonding/rte_eth_bond_8023ad.c |  14 ++--
>      >  drivers/net/cxgbe/base/t4_hw.c            |   8 +-
>      >  drivers/net/cxgbe/cxgbe_ethdev.c          |   2 +-
>      >  drivers/net/e1000/em_ethdev.c             | 116
>      ++++++++++++++--------------
>      >  drivers/net/e1000/igb_ethdev.c            | 111
>      +++++++++++++-------------
>      >  drivers/net/fm10k/fm10k_ethdev.c          |   8 +-
>      >  drivers/net/i40e/i40e_ethdev.c            |  73 +++++++++---------
>      >  drivers/net/i40e/i40e_ethdev_vf.c         |  11 +--
>      >  drivers/net/ixgbe/ixgbe_ethdev.c          |  78 ++++++++-----------
>      >  drivers/net/mlx4/mlx4.c                   |   6 +-
>      >  drivers/net/mlx5/mlx5_ethdev.c            |  10 +--
>      >  drivers/net/mpipe/mpipe_tilegx.c          |   6 +-
>      >  drivers/net/nfp/nfp_net.c                 |   4 +-
>      >  drivers/net/null/rte_eth_null.c           |   5 +-
>      >  drivers/net/pcap/rte_eth_pcap.c           |   9 ++-
>      >  drivers/net/ring/rte_eth_ring.c           |   5 +-
>      >  drivers/net/virtio/virtio_ethdev.c        |   2 +-
>      >  drivers/net/virtio/virtio_ethdev.h        |   2 -
>      >  drivers/net/vmxnet3/vmxnet3_ethdev.c      |   5 +-
>      >  drivers/net/xenvirt/rte_eth_xenvirt.c     |   5 +-
>      >  examples/ip_pipeline/config_parse.c       |   3 +-
>      >  lib/librte_ether/rte_ethdev.c             |  49 ++++++++++++
>      >  lib/librte_ether/rte_ethdev.h             | 113
>      +++++++++++++++++----------
>      >  lib/librte_ether/rte_ether_version.map    |   6 ++
>      >  30 files changed, 448 insertions(+), 350 deletions(-)
>      >
>      > diff --git a/app/test-pipeline/init.c b/app/test-pipeline/init.c
>      > index db2196b..6a69fe2 100644
>      > --- a/app/test-pipeline/init.c
>      > +++ b/app/test-pipeline/init.c
>      > @@ -200,7 +200,7 @@ app_ports_check_link(void)
>      >               port = (uint8_t) app.ports[i];
>      >               memset(&link, 0, sizeof(link));
>      >               rte_eth_link_get_nowait(port, &link);
>      > -             RTE_LOG(INFO, USER1, "Port %u (%u Gbps) %s\n",
>      > +             RTE_LOG(INFO, USER1, "Port %u (%d Gbps) %s\n",
>      >                       port,
>      >                       link.link_speed / 1000,
>      >                       link.link_status ? "UP" : "DOWN");
>      > diff --git a/app/test-pmd/cmdline.c b/app/test-pmd/cmdline.c
>      > index 52e9f5f..57ad25f 100644
>      > --- a/app/test-pmd/cmdline.c
>      > +++ b/app/test-pmd/cmdline.c
>      > @@ -956,14 +956,65 @@ struct cmd_config_speed_all {
>      >       cmdline_fixed_string_t value2;
>      >  };
>      >
>      > +static int
>      > +parse_and_check_speed_duplex(char *value1, char *value2, uint32_t
>      *link_speed)
> 
>      "value" variables should have the more friendly name, we need to read
>      the
>      code to understand what is value1 and value2.
> 
>    Hello,
>    Ok, but note that the entire source code of cmdline.c uses value1 and
>    value2 to reference speed and duplex mode. This is not something I
>    introduced in this patch.
>    Marc

Ok, I did not look in the whole file only in your patch.  You kept
the logic of the file, it is good for me.

>      >[...]
>      --
>      Nélio Laranjeiro
>      6WIND
> 
> References
> 
>    Visible links
>    1. mailto:nelio.laranjeiro@6wind.com
>    2. mailto:marcdevel@gmail.com

-- 
Nélio Laranjeiro
6WIND

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

* Re: [PATCH v9 0/4] ethdev: add speed capabilities and refactor link API
  2016-03-09 10:09               ` Nélio Laranjeiro
@ 2016-03-09 20:57                 ` Marc
  0 siblings, 0 replies; 167+ messages in thread
From: Marc @ 2016-03-09 20:57 UTC (permalink / raw)
  To: Nélio Laranjeiro; +Cc: dev

On 9 March 2016 at 11:09, Nélio Laranjeiro <nelio.laranjeiro@6wind.com>
wrote:

> On Wed, Mar 09, 2016 at 10:29:38AM +0100, Nélio Laranjeiro wrote:
> > On Tue, Mar 08, 2016 at 05:53:05PM +0100, Nélio Laranjeiro wrote:
> > > On Tue, Mar 08, 2016 at 04:00:29PM +0100, Marc Sune wrote:
> > > > 2016-03-01 1:45 GMT+01:00 Marc Sune <marcdevel@gmail.com>:
> > > >
> > > > > The current rte_eth_dev_info abstraction does not provide any
> mechanism to
> > > > > get the supported speed(s) of an ethdev.
> > > > >
> > > > > For some drivers (e.g. ixgbe), an educated guess could be done
> based on the
> > > > > driver's name (driver_name in rte_eth_dev_info), see:
> > > > >
> > > > > http://dpdk.org/ml/archives/dev/2013-August/000412.html
> > > > >
> > > > > However, i) doing string comparisons is annoying, and can silently
> > > > > break existing applications if PMDs change their names ii) it does
> not
> > > > > provide all the supported capabilities of the ethdev iii) for some
> drivers
> > > > > it
> > > > > is impossible determine correctly the (max) speed by the
> application
> > > > > (e.g. in i40, distinguish between XL710 and X710).
> > > > >
> > > > > In addition, the link APIs do not allow to define a set of
> advertised link
> > > > > speeds for autonegociation.
> > > > >
> > > > > This series of patches adds the following capabilities:
> > > > >
> > > > > * speed_capa bitmap in rte_eth_dev_info, which is filled by the
> PMDs
> > > > >   according to the physical device capabilities.
> > > > > * refactors link API in ethdev to allow the definition of the
> advertised
> > > > >   link speeds, fix speed (no auto-negociation) or advertise all
> supported
> > > > >   speeds (default).
> > > > >
> > > > > WARNING: this patch series, specifically 3/4, is NOT tested for
> most of the
> > > > > PMDs, due to the lack of hardware. Only generic EM is tested (VM).
> > > > > Reviewing
> > > > > and testing required by PMD maintainers.
> > > > >
> > > > > * * * * *
> > > > >
> > > > > v2: rebase, converted speed_capa into 32 bits bitmap, fixed
> alignment
> > > > >     (checkpatch).
> > > > >
> > > > > v3: rebase to v2.1. unified ETH_LINK_SPEED and ETH_SPEED_CAP into
> > > > > ETH_SPEED.
> > > > >     Converted field speed in struct rte_eth_conf to speed, to
> allow a
> > > > > bitmap
> > > > >     for defining the announced speeds, as suggested M. Brorup.
> Fixed
> > > > > spelling
> > > > >     issues.
> > > > >
> > > > > v4: fixed errata in the documentation of field speeds of
> rte_eth_conf, and
> > > > >     commit 1/2 message. rebased to v2.1.0. v3 was incorrectly
> based on
> > > > >     ~2.1.0-rc1.
> > > > >
> > > > > v5: revert to v2 speed capabilities patch. Fixed MLX4 speed
> capabilities
> > > > >     (thanks N. Laranjeiro). Refactored link speed API to allow
> setting
> > > > >     advertised speeds (3/4). Added NO_AUTONEG option to
> explicitely disable
> > > > >     auto-negociation. Updated 2.2 rel. notes (4/4). Rebased to
> current
> > > > > HEAD.
> > > > >
> > > > > v6: Move link_duplex to be part of bitfield. Fixed i40 autoneg
> flag link
> > > > >     update code. Added rte_eth_speed_to_bm_flag() to .map file.
> Fixed other
> > > > >     spelling issues. Rebased to current HEAD.
> > > > >
> > > > > v7: Rebased to current HEAD. Moved documentation to v2.3. Still
> needs
> > > > > testing
> > > > >     from PMD maintainers.
> > > > >
> > > > > v8: Rebased to current HEAD. Modified em driver impl. to not touch
> base
> > > > > files.
> > > > >     Merged patch 5 into 3 (map file). Changed numeric speed to a
> 64 bit
> > > > > value.
> > > > >     Filled-in speed capabilities for drivers bnx2x, cxgbe, mlx5
> and nfp in
> > > > >     addition to the ones of previous patch sets.
> > > > >
> > > > > v9: rebased to current HEAD. Reverted numeric speed to 32 bit in
> struct
> > > > >     rte_eth_link (no atomic link get > 64bit). Fixed mlx5 driver
> > > > > compilation
> > > > >     and link speeds. Moved documentation to release_16_04.rst and
> fixed
> > > > > several
> > > > >     issues. Upgrade NIC notes with speed capabilities.
> > > > >
> > > >
> > > > Anyone interested in reviewing and _testing_ this series?
> > > >
> > > > Thank you
> > > > Marc
> > >
> > > Hi Marc,
> > >
> > > I will take a look tomorrow morning and run test on Mellanox NICs
> > > (ConnectX 3 and 4).
> > >
> > > I do not have access to the others NICs, if those who have can do
> > > it, could be really great.
> > >
> > > Regards,
> >
> > It works as expected with Mellanox NICs.
> >
> > Regards,
> >
> > --
> > Nélio Laranjeiro
> > 6WIND
>
> Tested-by: Nelio Laranjeiro <nelio.laranjeiro@6wind.com>
>
> - OS/Kernel: Debian 8/3.16.0-4-amd64
> - GCC: gcc (Debian 4.9.2-10) 4.9.2
> - CPU: Intel(R) Xeon(R) CPU E5-2697 v2 @ 2.70GHz
> - MLNX OFED: 3.2-2.0.0.0
> - NIC: ConnectX 4 100G
>
> - OS/Kernel: Debian 7/3.16.0-0.bpo.4-amd64
> - GCC: gcc (Debian 4.7.2-5) 4.7.2
> - CPU: Intel(R) Xeon(R) CPU E5-2648L 0 @ 1.80GHz
> - MLNX OFED: 3.2-2.0.0.0
> - NIC: ConnectX 3 Pro
>
>
> 1. Link displayed at the correct negotiated speed:
>    - 40Gbps for ConnectX3 Pro
>    - 100Gbps for ConnectX4 100G
>    - 40Gbps for ConnectX4 100G on a 40G link.
>
> 2. Configuring speed:
>    - Not supported yet for Mellanox as expected.
>

Thanks Neilo,

It would be good that at least i40 and e1000/ixgbe is tested and acked,
specially for the speed config part. Some more reviews would also help.

Marc




>
> --
> Nélio Laranjeiro
> 6WIND
>

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

* [PATCH v10 0/8] ethdev: 100G and link speed API refactoring
  2016-03-01  0:45       ` [PATCH v9 0/4] ethdev: add speed capabilities and refactor link API Marc Sune
                           ` (4 preceding siblings ...)
  2016-03-08 15:00         ` [PATCH v9 0/4] ethdev: add speed capabilities and refactor link API Marc Sune
@ 2016-03-14 21:55         ` Thomas Monjalon
  2016-03-14 21:55           ` [PATCH v10 1/8] ethdev: use constants for link state Thomas Monjalon
                             ` (11 more replies)
  5 siblings, 12 replies; 167+ messages in thread
From: Thomas Monjalon @ 2016-03-14 21:55 UTC (permalink / raw)
  To: marcdevel, bruce.richardson, declan.doherty, konstantin.ananyev,
	wenzhuo.lu, helin.zhang, jing.d.chen, harish.patil,
	rahul.lakkireddy, johndale, vido, adrien.mazarguil,
	alejandro.lucero
  Cc: dev

Re-spin of the Marc's patchset.
The first version was sent 10 months ago!
There are still too few tests and reviews but it is now time to move
forward with this rework.
Some issues were remaining in v9 and were difficult to see because it
was mainly one big patch. That's why I've split it in several steps
and fixed/reworked some pieces.
There will be an exception to integrate this feature in 16.04-rc2.
Please test and review shortly, thanks!

--------

This series of patches adds the following capabilities:

* speed_capa bitmap in rte_eth_dev_info, which is filled by the PMDs
  according to the physical device capabilities.
* refactors link API in ethdev to allow the definition of the advertised
  link speeds, fix speed (no auto-negociation) or advertise all supported
  speeds (default).

WARNING: this patch series, specifically the patch 6/8, is NOT tested for
most of the drivers.
Reviewing and testing are required by PMD maintainers.

--------

Marc Sune (6):
  ethdev: use constants for link duplex
  app/testpmd: move speed and duplex parsing in a function
  ethdev: rename link speed constants
  ethdev: add speed capabilities
  ethdev: redesign link speed config
  ethdev: convert speed number to bitmap flag

Thomas Monjalon (2):
  ethdev: use constants for link state
  ethdev: add 100G link speed

v10:
    - rebase
    - rework release notes
    - rearrange patch splitting
    - fix doxygen comments
    - fix typos
    - removed log format of link.link_speed as %d (keep %u)
    - complete ETH_LINK_[DOWN/UP] replacement from 0/1
    - change ETH_LINK_SPEED_AUTONEG to 1
    - replace ETH_LINK_SPEED_NEG by ETH_LINK_SPEED_AUTONEG (1)
    - replace ETH_LINK_SPEED_NO_AUTONEG by ETH_LINK_SPEED_FIXED (0)
    - rework rte_eth_speed_to_bm_flag to rte_eth_speed_bitflag
    - complete 100G support in testpmd

v9: rebased to current HEAD. Reverted numeric speed to 32 bit in struct
    rte_eth_link (no atomic link get > 64bit). Fixed mlx5 driver compilation
    and link speeds. Moved documentation to release_16_04.rst and fixed several
    issues. Upgrade NIC notes with speed capabilities.

v8: Rebased to current HEAD. Modified em driver impl. to not touch base files.
    Merged patch 5 into 3 (map file). Changed numeric speed to a 64 bit value.
    Filled-in speed capabilities for drivers bnx2x, cxgbe, mlx5 and nfp in
    addition to the ones of previous patch sets.

v7: Rebased to current HEAD. Moved documentation to v2.3. Still needs testing
    from PMD maintainers.

v6: Move link_duplex to be part of bitfield. Fixed i40 autoneg flag link
    update code. Added rte_eth_speed_to_bm_flag() to .map file. Fixed other
    spelling issues. Rebased to current HEAD.

v5: revert to v2 speed capabilities patch. Fixed MLX4 speed capabilities
    (thanks N. Laranjeiro). Refactored link speed API to allow setting
    advertised speeds (3/4). Added NO_AUTONEG option to explicitely disable
    auto-negociation. Updated 2.2 rel. notes (4/4). Rebased to current HEAD.

v4: fixed errata in the documentation of field speeds of rte_eth_conf, and
    commit 1/2 message. rebased to v2.1.0. v3 was incorrectly based on
    ~2.1.0-rc1.

v3: rebase to v2.1. unified ETH_LINK_SPEED and ETH_SPEED_CAP into ETH_SPEED.
    Converted field speed in struct rte_eth_conf to speed, to allow a bitmap
    for defining the announced speeds, as suggested M. Brorup. Fixed spelling
    issues.

v2: rebase, converted speed_capa into 32 bits bitmap, fixed alignment
    (checkpatch).


 app/test-pipeline/init.c                           |   2 +-
 app/test-pmd/cmdline.c                             | 125 ++++++++++-----------
 app/test-pmd/testpmd.c                             |   2 +-
 app/test/test_pmd_perf.c                           |   2 +-
 app/test/virtual_pmd.c                             |   8 +-
 doc/guides/nics/overview.rst                       |   1 +
 doc/guides/rel_notes/release_16_04.rst             |  22 ++++
 doc/guides/testpmd_app_ug/testpmd_funcs.rst        |   2 +-
 drivers/net/af_packet/rte_eth_af_packet.c          |   9 +-
 drivers/net/bnx2x/bnx2x_ethdev.c                   |   7 +-
 drivers/net/bnx2x/elink.c                          |   2 +-
 drivers/net/bonding/rte_eth_bond_8023ad.c          |  14 +--
 drivers/net/bonding/rte_eth_bond_api.c             |   4 +-
 drivers/net/bonding/rte_eth_bond_pmd.c             |  12 +-
 drivers/net/cxgbe/base/t4_hw.c                     |   8 +-
 drivers/net/cxgbe/cxgbe_ethdev.c                   |   1 +
 drivers/net/e1000/em_ethdev.c                      | 111 +++++++++---------
 drivers/net/e1000/igb_ethdev.c                     | 104 +++++++++--------
 drivers/net/fm10k/fm10k_ethdev.c                   |   6 +-
 drivers/net/i40e/i40e_ethdev.c                     |  76 +++++++------
 drivers/net/i40e/i40e_ethdev_vf.c                  |  11 +-
 drivers/net/ixgbe/ixgbe_ethdev.c                   |  76 ++++++-------
 drivers/net/mlx4/mlx4.c                            |   4 +
 drivers/net/mlx5/mlx5_ethdev.c                     |   3 +
 drivers/net/mpipe/mpipe_tilegx.c                   |  18 +--
 drivers/net/nfp/nfp_net.c                          |   6 +-
 drivers/net/null/rte_eth_null.c                    |   9 +-
 drivers/net/pcap/rte_eth_pcap.c                    |   9 +-
 drivers/net/ring/rte_eth_ring.c                    |  13 ++-
 drivers/net/szedata2/rte_eth_szedata2.c            |   7 +-
 drivers/net/virtio/virtio_ethdev.c                 |   8 +-
 drivers/net/virtio/virtio_ethdev.h                 |   2 -
 drivers/net/vmxnet3/vmxnet3_ethdev.c               |   5 +-
 drivers/net/xenvirt/rte_eth_xenvirt.c              |   9 +-
 examples/exception_path/main.c                     |   2 +-
 examples/ip_fragmentation/main.c                   |   2 +-
 examples/ip_pipeline/config_parse.c                |   3 +-
 examples/ip_pipeline/init.c                        |   2 +-
 examples/ip_reassembly/main.c                      |   2 +-
 examples/ipsec-secgw/ipsec-secgw.c                 |   2 +-
 examples/ipv4_multicast/main.c                     |   2 +-
 examples/kni/main.c                                |   2 +-
 examples/l2fwd-crypto/main.c                       |   2 +-
 examples/l2fwd-ivshmem/host/host.c                 |   2 +-
 examples/l2fwd-jobstats/main.c                     |   2 +-
 examples/l2fwd-keepalive/main.c                    |   2 +-
 examples/l2fwd/main.c                              |   2 +-
 examples/l3fwd-acl/main.c                          |   2 +-
 examples/l3fwd-power/main.c                        |   2 +-
 examples/l3fwd/main.c                              |   2 +-
 examples/link_status_interrupt/main.c              |   2 +-
 examples/load_balancer/init.c                      |   2 +-
 .../client_server_mp/mp_server/init.c              |   2 +-
 examples/multi_process/l2fwd_fork/main.c           |   2 +-
 examples/multi_process/symmetric_mp/main.c         |   2 +-
 examples/performance-thread/l3fwd-thread/main.c    |   2 +-
 lib/librte_ether/rte_ethdev.c                      |  33 ++++++
 lib/librte_ether/rte_ethdev.h                      |  91 +++++++++++----
 lib/librte_ether/rte_ether_version.map             |   1 +
 59 files changed, 503 insertions(+), 365 deletions(-)

-- 
2.7.0

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

* [PATCH v10 1/8] ethdev: use constants for link state
  2016-03-14 21:55         ` [PATCH v10 0/8] ethdev: 100G and link speed API refactoring Thomas Monjalon
@ 2016-03-14 21:55           ` Thomas Monjalon
  2016-03-15  1:26             ` Zhang, Helin
  2016-03-14 21:55           ` [PATCH v10 2/8] ethdev: use constants for link duplex Thomas Monjalon
                             ` (10 subsequent siblings)
  11 siblings, 1 reply; 167+ messages in thread
From: Thomas Monjalon @ 2016-03-14 21:55 UTC (permalink / raw)
  To: marcdevel, bruce.richardson, declan.doherty, konstantin.ananyev,
	wenzhuo.lu, helin.zhang, jing.d.chen, harish.patil,
	rahul.lakkireddy, johndale, vido, adrien.mazarguil,
	alejandro.lucero
  Cc: dev

Define and use ETH_LINK_UP and ETH_LINK_DOWN where appropriate.

Signed-off-by: Marc Sune <marcdevel@gmail.com>
Signed-off-by: Thomas Monjalon <thomas.monjalon@6wind.com>
---
 app/test-pipeline/init.c                                 |  2 +-
 app/test-pmd/testpmd.c                                   |  2 +-
 app/test/test_pmd_perf.c                                 |  2 +-
 app/test/virtual_pmd.c                                   |  6 +++---
 drivers/net/af_packet/rte_eth_af_packet.c                |  6 +++---
 drivers/net/bnx2x/bnx2x_ethdev.c                         |  2 +-
 drivers/net/bnx2x/elink.c                                |  2 +-
 drivers/net/bonding/rte_eth_bond_api.c                   |  4 ++--
 drivers/net/bonding/rte_eth_bond_pmd.c                   | 12 ++++++------
 drivers/net/e1000/em_ethdev.c                            |  6 +++---
 drivers/net/e1000/igb_ethdev.c                           |  4 ++--
 drivers/net/fm10k/fm10k_ethdev.c                         |  2 +-
 drivers/net/i40e/i40e_ethdev_vf.c                        |  2 +-
 drivers/net/ixgbe/ixgbe_ethdev.c                         |  4 ++--
 drivers/net/mpipe/mpipe_tilegx.c                         | 12 ++++++------
 drivers/net/nfp/nfp_net.c                                |  2 +-
 drivers/net/null/rte_eth_null.c                          |  6 +++---
 drivers/net/pcap/rte_eth_pcap.c                          |  6 +++---
 drivers/net/ring/rte_eth_ring.c                          | 10 +++++-----
 drivers/net/szedata2/rte_eth_szedata2.c                  |  6 +++---
 drivers/net/virtio/virtio_ethdev.c                       |  6 +++---
 drivers/net/vmxnet3/vmxnet3_ethdev.c                     |  2 +-
 drivers/net/xenvirt/rte_eth_xenvirt.c                    |  6 +++---
 examples/exception_path/main.c                           |  2 +-
 examples/ip_fragmentation/main.c                         |  2 +-
 examples/ip_pipeline/init.c                              |  2 +-
 examples/ip_reassembly/main.c                            |  2 +-
 examples/ipsec-secgw/ipsec-secgw.c                       |  2 +-
 examples/ipv4_multicast/main.c                           |  2 +-
 examples/kni/main.c                                      |  2 +-
 examples/l2fwd-crypto/main.c                             |  2 +-
 examples/l2fwd-ivshmem/host/host.c                       |  2 +-
 examples/l2fwd-jobstats/main.c                           |  2 +-
 examples/l2fwd-keepalive/main.c                          |  2 +-
 examples/l2fwd/main.c                                    |  2 +-
 examples/l3fwd-acl/main.c                                |  2 +-
 examples/l3fwd-power/main.c                              |  2 +-
 examples/l3fwd/main.c                                    |  2 +-
 examples/link_status_interrupt/main.c                    |  2 +-
 examples/load_balancer/init.c                            |  2 +-
 examples/multi_process/client_server_mp/mp_server/init.c |  2 +-
 examples/multi_process/l2fwd_fork/main.c                 |  2 +-
 examples/multi_process/symmetric_mp/main.c               |  2 +-
 examples/performance-thread/l3fwd-thread/main.c          |  2 +-
 lib/librte_ether/rte_ethdev.h                            |  5 ++++-
 45 files changed, 81 insertions(+), 78 deletions(-)

diff --git a/app/test-pipeline/init.c b/app/test-pipeline/init.c
index db2196b..aef082f 100644
--- a/app/test-pipeline/init.c
+++ b/app/test-pipeline/init.c
@@ -205,7 +205,7 @@ app_ports_check_link(void)
 			link.link_speed / 1000,
 			link.link_status ? "UP" : "DOWN");
 
-		if (link.link_status == 0)
+		if (link.link_status == ETH_LINK_DOWN)
 			all_ports_up = 0;
 	}
 
diff --git a/app/test-pmd/testpmd.c b/app/test-pmd/testpmd.c
index 38b9051..f713f39 100644
--- a/app/test-pmd/testpmd.c
+++ b/app/test-pmd/testpmd.c
@@ -1641,7 +1641,7 @@ check_all_ports_link_status(uint32_t port_mask)
 				continue;
 			}
 			/* clear all_ports_up flag if any link down */
-			if (link.link_status == 0) {
+			if (link.link_status == ETH_LINK_DOWN) {
 				all_ports_up = 0;
 				break;
 			}
diff --git a/app/test/test_pmd_perf.c b/app/test/test_pmd_perf.c
index 48e16c9..59803f7 100644
--- a/app/test/test_pmd_perf.c
+++ b/app/test/test_pmd_perf.c
@@ -192,7 +192,7 @@ check_all_ports_link_status(uint8_t port_num, uint32_t port_mask)
 				continue;
 			}
 			/* clear all_ports_up flag if any link down */
-			if (link.link_status == 0) {
+			if (link.link_status == ETH_LINK_DOWN) {
 				all_ports_up = 0;
 				break;
 			}
diff --git a/app/test/virtual_pmd.c b/app/test/virtual_pmd.c
index a538c8a..b1d40d7 100644
--- a/app/test/virtual_pmd.c
+++ b/app/test/virtual_pmd.c
@@ -79,7 +79,7 @@ static void  virtual_ethdev_stop(struct rte_eth_dev *eth_dev __rte_unused)
 	void *pkt = NULL;
 	struct virtual_ethdev_private *prv = eth_dev->data->dev_private;
 
-	eth_dev->data->dev_link.link_status = 0;
+	eth_dev->data->dev_link.link_status = ETH_LINK_DOWN;
 	eth_dev->data->dev_started = 0;
 	while (rte_ring_dequeue(prv->rx_queue, &pkt) != -ENOENT)
 		rte_pktmbuf_free(pkt);
@@ -199,7 +199,7 @@ virtual_ethdev_link_update_success(struct rte_eth_dev *bonded_eth_dev,
 		int wait_to_complete __rte_unused)
 {
 	if (!bonded_eth_dev->data->dev_started)
-		bonded_eth_dev->data->dev_link.link_status = 0;
+		bonded_eth_dev->data->dev_link.link_status = ETH_LINK_DOWN;
 
 	return 0;
 }
@@ -603,7 +603,7 @@ virtual_ethdev_create(const char *name, struct ether_addr *mac_addr,
 
 	TAILQ_INIT(&(eth_dev->link_intr_cbs));
 
-	eth_dev->data->dev_link.link_status = 0;
+	eth_dev->data->dev_link.link_status = ETH_LINK_DOWN;
 	eth_dev->data->dev_link.link_speed = ETH_LINK_SPEED_10000;
 	eth_dev->data->dev_link.link_duplex = ETH_LINK_FULL_DUPLEX;
 
diff --git a/drivers/net/af_packet/rte_eth_af_packet.c b/drivers/net/af_packet/rte_eth_af_packet.c
index 767f36b..24f909f 100644
--- a/drivers/net/af_packet/rte_eth_af_packet.c
+++ b/drivers/net/af_packet/rte_eth_af_packet.c
@@ -118,7 +118,7 @@ static const char *drivername = "AF_PACKET PMD";
 static struct rte_eth_link pmd_link = {
 	.link_speed = 10000,
 	.link_duplex = ETH_LINK_FULL_DUPLEX,
-	.link_status = 0
+	.link_status = ETH_LINK_DOWN,
 };
 
 static uint16_t
@@ -234,7 +234,7 @@ eth_af_packet_tx(void *queue, struct rte_mbuf **bufs, uint16_t nb_pkts)
 static int
 eth_dev_start(struct rte_eth_dev *dev)
 {
-	dev->data->dev_link.link_status = 1;
+	dev->data->dev_link.link_status = ETH_LINK_UP;
 	return 0;
 }
 
@@ -257,7 +257,7 @@ eth_dev_stop(struct rte_eth_dev *dev)
 			close(sockfd);
 	}
 
-	dev->data->dev_link.link_status = 0;
+	dev->data->dev_link.link_status = ETH_LINK_DOWN;
 }
 
 static int
diff --git a/drivers/net/bnx2x/bnx2x_ethdev.c b/drivers/net/bnx2x/bnx2x_ethdev.c
index 69df02e..f109900 100644
--- a/drivers/net/bnx2x/bnx2x_ethdev.c
+++ b/drivers/net/bnx2x/bnx2x_ethdev.c
@@ -286,7 +286,7 @@ bnx2xvf_dev_link_update(struct rte_eth_dev *dev, __rte_unused int wait_to_comple
 	if (sc->old_bulletin.valid_bitmap & (1 << CHANNEL_DOWN)) {
 		PMD_DRV_LOG(ERR, "PF indicated channel is down."
 				"VF device is no longer operational");
-		dev->data->dev_link.link_status = 0;
+		dev->data->dev_link.link_status = ETH_LINK_DOWN;
 	}
 
 	return old_link_status == dev->data->dev_link.link_status ? -1 : 0;
diff --git a/drivers/net/bnx2x/elink.c b/drivers/net/bnx2x/elink.c
index da2366e..b9149b8 100644
--- a/drivers/net/bnx2x/elink.c
+++ b/drivers/net/bnx2x/elink.c
@@ -6312,7 +6312,7 @@ elink_status_t elink_link_update(struct elink_params * params,
 	for (phy_index = ELINK_INT_PHY; phy_index < params->num_phys;
 	     phy_index++) {
 		phy_vars[phy_index].flow_ctrl = 0;
-		phy_vars[phy_index].link_status = 0;
+		phy_vars[phy_index].link_status = ETH_LINK_DOWN;
 		phy_vars[phy_index].line_speed = 0;
 		phy_vars[phy_index].duplex = DUPLEX_FULL;
 		phy_vars[phy_index].phy_link_up = 0;
diff --git a/drivers/net/bonding/rte_eth_bond_api.c b/drivers/net/bonding/rte_eth_bond_api.c
index 8a000c8..b0ebd35 100644
--- a/drivers/net/bonding/rte_eth_bond_api.c
+++ b/drivers/net/bonding/rte_eth_bond_api.c
@@ -205,7 +205,7 @@ rte_eth_bond_create(const char *name, uint8_t mode, uint8_t socket_id)
 
 	TAILQ_INIT(&(eth_dev->link_intr_cbs));
 
-	eth_dev->data->dev_link.link_status = 0;
+	eth_dev->data->dev_link.link_status = ETH_LINK_DOWN;
 
 	eth_dev->data->mac_addrs = rte_zmalloc_socket(name, ETHER_ADDR_LEN, 0,
 			socket_id);
@@ -427,7 +427,7 @@ __eth_bond_slave_add_lock_free(uint8_t bonded_port_id, uint8_t slave_port_id)
 	if (bonded_eth_dev->data->dev_started) {
 		rte_eth_link_get_nowait(slave_port_id, &link_props);
 
-		 if (link_props.link_status == 1)
+		 if (link_props.link_status == ETH_LINK_UP)
 			activate_slave(bonded_eth_dev, slave_port_id);
 	}
 	return 0;
diff --git a/drivers/net/bonding/rte_eth_bond_pmd.c b/drivers/net/bonding/rte_eth_bond_pmd.c
index b63c886..e63a7d0 100644
--- a/drivers/net/bonding/rte_eth_bond_pmd.c
+++ b/drivers/net/bonding/rte_eth_bond_pmd.c
@@ -1499,7 +1499,7 @@ bond_ethdev_start(struct rte_eth_dev *eth_dev)
 		return -1;
 	}
 
-	eth_dev->data->dev_link.link_status = 0;
+	eth_dev->data->dev_link.link_status = ETH_LINK_DOWN;
 	eth_dev->data->dev_started = 1;
 
 	internals = eth_dev->data->dev_private;
@@ -1616,7 +1616,7 @@ bond_ethdev_stop(struct rte_eth_dev *eth_dev)
 	internals->active_slave_count = 0;
 	internals->link_status_polling_enabled = 0;
 
-	eth_dev->data->dev_link.link_status = 0;
+	eth_dev->data->dev_link.link_status = ETH_LINK_DOWN;
 	eth_dev->data->dev_started = 0;
 }
 
@@ -1782,7 +1782,7 @@ bond_ethdev_link_update(struct rte_eth_dev *bonded_eth_dev,
 
 	if (!bonded_eth_dev->data->dev_started ||
 		internals->active_slave_count == 0) {
-		bonded_eth_dev->data->dev_link.link_status = 0;
+		bonded_eth_dev->data->dev_link.link_status = ETH_LINK_DOWN;
 		return 0;
 	} else {
 		struct rte_eth_dev *slave_eth_dev;
@@ -1793,7 +1793,7 @@ bond_ethdev_link_update(struct rte_eth_dev *bonded_eth_dev,
 
 			(*slave_eth_dev->dev_ops->link_update)(slave_eth_dev,
 					wait_to_complete);
-			if (slave_eth_dev->data->dev_link.link_status == 1) {
+			if (slave_eth_dev->data->dev_link.link_status == ETH_LINK_UP) {
 				link_up = 1;
 				break;
 			}
@@ -1962,7 +1962,7 @@ bond_ethdev_lsc_event_callback(uint8_t port_id, enum rte_eth_event_type type,
 		/* if no active slave ports then set this port to be primary port */
 		if (internals->active_slave_count < 1) {
 			/* If first active slave, then change link status */
-			bonded_eth_dev->data->dev_link.link_status = 1;
+			bonded_eth_dev->data->dev_link.link_status = ETH_LINK_UP;
 			internals->current_primary_port = port_id;
 			lsc_flag = 1;
 
@@ -1990,7 +1990,7 @@ bond_ethdev_lsc_event_callback(uint8_t port_id, enum rte_eth_event_type type,
 		 * link properties */
 		if (internals->active_slave_count < 1) {
 			lsc_flag = 1;
-			bonded_eth_dev->data->dev_link.link_status = 0;
+			bonded_eth_dev->data->dev_link.link_status = ETH_LINK_DOWN;
 
 			link_properties_reset(bonded_eth_dev);
 		}
diff --git a/drivers/net/e1000/em_ethdev.c b/drivers/net/e1000/em_ethdev.c
index 4a843fe..58f9c7a 100644
--- a/drivers/net/e1000/em_ethdev.c
+++ b/drivers/net/e1000/em_ethdev.c
@@ -1073,11 +1073,11 @@ eth_em_link_update(struct rte_eth_dev *dev, int wait_to_complete)
 	if (link_check && (link.link_status == 0)) {
 		hw->mac.ops.get_link_up_info(hw, &link.link_speed,
 			&link.link_duplex);
-		link.link_status = 1;
-	} else if (!link_check && (link.link_status == 1)) {
+		link.link_status = ETH_LINK_UP;
+	} else if (!link_check && (link.link_status == ETH_LINK_UP)) {
 		link.link_speed = 0;
 		link.link_duplex = 0;
-		link.link_status = 0;
+		link.link_status = ETH_LINK_DOWN;
 	}
 	rte_em_dev_atomic_write_link_status(dev, &link);
 
diff --git a/drivers/net/e1000/igb_ethdev.c b/drivers/net/e1000/igb_ethdev.c
index 2581995..614d8cb 100644
--- a/drivers/net/e1000/igb_ethdev.c
+++ b/drivers/net/e1000/igb_ethdev.c
@@ -2021,11 +2021,11 @@ eth_igb_link_update(struct rte_eth_dev *dev, int wait_to_complete)
 	if (link_check) {
 		hw->mac.ops.get_link_up_info(hw, &link.link_speed,
 					  &link.link_duplex);
-		link.link_status = 1;
+		link.link_status = ETH_LINK_UP;
 	} else if (!link_check) {
 		link.link_speed = 0;
 		link.link_duplex = 0;
-		link.link_status = 0;
+		link.link_status = ETH_LINK_DOWN;
 	}
 	rte_igb_dev_atomic_write_link_status(dev, &link);
 
diff --git a/drivers/net/fm10k/fm10k_ethdev.c b/drivers/net/fm10k/fm10k_ethdev.c
index 421266b..378faf2 100644
--- a/drivers/net/fm10k/fm10k_ethdev.c
+++ b/drivers/net/fm10k/fm10k_ethdev.c
@@ -1172,7 +1172,7 @@ fm10k_link_update(struct rte_eth_dev *dev,
 	 * is no 50Gbps Ethernet. */
 	dev->data->dev_link.link_speed  = 0;
 	dev->data->dev_link.link_duplex = ETH_LINK_FULL_DUPLEX;
-	dev->data->dev_link.link_status = 1;
+	dev->data->dev_link.link_status = ETH_LINK_UP;
 
 	return 0;
 }
diff --git a/drivers/net/i40e/i40e_ethdev_vf.c b/drivers/net/i40e/i40e_ethdev_vf.c
index 13c5b3d..80dc920 100644
--- a/drivers/net/i40e/i40e_ethdev_vf.c
+++ b/drivers/net/i40e/i40e_ethdev_vf.c
@@ -1917,7 +1917,7 @@ i40evf_dev_link_update(struct rte_eth_dev *dev,
 		/* Always assume it's up, for Linux driver PF host */
 		new_link.link_duplex = ETH_LINK_AUTONEG_DUPLEX;
 		new_link.link_speed  = ETH_LINK_SPEED_10000;
-		new_link.link_status = 1;
+		new_link.link_status = ETH_LINK_UP;
 	}
 	i40evf_dev_atomic_write_link_status(dev, &new_link);
 
diff --git a/drivers/net/ixgbe/ixgbe_ethdev.c b/drivers/net/ixgbe/ixgbe_ethdev.c
index 8431755..62a8dff 100644
--- a/drivers/net/ixgbe/ixgbe_ethdev.c
+++ b/drivers/net/ixgbe/ixgbe_ethdev.c
@@ -2957,7 +2957,7 @@ ixgbe_dev_link_update(struct rte_eth_dev *dev, int wait_to_complete)
 	int link_up;
 	int diag;
 
-	link.link_status = 0;
+	link.link_status = ETH_LINK_DOWN;
 	link.link_speed = 0;
 	link.link_duplex = 0;
 	memset(&old, 0, sizeof(old));
@@ -2986,7 +2986,7 @@ ixgbe_dev_link_update(struct rte_eth_dev *dev, int wait_to_complete)
 			return -1;
 		return 0;
 	}
-	link.link_status = 1;
+	link.link_status = ETH_LINK_UP;
 	link.link_duplex = ETH_LINK_FULL_DUPLEX;
 
 	switch (link_speed) {
diff --git a/drivers/net/mpipe/mpipe_tilegx.c b/drivers/net/mpipe/mpipe_tilegx.c
index 04f3c9f..118d3a5 100644
--- a/drivers/net/mpipe/mpipe_tilegx.c
+++ b/drivers/net/mpipe/mpipe_tilegx.c
@@ -391,11 +391,11 @@ mpipe_link_update(struct rte_eth_dev *dev, int wait_to_complete)
 		if (speed == GXIO_MPIPE_LINK_1G) {
 			new.link_speed = ETH_LINK_SPEED_1000;
 			new.link_duplex = ETH_LINK_FULL_DUPLEX;
-			new.link_status = 1;
+			new.link_status = ETH_LINK_UP;
 		} else if (speed == GXIO_MPIPE_LINK_10G) {
 			new.link_speed = ETH_LINK_SPEED_10000;
 			new.link_duplex = ETH_LINK_FULL_DUPLEX;
-			new.link_status = 1;
+			new.link_status = ETH_LINK_UP;
 		}
 
 		rc = mpipe_link_compare(&old, &new);
@@ -847,9 +847,9 @@ mpipe_start(struct rte_eth_dev *dev)
 
 	/* Start xmit/recv on queues. */
 	for (queue = 0; queue < priv->nb_tx_queues; queue++)
-		mpipe_tx_queue(priv, queue)->q.link_status = 1;
+		mpipe_tx_queue(priv, queue)->q.link_status = ETH_LINK_UP;
 	for (queue = 0; queue < priv->nb_rx_queues; queue++)
-		mpipe_rx_queue(priv, queue)->q.link_status = 1;
+		mpipe_rx_queue(priv, queue)->q.link_status = ETH_LINK_UP;
 	priv->running = 1;
 
 	return 0;
@@ -864,9 +864,9 @@ mpipe_stop(struct rte_eth_dev *dev)
 	int rc;
 
 	for (queue = 0; queue < priv->nb_tx_queues; queue++)
-		mpipe_tx_queue(priv, queue)->q.link_status = 0;
+		mpipe_tx_queue(priv, queue)->q.link_status = ETH_LINK_DOWN;
 	for (queue = 0; queue < priv->nb_rx_queues; queue++)
-		mpipe_rx_queue(priv, queue)->q.link_status = 0;
+		mpipe_rx_queue(priv, queue)->q.link_status = ETH_LINK_DOWN;
 
 	/* Make sure the link_status writes land. */
 	rte_wmb();
diff --git a/drivers/net/nfp/nfp_net.c b/drivers/net/nfp/nfp_net.c
index 9c4f218..d1e004a 100644
--- a/drivers/net/nfp/nfp_net.c
+++ b/drivers/net/nfp/nfp_net.c
@@ -827,7 +827,7 @@ nfp_net_link_update(struct rte_eth_dev *dev, __rte_unused int wait_to_complete)
 	memset(&link, 0, sizeof(struct rte_eth_link));
 
 	if (nn_link_status & NFP_NET_CFG_STS_LINK)
-		link.link_status = 1;
+		link.link_status = ETH_LINK_UP;
 
 	link.link_duplex = ETH_LINK_FULL_DUPLEX;
 	/* Other cards can limit the tx and rx rate per VF */
diff --git a/drivers/net/null/rte_eth_null.c b/drivers/net/null/rte_eth_null.c
index 77fc988..2e60823 100644
--- a/drivers/net/null/rte_eth_null.c
+++ b/drivers/net/null/rte_eth_null.c
@@ -95,7 +95,7 @@ static const char *drivername = "Null PMD";
 static struct rte_eth_link pmd_link = {
 	.link_speed = 10000,
 	.link_duplex = ETH_LINK_FULL_DUPLEX,
-	.link_status = 0
+	.link_status = ETH_LINK_DOWN,
 };
 
 static uint16_t
@@ -208,7 +208,7 @@ eth_dev_start(struct rte_eth_dev *dev)
 	if (dev == NULL)
 		return -EINVAL;
 
-	dev->data->dev_link.link_status = 1;
+	dev->data->dev_link.link_status = ETH_LINK_UP;
 	return 0;
 }
 
@@ -218,7 +218,7 @@ eth_dev_stop(struct rte_eth_dev *dev)
 	if (dev == NULL)
 		return;
 
-	dev->data->dev_link.link_status = 0;
+	dev->data->dev_link.link_status = ETH_LINK_DOWN;
 }
 
 static int
diff --git a/drivers/net/pcap/rte_eth_pcap.c b/drivers/net/pcap/rte_eth_pcap.c
index f9230eb..2b32e8d 100644
--- a/drivers/net/pcap/rte_eth_pcap.c
+++ b/drivers/net/pcap/rte_eth_pcap.c
@@ -127,7 +127,7 @@ static const char *drivername = "Pcap PMD";
 static struct rte_eth_link pmd_link = {
 		.link_speed = 10000,
 		.link_duplex = ETH_LINK_FULL_DUPLEX,
-		.link_status = 0
+		.link_status = ETH_LINK_DOWN,
 };
 
 static int
@@ -430,7 +430,7 @@ eth_dev_start(struct rte_eth_dev *dev)
 
 status_up:
 
-	dev->data->dev_link.link_status = 1;
+	dev->data->dev_link.link_status = ETH_LINK_UP;
 	return 0;
 }
 
@@ -481,7 +481,7 @@ eth_dev_stop(struct rte_eth_dev *dev)
 	}
 
 status_down:
-	dev->data->dev_link.link_status = 0;
+	dev->data->dev_link.link_status = ETH_LINK_DOWN;
 }
 
 static int
diff --git a/drivers/net/ring/rte_eth_ring.c b/drivers/net/ring/rte_eth_ring.c
index d92b088..4fcc2aa 100644
--- a/drivers/net/ring/rte_eth_ring.c
+++ b/drivers/net/ring/rte_eth_ring.c
@@ -73,7 +73,7 @@ static const char *drivername = "Rings PMD";
 static struct rte_eth_link pmd_link = {
 		.link_speed = 10000,
 		.link_duplex = ETH_LINK_FULL_DUPLEX,
-		.link_status = 0
+		.link_status = ETH_LINK_DOWN,
 };
 
 static uint16_t
@@ -113,27 +113,27 @@ eth_dev_configure(struct rte_eth_dev *dev __rte_unused) { return 0; }
 static int
 eth_dev_start(struct rte_eth_dev *dev)
 {
-	dev->data->dev_link.link_status = 1;
+	dev->data->dev_link.link_status = ETH_LINK_UP;
 	return 0;
 }
 
 static void
 eth_dev_stop(struct rte_eth_dev *dev)
 {
-	dev->data->dev_link.link_status = 0;
+	dev->data->dev_link.link_status = ETH_LINK_DOWN;
 }
 
 static int
 eth_dev_set_link_down(struct rte_eth_dev *dev)
 {
-	dev->data->dev_link.link_status = 0;
+	dev->data->dev_link.link_status = ETH_LINK_DOWN;
 	return 0;
 }
 
 static int
 eth_dev_set_link_up(struct rte_eth_dev *dev)
 {
-	dev->data->dev_link.link_status = 1;
+	dev->data->dev_link.link_status = ETH_LINK_UP;
 	return 0;
 }
 
diff --git a/drivers/net/szedata2/rte_eth_szedata2.c b/drivers/net/szedata2/rte_eth_szedata2.c
index 9f86c99..38be554 100644
--- a/drivers/net/szedata2/rte_eth_szedata2.c
+++ b/drivers/net/szedata2/rte_eth_szedata2.c
@@ -113,7 +113,7 @@ static const char *drivername = "SZEdata2 PMD";
 static struct rte_eth_link pmd_link = {
 		.link_speed = ETH_LINK_SPEED_10G,
 		.link_duplex = ETH_LINK_FULL_DUPLEX,
-		.link_status = 0
+		.link_status = ETH_LINK_DOWN
 };
 
 
@@ -1158,7 +1158,7 @@ eth_dev_start(struct rte_eth_dev *dev)
 		}
 	}
 
-	dev->data->dev_link.link_status = 1;
+	dev->data->dev_link.link_status = ETH_LINK_UP;
 	return 0;
 }
 
@@ -1188,7 +1188,7 @@ eth_dev_stop(struct rte_eth_dev *dev)
 	dev->data->nb_rx_queues = (uint16_t)0;
 	dev->data->nb_tx_queues = (uint16_t)0;
 
-	dev->data->dev_link.link_status = 0;
+	dev->data->dev_link.link_status = ETH_LINK_DOWN;
 }
 
 static int
diff --git a/drivers/net/virtio/virtio_ethdev.c b/drivers/net/virtio/virtio_ethdev.c
index 06bddd7..76a0faf 100644
--- a/drivers/net/virtio/virtio_ethdev.c
+++ b/drivers/net/virtio/virtio_ethdev.c
@@ -1392,16 +1392,16 @@ virtio_dev_link_update(struct rte_eth_dev *dev, __rte_unused int wait_to_complet
 				offsetof(struct virtio_net_config, status),
 				&status, sizeof(status));
 		if ((status & VIRTIO_NET_S_LINK_UP) == 0) {
-			link.link_status = 0;
+			link.link_status = ETH_LINK_DOWN;
 			PMD_INIT_LOG(DEBUG, "Port %d is down",
 				     dev->data->port_id);
 		} else {
-			link.link_status = 1;
+			link.link_status = ETH_LINK_UP;
 			PMD_INIT_LOG(DEBUG, "Port %d is up",
 				     dev->data->port_id);
 		}
 	} else {
-		link.link_status = 1;   /* Link up */
+		link.link_status = ETH_LINK_UP;
 	}
 	virtio_dev_atomic_write_link_status(dev, &link);
 
diff --git a/drivers/net/vmxnet3/vmxnet3_ethdev.c b/drivers/net/vmxnet3/vmxnet3_ethdev.c
index c363bf6..06793a6 100644
--- a/drivers/net/vmxnet3/vmxnet3_ethdev.c
+++ b/drivers/net/vmxnet3/vmxnet3_ethdev.c
@@ -736,7 +736,7 @@ vmxnet3_dev_link_update(struct rte_eth_dev *dev, __attribute__((unused)) int wai
 	ret = VMXNET3_READ_BAR1_REG(hw, VMXNET3_REG_CMD);
 
 	if (ret & 0x1) {
-		link.link_status = 1;
+		link.link_status = ETH_LINK_UP;
 		link.link_duplex = ETH_LINK_FULL_DUPLEX;
 		link.link_speed = ETH_LINK_SPEED_10000;
 	}
diff --git a/drivers/net/xenvirt/rte_eth_xenvirt.c b/drivers/net/xenvirt/rte_eth_xenvirt.c
index 3f31806..9453a06 100644
--- a/drivers/net/xenvirt/rte_eth_xenvirt.c
+++ b/drivers/net/xenvirt/rte_eth_xenvirt.c
@@ -72,7 +72,7 @@ static const char *drivername = "xen virtio PMD";
 static struct rte_eth_link pmd_link = {
 		.link_speed = 10000,
 		.link_duplex = ETH_LINK_FULL_DUPLEX,
-		.link_status = 0
+		.link_status = ETH_LINK_DOWN,
 };
 
 static void
@@ -290,7 +290,7 @@ eth_dev_start(struct rte_eth_dev *dev)
 	struct pmd_internals *pi = (struct pmd_internals *)dev->data->dev_private;
 	int rv;
 
-	dev->data->dev_link.link_status = 1;
+	dev->data->dev_link.link_status = ETH_LINK_UP;
 	while (!virtqueue_full(rxvq)) {
 		m = rte_rxmbuf_alloc(rxvq->mpool);
 		if (m == NULL)
@@ -318,7 +318,7 @@ eth_dev_stop(struct rte_eth_dev *dev)
 {
 	struct pmd_internals *pi = (struct pmd_internals *)dev->data->dev_private;
 
-	dev->data->dev_link.link_status = 0;
+	dev->data->dev_link.link_status = ETH_LINK_DOWN;
 	dev_stop_notify(pi->virtio_idx);
 }
 
diff --git a/examples/exception_path/main.c b/examples/exception_path/main.c
index b3fe170..bec9804 100644
--- a/examples/exception_path/main.c
+++ b/examples/exception_path/main.c
@@ -485,7 +485,7 @@ check_all_ports_link_status(uint8_t port_num, uint32_t port_mask)
 				continue;
 			}
 			/* clear all_ports_up flag if any link down */
-			if (link.link_status == 0) {
+			if (link.link_status == ETH_LINK_DOWN) {
 				all_ports_up = 0;
 				break;
 			}
diff --git a/examples/ip_fragmentation/main.c b/examples/ip_fragmentation/main.c
index 8021702..81a4918 100644
--- a/examples/ip_fragmentation/main.c
+++ b/examples/ip_fragmentation/main.c
@@ -631,7 +631,7 @@ check_all_ports_link_status(uint8_t port_num, uint32_t port_mask)
 				continue;
 			}
 			/* clear all_ports_up flag if any link down */
-			if (link.link_status == 0) {
+			if (link.link_status == ETH_LINK_DOWN) {
 				all_ports_up = 0;
 				break;
 			}
diff --git a/examples/ip_pipeline/init.c b/examples/ip_pipeline/init.c
index e59a6b4..83422e8 100644
--- a/examples/ip_pipeline/init.c
+++ b/examples/ip_pipeline/init.c
@@ -856,7 +856,7 @@ app_check_link(struct app_params *app)
 			link_params.link_speed / 1000,
 			link_params.link_status ? "UP" : "DOWN");
 
-		if (link_params.link_status == 0)
+		if (link_params.link_status == ETH_LINK_DOWN)
 			all_links_up = 0;
 	}
 
diff --git a/examples/ip_reassembly/main.c b/examples/ip_reassembly/main.c
index 19ec46c..c27e735 100644
--- a/examples/ip_reassembly/main.c
+++ b/examples/ip_reassembly/main.c
@@ -763,7 +763,7 @@ check_all_ports_link_status(uint8_t port_num, uint32_t port_mask)
 				continue;
 			}
 			/* clear all_ports_up flag if any link down */
-			if (link.link_status == 0) {
+			if (link.link_status == ETH_LINK_DOWN) {
 				all_ports_up = 0;
 				break;
 			}
diff --git a/examples/ipsec-secgw/ipsec-secgw.c b/examples/ipsec-secgw/ipsec-secgw.c
index d6c9a5d..393f9bd 100644
--- a/examples/ipsec-secgw/ipsec-secgw.c
+++ b/examples/ipsec-secgw/ipsec-secgw.c
@@ -945,7 +945,7 @@ check_all_ports_link_status(uint8_t port_num, uint32_t port_mask)
 				continue;
 			}
 			/* clear all_ports_up flag if any link down */
-			if (link.link_status == 0) {
+			if (link.link_status == ETH_LINK_DOWN) {
 				all_ports_up = 0;
 				break;
 			}
diff --git a/examples/ipv4_multicast/main.c b/examples/ipv4_multicast/main.c
index 5dbea1a..96b4157 100644
--- a/examples/ipv4_multicast/main.c
+++ b/examples/ipv4_multicast/main.c
@@ -642,7 +642,7 @@ check_all_ports_link_status(uint8_t port_num, uint32_t port_mask)
 				continue;
 			}
 			/* clear all_ports_up flag if any link down */
-			if (link.link_status == 0) {
+			if (link.link_status == ETH_LINK_DOWN) {
 				all_ports_up = 0;
 				break;
 			}
diff --git a/examples/kni/main.c b/examples/kni/main.c
index 6d434ad..a5297f2 100644
--- a/examples/kni/main.c
+++ b/examples/kni/main.c
@@ -670,7 +670,7 @@ check_all_ports_link_status(uint8_t port_num, uint32_t port_mask)
 				continue;
 			}
 			/* clear all_ports_up flag if any link down */
-			if (link.link_status == 0) {
+			if (link.link_status == ETH_LINK_DOWN) {
 				all_ports_up = 0;
 				break;
 			}
diff --git a/examples/l2fwd-crypto/main.c b/examples/l2fwd-crypto/main.c
index 762d22a..fef5b0c 100644
--- a/examples/l2fwd-crypto/main.c
+++ b/examples/l2fwd-crypto/main.c
@@ -1238,7 +1238,7 @@ check_all_ports_link_status(uint8_t port_num, uint32_t port_mask)
 				continue;
 			}
 			/* clear all_ports_up flag if any link down */
-			if (link.link_status == 0) {
+			if (link.link_status == ETH_LINK_DOWN) {
 				all_ports_up = 0;
 				break;
 			}
diff --git a/examples/l2fwd-ivshmem/host/host.c b/examples/l2fwd-ivshmem/host/host.c
index 6e6ed5e..4bd7c41 100644
--- a/examples/l2fwd-ivshmem/host/host.c
+++ b/examples/l2fwd-ivshmem/host/host.c
@@ -371,7 +371,7 @@ check_all_ports_link_status(uint8_t port_num, uint32_t port_mask)
 				continue;
 			}
 			/* clear all_ports_up flag if any link down */
-			if (link.link_status == 0) {
+			if (link.link_status == ETH_LINK_DOWN) {
 				all_ports_up = 0;
 				break;
 			}
diff --git a/examples/l2fwd-jobstats/main.c b/examples/l2fwd-jobstats/main.c
index d1e9bf7..9f3a77d 100644
--- a/examples/l2fwd-jobstats/main.c
+++ b/examples/l2fwd-jobstats/main.c
@@ -746,7 +746,7 @@ check_all_ports_link_status(uint8_t port_num, uint32_t port_mask)
 				continue;
 			}
 			/* clear all_ports_up flag if any link down */
-			if (link.link_status == 0) {
+			if (link.link_status == ETH_LINK_DOWN) {
 				all_ports_up = 0;
 				break;
 			}
diff --git a/examples/l2fwd-keepalive/main.c b/examples/l2fwd-keepalive/main.c
index 94b8677..8da89aa 100644
--- a/examples/l2fwd-keepalive/main.c
+++ b/examples/l2fwd-keepalive/main.c
@@ -499,7 +499,7 @@ check_all_ports_link_status(uint8_t port_num, uint32_t port_mask)
 				continue;
 			}
 			/* clear all_ports_up flag if any link down */
-			if (link.link_status == 0) {
+			if (link.link_status == ETH_LINK_DOWN) {
 				all_ports_up = 0;
 				break;
 			}
diff --git a/examples/l2fwd/main.c b/examples/l2fwd/main.c
index e175681..1ad9488 100644
--- a/examples/l2fwd/main.c
+++ b/examples/l2fwd/main.c
@@ -480,7 +480,7 @@ check_all_ports_link_status(uint8_t port_num, uint32_t port_mask)
 				continue;
 			}
 			/* clear all_ports_up flag if any link down */
-			if (link.link_status == 0) {
+			if (link.link_status == ETH_LINK_DOWN) {
 				all_ports_up = 0;
 				break;
 			}
diff --git a/examples/l3fwd-acl/main.c b/examples/l3fwd-acl/main.c
index 3a895b7..621872f 100644
--- a/examples/l3fwd-acl/main.c
+++ b/examples/l3fwd-acl/main.c
@@ -1858,7 +1858,7 @@ check_all_ports_link_status(uint8_t port_num, uint32_t port_mask)
 				continue;
 			}
 			/* clear all_ports_up flag if any link down */
-			if (link.link_status == 0) {
+			if (link.link_status == ETH_LINK_DOWN) {
 				all_ports_up = 0;
 				break;
 			}
diff --git a/examples/l3fwd-power/main.c b/examples/l3fwd-power/main.c
index d4bb7a3..f0a72fc 100644
--- a/examples/l3fwd-power/main.c
+++ b/examples/l3fwd-power/main.c
@@ -1508,7 +1508,7 @@ check_all_ports_link_status(uint8_t port_num, uint32_t port_mask)
 				continue;
 			}
 			/* clear all_ports_up flag if any link down */
-			if (link.link_status == 0) {
+			if (link.link_status == ETH_LINK_DOWN) {
 				all_ports_up = 0;
 				break;
 			}
diff --git a/examples/l3fwd/main.c b/examples/l3fwd/main.c
index 8520f71..04eae16 100644
--- a/examples/l3fwd/main.c
+++ b/examples/l3fwd/main.c
@@ -746,7 +746,7 @@ check_all_ports_link_status(uint8_t port_num, uint32_t port_mask)
 				continue;
 			}
 			/* clear all_ports_up flag if any link down */
-			if (link.link_status == 0) {
+			if (link.link_status == ETH_LINK_DOWN) {
 				all_ports_up = 0;
 				break;
 			}
diff --git a/examples/link_status_interrupt/main.c b/examples/link_status_interrupt/main.c
index cbc29bc..9981598 100644
--- a/examples/link_status_interrupt/main.c
+++ b/examples/link_status_interrupt/main.c
@@ -523,7 +523,7 @@ check_all_ports_link_status(uint8_t port_num, uint32_t port_mask)
 				continue;
 			}
 			/* clear all_ports_up flag if any link down */
-			if (link.link_status == 0) {
+			if (link.link_status == ETH_LINK_DOWN) {
 				all_ports_up = 0;
 				break;
 			}
diff --git a/examples/load_balancer/init.c b/examples/load_balancer/init.c
index a96d778..e07850b 100644
--- a/examples/load_balancer/init.c
+++ b/examples/load_balancer/init.c
@@ -395,7 +395,7 @@ check_all_ports_link_status(uint8_t port_num, uint32_t port_mask)
 				continue;
 			}
 			/* clear all_ports_up flag if any link down */
-			if (link.link_status == 0) {
+			if (link.link_status == ETH_LINK_DOWN) {
 				all_ports_up = 0;
 				break;
 			}
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 1078ffd..ecb61c6 100644
--- a/examples/multi_process/client_server_mp/mp_server/init.c
+++ b/examples/multi_process/client_server_mp/mp_server/init.c
@@ -226,7 +226,7 @@ check_all_ports_link_status(uint8_t port_num, uint32_t port_mask)
 				continue;
 			}
 			/* clear all_ports_up flag if any link down */
-			if (link.link_status == 0) {
+			if (link.link_status == ETH_LINK_DOWN) {
 				all_ports_up = 0;
 				break;
 			}
diff --git a/examples/multi_process/l2fwd_fork/main.c b/examples/multi_process/l2fwd_fork/main.c
index aebf531..2dc8b82 100644
--- a/examples/multi_process/l2fwd_fork/main.c
+++ b/examples/multi_process/l2fwd_fork/main.c
@@ -900,7 +900,7 @@ check_all_ports_link_status(uint8_t port_num, uint32_t port_mask)
 				continue;
 			}
 			/* clear all_ports_up flag if any link down */
-			if (link.link_status == 0) {
+			if (link.link_status == ETH_LINK_DOWN) {
 				all_ports_up = 0;
 				break;
 			}
diff --git a/examples/multi_process/symmetric_mp/main.c b/examples/multi_process/symmetric_mp/main.c
index 72bad54..6bbff07 100644
--- a/examples/multi_process/symmetric_mp/main.c
+++ b/examples/multi_process/symmetric_mp/main.c
@@ -388,7 +388,7 @@ check_all_ports_link_status(uint8_t port_num, uint32_t port_mask)
 				continue;
 			}
 			/* clear all_ports_up flag if any link down */
-			if (link.link_status == 0) {
+			if (link.link_status == ETH_LINK_DOWN) {
 				all_ports_up = 0;
 				break;
 			}
diff --git a/examples/performance-thread/l3fwd-thread/main.c b/examples/performance-thread/l3fwd-thread/main.c
index 7bcca37..aa1fdc3 100644
--- a/examples/performance-thread/l3fwd-thread/main.c
+++ b/examples/performance-thread/l3fwd-thread/main.c
@@ -3407,7 +3407,7 @@ check_all_ports_link_status(uint8_t port_num, uint32_t port_mask)
 				continue;
 			}
 			/* clear all_ports_up flag if any link down */
-			if (link.link_status == 0) {
+			if (link.link_status == ETH_LINK_DOWN) {
 				all_ports_up = 0;
 				break;
 			}
diff --git a/lib/librte_ether/rte_ethdev.h b/lib/librte_ether/rte_ethdev.h
index d867976..6704a82 100644
--- a/lib/librte_ether/rte_ethdev.h
+++ b/lib/librte_ether/rte_ethdev.h
@@ -247,7 +247,7 @@ struct rte_eth_stats {
 struct rte_eth_link {
 	uint16_t link_speed;      /**< ETH_LINK_SPEED_[10, 100, 1000, 10000] */
 	uint16_t link_duplex;     /**< ETH_LINK_[HALF_DUPLEX, FULL_DUPLEX] */
-	uint8_t  link_status : 1; /**< 1 -> link up, 0 -> link down */
+	uint8_t  link_status : 1; /**< ETH_LINK_[DOWN/UP] */
 }__attribute__((aligned(8)));     /**< aligned for atomic64 read/write */
 
 #define ETH_LINK_SPEED_AUTONEG  0       /**< Auto-negotiate link speed. */
@@ -259,9 +259,12 @@ struct rte_eth_link {
 #define ETH_LINK_SPEED_20G      20000   /**< 20 gigabits/second. */
 #define ETH_LINK_SPEED_40G      40000   /**< 40 gigabits/second. */
 
+/* Utility constants */
 #define ETH_LINK_AUTONEG_DUPLEX 0       /**< Auto-negotiate duplex. */
 #define ETH_LINK_HALF_DUPLEX    1       /**< Half-duplex connection. */
 #define ETH_LINK_FULL_DUPLEX    2       /**< Full-duplex connection. */
+#define ETH_LINK_DOWN           0 /**< Link is down. */
+#define ETH_LINK_UP             1 /**< Link is up. */
 
 /**
  * A structure used to configure the ring threshold registers of an RX/TX
-- 
2.7.0

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

* [PATCH v10 2/8] ethdev: use constants for link duplex
  2016-03-14 21:55         ` [PATCH v10 0/8] ethdev: 100G and link speed API refactoring Thomas Monjalon
  2016-03-14 21:55           ` [PATCH v10 1/8] ethdev: use constants for link state Thomas Monjalon
@ 2016-03-14 21:55           ` Thomas Monjalon
  2016-03-14 21:55           ` [PATCH v10 3/8] app/testpmd: move speed and duplex parsing in a function Thomas Monjalon
                             ` (9 subsequent siblings)
  11 siblings, 0 replies; 167+ messages in thread
From: Thomas Monjalon @ 2016-03-14 21:55 UTC (permalink / raw)
  To: marcdevel, bruce.richardson, declan.doherty, konstantin.ananyev,
	wenzhuo.lu, helin.zhang, jing.d.chen, harish.patil,
	rahul.lakkireddy, johndale, vido, adrien.mazarguil,
	alejandro.lucero
  Cc: dev

From: Marc Sune <marcdevel@gmail.com>

Some duplex values are replaced from 0 to half-duplex when link is down.

Some drivers are still using their own constants for duplex modes.

Signed-off-by: Marc Sune <marcdevel@gmail.com>
---
 drivers/net/e1000/em_ethdev.c      | 2 +-
 drivers/net/e1000/igb_ethdev.c     | 2 +-
 drivers/net/ixgbe/ixgbe_ethdev.c   | 2 +-
 drivers/net/virtio/virtio_ethdev.c | 2 +-
 drivers/net/virtio/virtio_ethdev.h | 2 --
 lib/librte_ether/rte_ethdev.h      | 2 +-
 6 files changed, 5 insertions(+), 7 deletions(-)

diff --git a/drivers/net/e1000/em_ethdev.c b/drivers/net/e1000/em_ethdev.c
index 58f9c7a..2f3529f 100644
--- a/drivers/net/e1000/em_ethdev.c
+++ b/drivers/net/e1000/em_ethdev.c
@@ -1076,7 +1076,7 @@ eth_em_link_update(struct rte_eth_dev *dev, int wait_to_complete)
 		link.link_status = ETH_LINK_UP;
 	} else if (!link_check && (link.link_status == ETH_LINK_UP)) {
 		link.link_speed = 0;
-		link.link_duplex = 0;
+		link.link_duplex = ETH_LINK_HALF_DUPLEX;
 		link.link_status = ETH_LINK_DOWN;
 	}
 	rte_em_dev_atomic_write_link_status(dev, &link);
diff --git a/drivers/net/e1000/igb_ethdev.c b/drivers/net/e1000/igb_ethdev.c
index 614d8cb..0e58fa9 100644
--- a/drivers/net/e1000/igb_ethdev.c
+++ b/drivers/net/e1000/igb_ethdev.c
@@ -2024,7 +2024,7 @@ eth_igb_link_update(struct rte_eth_dev *dev, int wait_to_complete)
 		link.link_status = ETH_LINK_UP;
 	} else if (!link_check) {
 		link.link_speed = 0;
-		link.link_duplex = 0;
+		link.link_duplex = ETH_LINK_HALF_DUPLEX;
 		link.link_status = ETH_LINK_DOWN;
 	}
 	rte_igb_dev_atomic_write_link_status(dev, &link);
diff --git a/drivers/net/ixgbe/ixgbe_ethdev.c b/drivers/net/ixgbe/ixgbe_ethdev.c
index 62a8dff..99c55bd 100644
--- a/drivers/net/ixgbe/ixgbe_ethdev.c
+++ b/drivers/net/ixgbe/ixgbe_ethdev.c
@@ -2959,7 +2959,7 @@ ixgbe_dev_link_update(struct rte_eth_dev *dev, int wait_to_complete)
 
 	link.link_status = ETH_LINK_DOWN;
 	link.link_speed = 0;
-	link.link_duplex = 0;
+	link.link_duplex = ETH_LINK_HALF_DUPLEX;
 	memset(&old, 0, sizeof(old));
 	rte_ixgbe_dev_atomic_read_link_status(dev, &old);
 
diff --git a/drivers/net/virtio/virtio_ethdev.c b/drivers/net/virtio/virtio_ethdev.c
index 76a0faf..aa5ae10 100644
--- a/drivers/net/virtio/virtio_ethdev.c
+++ b/drivers/net/virtio/virtio_ethdev.c
@@ -1383,7 +1383,7 @@ virtio_dev_link_update(struct rte_eth_dev *dev, __rte_unused int wait_to_complet
 	memset(&link, 0, sizeof(link));
 	virtio_dev_atomic_read_link_status(dev, &link);
 	old = link;
-	link.link_duplex = FULL_DUPLEX;
+	link.link_duplex = ETH_LINK_FULL_DUPLEX;
 	link.link_speed  = SPEED_10G;
 
 	if (vtpci_with_feature(hw, VIRTIO_NET_F_STATUS)) {
diff --git a/drivers/net/virtio/virtio_ethdev.h b/drivers/net/virtio/virtio_ethdev.h
index fed9571..66423a0 100644
--- a/drivers/net/virtio/virtio_ethdev.h
+++ b/drivers/net/virtio/virtio_ethdev.h
@@ -42,8 +42,6 @@
 #define SPEED_100	100
 #define SPEED_1000	1000
 #define SPEED_10G	10000
-#define HALF_DUPLEX	1
-#define FULL_DUPLEX	2
 
 #ifndef PAGE_SIZE
 #define PAGE_SIZE 4096
diff --git a/lib/librte_ether/rte_ethdev.h b/lib/librte_ether/rte_ethdev.h
index 6704a82..12b552d 100644
--- a/lib/librte_ether/rte_ethdev.h
+++ b/lib/librte_ether/rte_ethdev.h
@@ -246,7 +246,7 @@ struct rte_eth_stats {
  */
 struct rte_eth_link {
 	uint16_t link_speed;      /**< ETH_LINK_SPEED_[10, 100, 1000, 10000] */
-	uint16_t link_duplex;     /**< ETH_LINK_[HALF_DUPLEX, FULL_DUPLEX] */
+	uint16_t link_duplex;     /**< ETH_LINK_[HALF/FULL]_DUPLEX */
 	uint8_t  link_status : 1; /**< ETH_LINK_[DOWN/UP] */
 }__attribute__((aligned(8)));     /**< aligned for atomic64 read/write */
 
-- 
2.7.0

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

* [PATCH v10 3/8] app/testpmd: move speed and duplex parsing in a function
  2016-03-14 21:55         ` [PATCH v10 0/8] ethdev: 100G and link speed API refactoring Thomas Monjalon
  2016-03-14 21:55           ` [PATCH v10 1/8] ethdev: use constants for link state Thomas Monjalon
  2016-03-14 21:55           ` [PATCH v10 2/8] ethdev: use constants for link duplex Thomas Monjalon
@ 2016-03-14 21:55           ` Thomas Monjalon
  2016-03-14 21:55           ` [PATCH v10 4/8] ethdev: rename link speed constants Thomas Monjalon
                             ` (8 subsequent siblings)
  11 siblings, 0 replies; 167+ messages in thread
From: Thomas Monjalon @ 2016-03-14 21:55 UTC (permalink / raw)
  To: marcdevel, bruce.richardson, declan.doherty, konstantin.ananyev,
	wenzhuo.lu, helin.zhang, jing.d.chen, harish.patil,
	rahul.lakkireddy, johndale, vido, adrien.mazarguil,
	alejandro.lucero
  Cc: dev

From: Marc Sune <marcdevel@gmail.com>

The code for checking and parsing speed/duplex was duplicated.
The new function is also checking the speed/duplex combination.

Signed-off-by: Marc Sune <marcdevel@gmail.com>
---
 app/test-pmd/cmdline.c | 99 ++++++++++++++++++++++++--------------------------
 1 file changed, 47 insertions(+), 52 deletions(-)

diff --git a/app/test-pmd/cmdline.c b/app/test-pmd/cmdline.c
index 9d52b8c..37be5cd 100644
--- a/app/test-pmd/cmdline.c
+++ b/app/test-pmd/cmdline.c
@@ -983,6 +983,49 @@ struct cmd_config_speed_all {
 	cmdline_fixed_string_t value2;
 };
 
+static int
+parse_and_check_speed_duplex(char *speedstr, char *duplexstr, uint16_t *speed)
+{
+
+	int duplex;
+
+	if (!strcmp(duplexstr, "half")) {
+		duplex = ETH_LINK_HALF_DUPLEX;
+	} else if (!strcmp(duplexstr, "full")) {
+		duplex = ETH_LINK_FULL_DUPLEX;
+	} else if (!strcmp(duplexstr, "auto")) {
+		duplex = ETH_LINK_FULL_DUPLEX;
+	} else {
+		printf("Unknown duplex parameter\n");
+		return -1;
+	}
+
+	if (!strcmp(speedstr, "10")) {
+		*speed = ETH_LINK_SPEED_10;
+	} else if (!strcmp(speedstr, "100")) {
+		*speed = ETH_LINK_SPEED_100;
+	} else {
+		if (duplex != ETH_LINK_FULL_DUPLEX) {
+			printf("Invalid speed/duplex parameters\n");
+			return -1;
+		}
+		if (!strcmp(speedstr, "1000")) {
+			*speed = ETH_LINK_SPEED_1000;
+		} else if (!strcmp(speedstr, "10000")) {
+			*speed = ETH_LINK_SPEED_10G;
+		} else if (!strcmp(speedstr, "40000")) {
+			*speed = ETH_LINK_SPEED_40G;
+		} else if (!strcmp(speedstr, "auto")) {
+			*speed = ETH_LINK_SPEED_AUTONEG;
+		} else {
+			printf("Unknown speed parameter\n");
+			return -1;
+		}
+	}
+
+	return 0;
+}
+
 static void
 cmd_config_speed_all_parsed(void *parsed_result,
 			__attribute__((unused)) struct cmdline *cl,
@@ -998,33 +1041,9 @@ cmd_config_speed_all_parsed(void *parsed_result,
 		return;
 	}
 
-	if (!strcmp(res->value1, "10"))
-		link_speed = ETH_LINK_SPEED_10;
-	else if (!strcmp(res->value1, "100"))
-		link_speed = ETH_LINK_SPEED_100;
-	else if (!strcmp(res->value1, "1000"))
-		link_speed = ETH_LINK_SPEED_1000;
-	else if (!strcmp(res->value1, "10000"))
-		link_speed = ETH_LINK_SPEED_10G;
-	else if (!strcmp(res->value1, "40000"))
-		link_speed = ETH_LINK_SPEED_40G;
-	else if (!strcmp(res->value1, "auto"))
-		link_speed = ETH_LINK_SPEED_AUTONEG;
-	else {
-		printf("Unknown parameter\n");
+	if (parse_and_check_speed_duplex(res->value1, res->value2,
+			&link_speed) < 0)
 		return;
-	}
-
-	if (!strcmp(res->value2, "half"))
-		link_duplex = ETH_LINK_HALF_DUPLEX;
-	else if (!strcmp(res->value2, "full"))
-		link_duplex = ETH_LINK_FULL_DUPLEX;
-	else if (!strcmp(res->value2, "auto"))
-		link_duplex = ETH_LINK_AUTONEG_DUPLEX;
-	else {
-		printf("Unknown parameter\n");
-		return;
-	}
 
 	FOREACH_PORT(pid, ports) {
 		ports[pid].dev_conf.link_speed = link_speed;
@@ -1097,33 +1116,9 @@ cmd_config_speed_specific_parsed(void *parsed_result,
 	if (port_id_is_invalid(res->id, ENABLED_WARN))
 		return;
 
-	if (!strcmp(res->value1, "10"))
-		link_speed = ETH_LINK_SPEED_10;
-	else if (!strcmp(res->value1, "100"))
-		link_speed = ETH_LINK_SPEED_100;
-	else if (!strcmp(res->value1, "1000"))
-		link_speed = ETH_LINK_SPEED_1000;
-	else if (!strcmp(res->value1, "10000"))
-		link_speed = ETH_LINK_SPEED_10000;
-	else if (!strcmp(res->value1, "40000"))
-		link_speed = ETH_LINK_SPEED_40G;
-	else if (!strcmp(res->value1, "auto"))
-		link_speed = ETH_LINK_SPEED_AUTONEG;
-	else {
-		printf("Unknown parameter\n");
-		return;
-	}
-
-	if (!strcmp(res->value2, "half"))
-		link_duplex = ETH_LINK_HALF_DUPLEX;
-	else if (!strcmp(res->value2, "full"))
-		link_duplex = ETH_LINK_FULL_DUPLEX;
-	else if (!strcmp(res->value2, "auto"))
-		link_duplex = ETH_LINK_AUTONEG_DUPLEX;
-	else {
-		printf("Unknown parameter\n");
+	if (parse_and_check_speed_duplex(res->value1, res->value2,
+			&link_speed) < 0)
 		return;
-	}
 
 	ports[res->id].dev_conf.link_speed = link_speed;
 	ports[res->id].dev_conf.link_duplex = link_duplex;
-- 
2.7.0

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

* [PATCH v10 4/8] ethdev: rename link speed constants
  2016-03-14 21:55         ` [PATCH v10 0/8] ethdev: 100G and link speed API refactoring Thomas Monjalon
                             ` (2 preceding siblings ...)
  2016-03-14 21:55           ` [PATCH v10 3/8] app/testpmd: move speed and duplex parsing in a function Thomas Monjalon
@ 2016-03-14 21:55           ` Thomas Monjalon
  2016-03-14 21:55           ` [PATCH v10 5/8] ethdev: add speed capabilities Thomas Monjalon
                             ` (7 subsequent siblings)
  11 siblings, 0 replies; 167+ messages in thread
From: Thomas Monjalon @ 2016-03-14 21:55 UTC (permalink / raw)
  To: marcdevel, bruce.richardson, declan.doherty, konstantin.ananyev,
	wenzhuo.lu, helin.zhang, jing.d.chen, harish.patil,
	rahul.lakkireddy, johndale, vido, adrien.mazarguil,
	alejandro.lucero
  Cc: dev

From: Marc Sune <marcdevel@gmail.com>

The speed numbers ETH_LINK_SPEED_ are renamed ETH_SPEED_NUM_.
The prefix ETH_LINK_SPEED_ is kept for AUTONEG and will be used
for bit flags in next patch.

Signed-off-by: Marc Sune <marcdevel@gmail.com>
---
 app/test-pmd/cmdline.c                    | 10 +++++-----
 app/test/virtual_pmd.c                    |  2 +-
 drivers/net/af_packet/rte_eth_af_packet.c |  2 +-
 drivers/net/bonding/rte_eth_bond_8023ad.c | 12 ++++++------
 drivers/net/cxgbe/base/t4_hw.c            |  8 ++++----
 drivers/net/e1000/em_ethdev.c             |  8 ++++----
 drivers/net/e1000/igb_ethdev.c            |  8 ++++----
 drivers/net/i40e/i40e_ethdev.c            | 30 +++++++++++++++---------------
 drivers/net/i40e/i40e_ethdev_vf.c         |  2 +-
 drivers/net/ixgbe/ixgbe_ethdev.c          | 22 +++++++++++-----------
 drivers/net/mpipe/mpipe_tilegx.c          |  4 ++--
 drivers/net/nfp/nfp_net.c                 |  2 +-
 drivers/net/null/rte_eth_null.c           |  2 +-
 drivers/net/pcap/rte_eth_pcap.c           |  2 +-
 drivers/net/ring/rte_eth_ring.c           |  2 +-
 drivers/net/szedata2/rte_eth_szedata2.c   |  2 +-
 drivers/net/vmxnet3/vmxnet3_ethdev.c      |  2 +-
 drivers/net/xenvirt/rte_eth_xenvirt.c     |  2 +-
 lib/librte_ether/rte_ethdev.h             | 29 ++++++++++++++++++-----------
 19 files changed, 79 insertions(+), 72 deletions(-)

diff --git a/app/test-pmd/cmdline.c b/app/test-pmd/cmdline.c
index 37be5cd..874129a 100644
--- a/app/test-pmd/cmdline.c
+++ b/app/test-pmd/cmdline.c
@@ -1001,20 +1001,20 @@ parse_and_check_speed_duplex(char *speedstr, char *duplexstr, uint16_t *speed)
 	}
 
 	if (!strcmp(speedstr, "10")) {
-		*speed = ETH_LINK_SPEED_10;
+		*speed = ETH_SPEED_NUM_10M;
 	} else if (!strcmp(speedstr, "100")) {
-		*speed = ETH_LINK_SPEED_100;
+		*speed = ETH_SPEED_NUM_100M;
 	} else {
 		if (duplex != ETH_LINK_FULL_DUPLEX) {
 			printf("Invalid speed/duplex parameters\n");
 			return -1;
 		}
 		if (!strcmp(speedstr, "1000")) {
-			*speed = ETH_LINK_SPEED_1000;
+			*speed = ETH_SPEED_NUM_1G;
 		} else if (!strcmp(speedstr, "10000")) {
-			*speed = ETH_LINK_SPEED_10G;
+			*speed = ETH_SPEED_NUM_10G;
 		} else if (!strcmp(speedstr, "40000")) {
-			*speed = ETH_LINK_SPEED_40G;
+			*speed = ETH_SPEED_NUM_40G;
 		} else if (!strcmp(speedstr, "auto")) {
 			*speed = ETH_LINK_SPEED_AUTONEG;
 		} else {
diff --git a/app/test/virtual_pmd.c b/app/test/virtual_pmd.c
index b1d40d7..b4bd2f2 100644
--- a/app/test/virtual_pmd.c
+++ b/app/test/virtual_pmd.c
@@ -604,7 +604,7 @@ virtual_ethdev_create(const char *name, struct ether_addr *mac_addr,
 	TAILQ_INIT(&(eth_dev->link_intr_cbs));
 
 	eth_dev->data->dev_link.link_status = ETH_LINK_DOWN;
-	eth_dev->data->dev_link.link_speed = ETH_LINK_SPEED_10000;
+	eth_dev->data->dev_link.link_speed = ETH_SPEED_NUM_10G;
 	eth_dev->data->dev_link.link_duplex = ETH_LINK_FULL_DUPLEX;
 
 	eth_dev->data->mac_addrs = rte_zmalloc(name, ETHER_ADDR_LEN, 0);
diff --git a/drivers/net/af_packet/rte_eth_af_packet.c b/drivers/net/af_packet/rte_eth_af_packet.c
index 24f909f..ff0d299 100644
--- a/drivers/net/af_packet/rte_eth_af_packet.c
+++ b/drivers/net/af_packet/rte_eth_af_packet.c
@@ -116,7 +116,7 @@ static const char *valid_arguments[] = {
 static const char *drivername = "AF_PACKET PMD";
 
 static struct rte_eth_link pmd_link = {
-	.link_speed = 10000,
+	.link_speed = ETH_SPEED_NUM_10G,
 	.link_duplex = ETH_LINK_FULL_DUPLEX,
 	.link_status = ETH_LINK_DOWN,
 };
diff --git a/drivers/net/bonding/rte_eth_bond_8023ad.c b/drivers/net/bonding/rte_eth_bond_8023ad.c
index b3b30f6..5f9c9b3 100644
--- a/drivers/net/bonding/rte_eth_bond_8023ad.c
+++ b/drivers/net/bonding/rte_eth_bond_8023ad.c
@@ -711,22 +711,22 @@ link_speed_key(uint16_t speed) {
 	case ETH_LINK_SPEED_AUTONEG:
 		key_speed = 0x00;
 		break;
-	case ETH_LINK_SPEED_10:
+	case ETH_SPEED_NUM_10M:
 		key_speed = BOND_LINK_SPEED_KEY_10M;
 		break;
-	case ETH_LINK_SPEED_100:
+	case ETH_SPEED_NUM_100M:
 		key_speed = BOND_LINK_SPEED_KEY_100M;
 		break;
-	case ETH_LINK_SPEED_1000:
+	case ETH_SPEED_NUM_1G:
 		key_speed = BOND_LINK_SPEED_KEY_1000M;
 		break;
-	case ETH_LINK_SPEED_10G:
+	case ETH_SPEED_NUM_10G:
 		key_speed = BOND_LINK_SPEED_KEY_10G;
 		break;
-	case ETH_LINK_SPEED_20G:
+	case ETH_SPEED_NUM_20G:
 		key_speed = BOND_LINK_SPEED_KEY_20G;
 		break;
-	case ETH_LINK_SPEED_40G:
+	case ETH_SPEED_NUM_40G:
 		key_speed = BOND_LINK_SPEED_KEY_40G;
 		break;
 	default:
diff --git a/drivers/net/cxgbe/base/t4_hw.c b/drivers/net/cxgbe/base/t4_hw.c
index 884d2cf..79af806 100644
--- a/drivers/net/cxgbe/base/t4_hw.c
+++ b/drivers/net/cxgbe/base/t4_hw.c
@@ -2159,13 +2159,13 @@ int t4_handle_fw_rpl(struct adapter *adap, const __be64 *rpl)
 		if (stat & F_FW_PORT_CMD_TXPAUSE)
 			fc |= PAUSE_TX;
 		if (stat & V_FW_PORT_CMD_LSPEED(FW_PORT_CAP_SPEED_100M))
-			speed = ETH_LINK_SPEED_100;
+			speed = ETH_SPEED_NUM_100M;
 		else if (stat & V_FW_PORT_CMD_LSPEED(FW_PORT_CAP_SPEED_1G))
-			speed = ETH_LINK_SPEED_1000;
+			speed = ETH_SPEED_NUM_1G;
 		else if (stat & V_FW_PORT_CMD_LSPEED(FW_PORT_CAP_SPEED_10G))
-			speed = ETH_LINK_SPEED_10000;
+			speed = ETH_SPEED_NUM_10G;
 		else if (stat & V_FW_PORT_CMD_LSPEED(FW_PORT_CAP_SPEED_40G))
-			speed = ETH_LINK_SPEED_40G;
+			speed = ETH_SPEED_NUM_40G;
 
 		for_each_port(adap, i) {
 			pi = adap2pinfo(adap, i);
diff --git a/drivers/net/e1000/em_ethdev.c b/drivers/net/e1000/em_ethdev.c
index 2f3529f..84845e7 100644
--- a/drivers/net/e1000/em_ethdev.c
+++ b/drivers/net/e1000/em_ethdev.c
@@ -596,7 +596,7 @@ eth_em_start(struct rte_eth_dev *dev)
 		else
 			goto error_invalid_config;
 		break;
-	case ETH_LINK_SPEED_10:
+	case ETH_SPEED_NUM_10M:
 		if (dev->data->dev_conf.link_duplex == ETH_LINK_AUTONEG_DUPLEX)
 			hw->phy.autoneg_advertised = E1000_ALL_10_SPEED;
 		else if (dev->data->dev_conf.link_duplex ==
@@ -608,7 +608,7 @@ eth_em_start(struct rte_eth_dev *dev)
 		else
 			goto error_invalid_config;
 		break;
-	case ETH_LINK_SPEED_100:
+	case ETH_SPEED_NUM_100M:
 		if (dev->data->dev_conf.link_duplex == ETH_LINK_AUTONEG_DUPLEX)
 			hw->phy.autoneg_advertised = E1000_ALL_100_SPEED;
 		else if (dev->data->dev_conf.link_duplex ==
@@ -620,7 +620,7 @@ eth_em_start(struct rte_eth_dev *dev)
 		else
 			goto error_invalid_config;
 		break;
-	case ETH_LINK_SPEED_1000:
+	case ETH_SPEED_NUM_1G:
 		if ((dev->data->dev_conf.link_duplex ==
 				ETH_LINK_AUTONEG_DUPLEX) ||
 			(dev->data->dev_conf.link_duplex ==
@@ -629,7 +629,7 @@ eth_em_start(struct rte_eth_dev *dev)
 		else
 			goto error_invalid_config;
 		break;
-	case ETH_LINK_SPEED_10000:
+	case ETH_SPEED_NUM_10G:
 	default:
 		goto error_invalid_config;
 	}
diff --git a/drivers/net/e1000/igb_ethdev.c b/drivers/net/e1000/igb_ethdev.c
index 0e58fa9..b4c8982 100644
--- a/drivers/net/e1000/igb_ethdev.c
+++ b/drivers/net/e1000/igb_ethdev.c
@@ -1232,7 +1232,7 @@ eth_igb_start(struct rte_eth_dev *dev)
 		else
 			goto error_invalid_config;
 		break;
-	case ETH_LINK_SPEED_10:
+	case ETH_SPEED_NUM_10M:
 		if (dev->data->dev_conf.link_duplex == ETH_LINK_AUTONEG_DUPLEX)
 			hw->phy.autoneg_advertised = E1000_ALL_10_SPEED;
 		else if (dev->data->dev_conf.link_duplex == ETH_LINK_HALF_DUPLEX)
@@ -1242,7 +1242,7 @@ eth_igb_start(struct rte_eth_dev *dev)
 		else
 			goto error_invalid_config;
 		break;
-	case ETH_LINK_SPEED_100:
+	case ETH_SPEED_NUM_100M:
 		if (dev->data->dev_conf.link_duplex == ETH_LINK_AUTONEG_DUPLEX)
 			hw->phy.autoneg_advertised = E1000_ALL_100_SPEED;
 		else if (dev->data->dev_conf.link_duplex == ETH_LINK_HALF_DUPLEX)
@@ -1252,14 +1252,14 @@ eth_igb_start(struct rte_eth_dev *dev)
 		else
 			goto error_invalid_config;
 		break;
-	case ETH_LINK_SPEED_1000:
+	case ETH_SPEED_NUM_1G:
 		if ((dev->data->dev_conf.link_duplex == ETH_LINK_AUTONEG_DUPLEX) ||
 				(dev->data->dev_conf.link_duplex == ETH_LINK_FULL_DUPLEX))
 			hw->phy.autoneg_advertised = ADVERTISE_1000_FULL;
 		else
 			goto error_invalid_config;
 		break;
-	case ETH_LINK_SPEED_10000:
+	case ETH_SPEED_NUM_10G:
 	default:
 		goto error_invalid_config;
 	}
diff --git a/drivers/net/i40e/i40e_ethdev.c b/drivers/net/i40e/i40e_ethdev.c
index 2f676f6..17b58a8 100644
--- a/drivers/net/i40e/i40e_ethdev.c
+++ b/drivers/net/i40e/i40e_ethdev.c
@@ -1363,19 +1363,19 @@ i40e_parse_link_speed(uint16_t eth_link_speed)
 	uint8_t link_speed = I40E_LINK_SPEED_UNKNOWN;
 
 	switch (eth_link_speed) {
-	case ETH_LINK_SPEED_40G:
+	case ETH_SPEED_NUM_40G:
 		link_speed = I40E_LINK_SPEED_40GB;
 		break;
-	case ETH_LINK_SPEED_20G:
+	case ETH_SPEED_NUM_20G:
 		link_speed = I40E_LINK_SPEED_20GB;
 		break;
-	case ETH_LINK_SPEED_10G:
+	case ETH_SPEED_NUM_10G:
 		link_speed = I40E_LINK_SPEED_10GB;
 		break;
-	case ETH_LINK_SPEED_1000:
+	case ETH_SPEED_NUM_1G:
 		link_speed = I40E_LINK_SPEED_1GB;
 		break;
-	case ETH_LINK_SPEED_100:
+	case ETH_SPEED_NUM_100M:
 		link_speed = I40E_LINK_SPEED_100MB;
 		break;
 	}
@@ -1745,7 +1745,7 @@ i40e_dev_link_update(struct rte_eth_dev *dev,
 		/* Get link status information from hardware */
 		status = i40e_aq_get_link_info(hw, false, &link_status, NULL);
 		if (status != I40E_SUCCESS) {
-			link.link_speed = ETH_LINK_SPEED_100;
+			link.link_speed = ETH_SPEED_NUM_100M;
 			link.link_duplex = ETH_LINK_FULL_DUPLEX;
 			PMD_DRV_LOG(ERR, "Failed to get link info");
 			goto out;
@@ -1767,22 +1767,22 @@ i40e_dev_link_update(struct rte_eth_dev *dev,
 	/* Parse the link status */
 	switch (link_status.link_speed) {
 	case I40E_LINK_SPEED_100MB:
-		link.link_speed = ETH_LINK_SPEED_100;
+		link.link_speed = ETH_SPEED_NUM_100M;
 		break;
 	case I40E_LINK_SPEED_1GB:
-		link.link_speed = ETH_LINK_SPEED_1000;
+		link.link_speed = ETH_SPEED_NUM_1G;
 		break;
 	case I40E_LINK_SPEED_10GB:
-		link.link_speed = ETH_LINK_SPEED_10G;
+		link.link_speed = ETH_SPEED_NUM_10G;
 		break;
 	case I40E_LINK_SPEED_20GB:
-		link.link_speed = ETH_LINK_SPEED_20G;
+		link.link_speed = ETH_SPEED_NUM_20G;
 		break;
 	case I40E_LINK_SPEED_40GB:
-		link.link_speed = ETH_LINK_SPEED_40G;
+		link.link_speed = ETH_SPEED_NUM_40G;
 		break;
 	default:
-		link.link_speed = ETH_LINK_SPEED_100;
+		link.link_speed = ETH_SPEED_NUM_100M;
 		break;
 	}
 
@@ -7967,15 +7967,15 @@ i40e_start_timecounters(struct rte_eth_dev *dev)
 	rte_i40e_dev_atomic_read_link_status(dev, &link);
 
 	switch (link.link_speed) {
-	case ETH_LINK_SPEED_40G:
+	case ETH_SPEED_NUM_40G:
 		tsync_inc_l = I40E_PTP_40GB_INCVAL & 0xFFFFFFFF;
 		tsync_inc_h = I40E_PTP_40GB_INCVAL >> 32;
 		break;
-	case ETH_LINK_SPEED_10G:
+	case ETH_SPEED_NUM_10G:
 		tsync_inc_l = I40E_PTP_10GB_INCVAL & 0xFFFFFFFF;
 		tsync_inc_h = I40E_PTP_10GB_INCVAL >> 32;
 		break;
-	case ETH_LINK_SPEED_1000:
+	case ETH_SPEED_NUM_1G:
 		tsync_inc_l = I40E_PTP_1GB_INCVAL & 0xFFFFFFFF;
 		tsync_inc_h = I40E_PTP_1GB_INCVAL >> 32;
 		break;
diff --git a/drivers/net/i40e/i40e_ethdev_vf.c b/drivers/net/i40e/i40e_ethdev_vf.c
index 80dc920..7ac5c48 100644
--- a/drivers/net/i40e/i40e_ethdev_vf.c
+++ b/drivers/net/i40e/i40e_ethdev_vf.c
@@ -1916,7 +1916,7 @@ i40evf_dev_link_update(struct rte_eth_dev *dev,
 	else {
 		/* Always assume it's up, for Linux driver PF host */
 		new_link.link_duplex = ETH_LINK_AUTONEG_DUPLEX;
-		new_link.link_speed  = ETH_LINK_SPEED_10000;
+		new_link.link_speed  = ETH_SPEED_NUM_10G;
 		new_link.link_status = ETH_LINK_UP;
 	}
 	i40evf_dev_atomic_write_link_status(dev, &new_link);
diff --git a/drivers/net/ixgbe/ixgbe_ethdev.c b/drivers/net/ixgbe/ixgbe_ethdev.c
index 99c55bd..1fa17b5 100644
--- a/drivers/net/ixgbe/ixgbe_ethdev.c
+++ b/drivers/net/ixgbe/ixgbe_ethdev.c
@@ -2138,17 +2138,17 @@ ixgbe_dev_start(struct rte_eth_dev *dev)
 				IXGBE_LINK_SPEED_82599_AUTONEG :
 				IXGBE_LINK_SPEED_82598_AUTONEG;
 		break;
-	case ETH_LINK_SPEED_100:
+	case ETH_SPEED_NUM_100M:
 		/*
 		 * Invalid for 82598 but error will be detected by
 		 * ixgbe_setup_link()
 		 */
 		speed = IXGBE_LINK_SPEED_100_FULL;
 		break;
-	case ETH_LINK_SPEED_1000:
+	case ETH_SPEED_NUM_1G:
 		speed = IXGBE_LINK_SPEED_1GB_FULL;
 		break;
-	case ETH_LINK_SPEED_10000:
+	case ETH_SPEED_NUM_10G:
 		speed = IXGBE_LINK_SPEED_10GB_FULL;
 		break;
 	default:
@@ -2972,7 +2972,7 @@ ixgbe_dev_link_update(struct rte_eth_dev *dev, int wait_to_complete)
 		diag = ixgbe_check_link(hw, &link_speed, &link_up, 1);
 
 	if (diag != 0) {
-		link.link_speed = ETH_LINK_SPEED_100;
+		link.link_speed = ETH_SPEED_NUM_100M;
 		link.link_duplex = ETH_LINK_HALF_DUPLEX;
 		rte_ixgbe_dev_atomic_write_link_status(dev, &link);
 		if (link.link_status == old.link_status)
@@ -2993,19 +2993,19 @@ ixgbe_dev_link_update(struct rte_eth_dev *dev, int wait_to_complete)
 	default:
 	case IXGBE_LINK_SPEED_UNKNOWN:
 		link.link_duplex = ETH_LINK_HALF_DUPLEX;
-		link.link_speed = ETH_LINK_SPEED_100;
+		link.link_speed = ETH_SPEED_NUM_100M;
 		break;
 
 	case IXGBE_LINK_SPEED_100_FULL:
-		link.link_speed = ETH_LINK_SPEED_100;
+		link.link_speed = ETH_SPEED_NUM_100M;
 		break;
 
 	case IXGBE_LINK_SPEED_1GB_FULL:
-		link.link_speed = ETH_LINK_SPEED_1000;
+		link.link_speed = ETH_SPEED_NUM_1G;
 		break;
 
 	case IXGBE_LINK_SPEED_10GB_FULL:
-		link.link_speed = ETH_LINK_SPEED_10000;
+		link.link_speed = ETH_SPEED_NUM_10G;
 		break;
 	}
 	rte_ixgbe_dev_atomic_write_link_status(dev, &link);
@@ -5782,15 +5782,15 @@ ixgbe_start_timecounters(struct rte_eth_dev *dev)
 	rte_ixgbe_dev_atomic_read_link_status(dev, &link);
 
 	switch (link.link_speed) {
-	case ETH_LINK_SPEED_100:
+	case ETH_SPEED_NUM_100M:
 		incval = IXGBE_INCVAL_100;
 		shift = IXGBE_INCVAL_SHIFT_100;
 		break;
-	case ETH_LINK_SPEED_1000:
+	case ETH_SPEED_NUM_1G:
 		incval = IXGBE_INCVAL_1GB;
 		shift = IXGBE_INCVAL_SHIFT_1GB;
 		break;
-	case ETH_LINK_SPEED_10000:
+	case ETH_SPEED_NUM_10G:
 	default:
 		incval = IXGBE_INCVAL_10GB;
 		shift = IXGBE_INCVAL_SHIFT_10GB;
diff --git a/drivers/net/mpipe/mpipe_tilegx.c b/drivers/net/mpipe/mpipe_tilegx.c
index 118d3a5..fc1f90d 100644
--- a/drivers/net/mpipe/mpipe_tilegx.c
+++ b/drivers/net/mpipe/mpipe_tilegx.c
@@ -389,11 +389,11 @@ mpipe_link_update(struct rte_eth_dev *dev, int wait_to_complete)
 		speed = state & GXIO_MPIPE_LINK_SPEED_MASK;
 
 		if (speed == GXIO_MPIPE_LINK_1G) {
-			new.link_speed = ETH_LINK_SPEED_1000;
+			new.link_speed = ETH_SPEED_NUM_1G;
 			new.link_duplex = ETH_LINK_FULL_DUPLEX;
 			new.link_status = ETH_LINK_UP;
 		} else if (speed == GXIO_MPIPE_LINK_10G) {
-			new.link_speed = ETH_LINK_SPEED_10000;
+			new.link_speed = ETH_SPEED_NUM_10G;
 			new.link_duplex = ETH_LINK_FULL_DUPLEX;
 			new.link_status = ETH_LINK_UP;
 		}
diff --git a/drivers/net/nfp/nfp_net.c b/drivers/net/nfp/nfp_net.c
index d1e004a..059b554 100644
--- a/drivers/net/nfp/nfp_net.c
+++ b/drivers/net/nfp/nfp_net.c
@@ -831,7 +831,7 @@ nfp_net_link_update(struct rte_eth_dev *dev, __rte_unused int wait_to_complete)
 
 	link.link_duplex = ETH_LINK_FULL_DUPLEX;
 	/* Other cards can limit the tx and rx rate per VF */
-	link.link_speed = ETH_LINK_SPEED_40G;
+	link.link_speed = ETH_SPEED_NUM_40G;
 
 	if (old.link_status != link.link_status) {
 		nfp_net_dev_atomic_write_link_status(dev, &link);
diff --git a/drivers/net/null/rte_eth_null.c b/drivers/net/null/rte_eth_null.c
index 2e60823..3f37c54 100644
--- a/drivers/net/null/rte_eth_null.c
+++ b/drivers/net/null/rte_eth_null.c
@@ -93,7 +93,7 @@ struct pmd_internals {
 static struct ether_addr eth_addr = { .addr_bytes = {0} };
 static const char *drivername = "Null PMD";
 static struct rte_eth_link pmd_link = {
-	.link_speed = 10000,
+	.link_speed = ETH_SPEED_NUM_10G,
 	.link_duplex = ETH_LINK_FULL_DUPLEX,
 	.link_status = ETH_LINK_DOWN,
 };
diff --git a/drivers/net/pcap/rte_eth_pcap.c b/drivers/net/pcap/rte_eth_pcap.c
index 2b32e8d..5251b9f 100644
--- a/drivers/net/pcap/rte_eth_pcap.c
+++ b/drivers/net/pcap/rte_eth_pcap.c
@@ -125,7 +125,7 @@ static int open_single_iface(const char *iface, pcap_t **pcap);
 static struct ether_addr eth_addr = { .addr_bytes = { 0, 0, 0, 0x1, 0x2, 0x3 } };
 static const char *drivername = "Pcap PMD";
 static struct rte_eth_link pmd_link = {
-		.link_speed = 10000,
+		.link_speed = ETH_SPEED_NUM_10G,
 		.link_duplex = ETH_LINK_FULL_DUPLEX,
 		.link_status = ETH_LINK_DOWN,
 };
diff --git a/drivers/net/ring/rte_eth_ring.c b/drivers/net/ring/rte_eth_ring.c
index 4fcc2aa..bd18508 100644
--- a/drivers/net/ring/rte_eth_ring.c
+++ b/drivers/net/ring/rte_eth_ring.c
@@ -71,7 +71,7 @@ struct pmd_internals {
 
 static const char *drivername = "Rings PMD";
 static struct rte_eth_link pmd_link = {
-		.link_speed = 10000,
+		.link_speed = ETH_SPEED_NUM_10G,
 		.link_duplex = ETH_LINK_FULL_DUPLEX,
 		.link_status = ETH_LINK_DOWN,
 };
diff --git a/drivers/net/szedata2/rte_eth_szedata2.c b/drivers/net/szedata2/rte_eth_szedata2.c
index 38be554..9d46987 100644
--- a/drivers/net/szedata2/rte_eth_szedata2.c
+++ b/drivers/net/szedata2/rte_eth_szedata2.c
@@ -111,7 +111,7 @@ static struct ether_addr eth_addr = {
 };
 static const char *drivername = "SZEdata2 PMD";
 static struct rte_eth_link pmd_link = {
-		.link_speed = ETH_LINK_SPEED_10G,
+		.link_speed = ETH_SPEED_NUM_10G,
 		.link_duplex = ETH_LINK_FULL_DUPLEX,
 		.link_status = ETH_LINK_DOWN
 };
diff --git a/drivers/net/vmxnet3/vmxnet3_ethdev.c b/drivers/net/vmxnet3/vmxnet3_ethdev.c
index 06793a6..64a035c 100644
--- a/drivers/net/vmxnet3/vmxnet3_ethdev.c
+++ b/drivers/net/vmxnet3/vmxnet3_ethdev.c
@@ -738,7 +738,7 @@ vmxnet3_dev_link_update(struct rte_eth_dev *dev, __attribute__((unused)) int wai
 	if (ret & 0x1) {
 		link.link_status = ETH_LINK_UP;
 		link.link_duplex = ETH_LINK_FULL_DUPLEX;
-		link.link_speed = ETH_LINK_SPEED_10000;
+		link.link_speed = ETH_SPEED_NUM_10G;
 	}
 
 	vmxnet3_dev_atomic_write_link_status(dev, &link);
diff --git a/drivers/net/xenvirt/rte_eth_xenvirt.c b/drivers/net/xenvirt/rte_eth_xenvirt.c
index 9453a06..77d3ba1 100644
--- a/drivers/net/xenvirt/rte_eth_xenvirt.c
+++ b/drivers/net/xenvirt/rte_eth_xenvirt.c
@@ -70,7 +70,7 @@ static int virtio_idx = 0;
 static const char *drivername = "xen virtio PMD";
 
 static struct rte_eth_link pmd_link = {
-		.link_speed = 10000,
+		.link_speed = ETH_SPEED_NUM_10G,
 		.link_duplex = ETH_LINK_FULL_DUPLEX,
 		.link_status = ETH_LINK_DOWN,
 };
diff --git a/lib/librte_ether/rte_ethdev.h b/lib/librte_ether/rte_ethdev.h
index 12b552d..b68e017 100644
--- a/lib/librte_ether/rte_ethdev.h
+++ b/lib/librte_ether/rte_ethdev.h
@@ -242,23 +242,30 @@ struct rte_eth_stats {
 };
 
 /**
+ * Ethernet numeric link speeds in Mbps
+ */
+#define ETH_LINK_SPEED_AUTONEG     0 /**< Auto-negotiate link speed. */
+#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 */
+
+/**
  * A structure used to retrieve link-level information of an Ethernet port.
  */
 struct rte_eth_link {
-	uint16_t link_speed;      /**< ETH_LINK_SPEED_[10, 100, 1000, 10000] */
+	uint16_t link_speed;      /**< ETH_SPEED_NUM_ */
 	uint16_t link_duplex;     /**< ETH_LINK_[HALF/FULL]_DUPLEX */
 	uint8_t  link_status : 1; /**< ETH_LINK_[DOWN/UP] */
 }__attribute__((aligned(8)));     /**< aligned for atomic64 read/write */
 
-#define ETH_LINK_SPEED_AUTONEG  0       /**< Auto-negotiate link speed. */
-#define ETH_LINK_SPEED_10       10      /**< 10 megabits/second. */
-#define ETH_LINK_SPEED_100      100     /**< 100 megabits/second. */
-#define ETH_LINK_SPEED_1000     1000    /**< 1 gigabits/second. */
-#define ETH_LINK_SPEED_10000    10000   /**< 10 gigabits/second. */
-#define ETH_LINK_SPEED_10G      10000   /**< alias of 10 gigabits/second. */
-#define ETH_LINK_SPEED_20G      20000   /**< 20 gigabits/second. */
-#define ETH_LINK_SPEED_40G      40000   /**< 40 gigabits/second. */
-
 /* Utility constants */
 #define ETH_LINK_AUTONEG_DUPLEX 0       /**< Auto-negotiate duplex. */
 #define ETH_LINK_HALF_DUPLEX    1       /**< Half-duplex connection. */
@@ -779,7 +786,7 @@ struct rte_intr_conf {
  */
 struct rte_eth_conf {
 	uint16_t link_speed;
-	/**< ETH_LINK_SPEED_10[0|00|000], or 0 for autonegotation */
+	/**< ETH_SPEED_NUM_ or 0 for autonegotiation */
 	uint16_t link_duplex;
 	/**< ETH_LINK_[HALF_DUPLEX|FULL_DUPLEX], or 0 for autonegotation */
 	struct rte_eth_rxmode rxmode; /**< Port RX configuration. */
-- 
2.7.0

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

* [PATCH v10 5/8] ethdev: add speed capabilities
  2016-03-14 21:55         ` [PATCH v10 0/8] ethdev: 100G and link speed API refactoring Thomas Monjalon
                             ` (3 preceding siblings ...)
  2016-03-14 21:55           ` [PATCH v10 4/8] ethdev: rename link speed constants Thomas Monjalon
@ 2016-03-14 21:55           ` Thomas Monjalon
  2016-03-14 21:55           ` [PATCH v10 6/8] ethdev: redesign link speed config Thomas Monjalon
                             ` (6 subsequent siblings)
  11 siblings, 0 replies; 167+ messages in thread
From: Thomas Monjalon @ 2016-03-14 21:55 UTC (permalink / raw)
  To: marcdevel, bruce.richardson, declan.doherty, konstantin.ananyev,
	wenzhuo.lu, helin.zhang, jing.d.chen, harish.patil,
	rahul.lakkireddy, johndale, vido, adrien.mazarguil,
	alejandro.lucero
  Cc: dev

From: Marc Sune <marcdevel@gmail.com>

The speed capabilities of a device can be retrieved with
rte_eth_dev_info_get().

The new field speed_capa is initialized in the drivers without
taking care of device characteristics in this patch.
When the capabilities of a driver are accurate, the table in
overview.rst must be filled.

Signed-off-by: Marc Sune <marcdevel@gmail.com>
---
 doc/guides/nics/overview.rst           |  1 +
 doc/guides/rel_notes/release_16_04.rst |  8 ++++++++
 drivers/net/bnx2x/bnx2x_ethdev.c       |  1 +
 drivers/net/cxgbe/cxgbe_ethdev.c       |  1 +
 drivers/net/e1000/em_ethdev.c          |  4 ++++
 drivers/net/e1000/igb_ethdev.c         |  4 ++++
 drivers/net/fm10k/fm10k_ethdev.c       |  4 ++++
 drivers/net/i40e/i40e_ethdev.c         |  8 ++++++++
 drivers/net/ixgbe/ixgbe_ethdev.c       |  8 ++++++++
 drivers/net/mlx4/mlx4.c                |  2 ++
 drivers/net/mlx5/mlx5_ethdev.c         |  3 +++
 drivers/net/nfp/nfp_net.c              |  2 ++
 lib/librte_ether/rte_ethdev.h          | 21 +++++++++++++++++++++
 13 files changed, 67 insertions(+)

diff --git a/doc/guides/nics/overview.rst b/doc/guides/nics/overview.rst
index 2d4f014..893da5f 100644
--- a/doc/guides/nics/overview.rst
+++ b/doc/guides/nics/overview.rst
@@ -88,6 +88,7 @@ Most of these differences are summarized below.
    ==================== = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
    link status                  X     X X                                   X
    link status event                  X X
+   speed capabilities
    Rx interrupt                       X X X X
    queue start/stop             X     X X X X                               X
    MTU update                   X
diff --git a/doc/guides/rel_notes/release_16_04.rst b/doc/guides/rel_notes/release_16_04.rst
index b729b67..fd24a6f 100644
--- a/doc/guides/rel_notes/release_16_04.rst
+++ b/doc/guides/rel_notes/release_16_04.rst
@@ -47,6 +47,11 @@ This section should contain new features added in this release. Sample format:
   A new function ``rte_pktmbuf_alloc_bulk()`` has been added to allow the user
   to allocate a bulk of mbufs.
 
+* **Added device link speed capabilities.**
+
+  The structure ``rte_eth_dev_info`` has now a ``speed_capa`` bitmap, which
+  allows the application to know the supported speeds of each device.
+
 * **Virtio 1.0.**
 
   Enabled virtio 1.0 support for virtio pmd driver.
@@ -208,6 +213,9 @@ This section should contain API changes. Sample format:
 * Add a short 1-2 sentence description of the API change. Use fixed width
   quotes for ``rte_function_names`` or ``rte_struct_names``. Use the past tense.
 
+* The ethdev structure ``rte_eth_dev_info`` was changed to support device
+  speed capabilities.
+
 * The functions ``rte_eth_dev_udp_tunnel_add`` and ``rte_eth_dev_udp_tunnel_delete``
   have been renamed into ``rte_eth_dev_udp_tunnel_port_add`` and
   ``rte_eth_dev_udp_tunnel_port_delete``.
diff --git a/drivers/net/bnx2x/bnx2x_ethdev.c b/drivers/net/bnx2x/bnx2x_ethdev.c
index f109900..b86784e 100644
--- a/drivers/net/bnx2x/bnx2x_ethdev.c
+++ b/drivers/net/bnx2x/bnx2x_ethdev.c
@@ -347,6 +347,7 @@ bnx2x_dev_infos_get(struct rte_eth_dev *dev, __rte_unused struct rte_eth_dev_inf
 	dev_info->min_rx_bufsize = BNX2X_MIN_RX_BUF_SIZE;
 	dev_info->max_rx_pktlen  = BNX2X_MAX_RX_PKT_LEN;
 	dev_info->max_mac_addrs  = BNX2X_MAX_MAC_ADDRS;
+	dev_info->speed_capa = ETH_LINK_SPEED_10G | ETH_LINK_SPEED_20G;
 }
 
 static void
diff --git a/drivers/net/cxgbe/cxgbe_ethdev.c b/drivers/net/cxgbe/cxgbe_ethdev.c
index 97ef152..05b954d 100644
--- a/drivers/net/cxgbe/cxgbe_ethdev.c
+++ b/drivers/net/cxgbe/cxgbe_ethdev.c
@@ -171,6 +171,7 @@ static void cxgbe_dev_info_get(struct rte_eth_dev *eth_dev,
 
 	device_info->rx_desc_lim = cxgbe_desc_lim;
 	device_info->tx_desc_lim = cxgbe_desc_lim;
+	device_info->speed_capa = ETH_LINK_SPEED_10G | ETH_LINK_SPEED_40G;
 }
 
 static void cxgbe_dev_promiscuous_enable(struct rte_eth_dev *eth_dev)
diff --git a/drivers/net/e1000/em_ethdev.c b/drivers/net/e1000/em_ethdev.c
index 84845e7..dddffff 100644
--- a/drivers/net/e1000/em_ethdev.c
+++ b/drivers/net/e1000/em_ethdev.c
@@ -1023,6 +1023,10 @@ eth_em_infos_get(struct rte_eth_dev *dev, struct rte_eth_dev_info *dev_info)
 		.nb_min = E1000_MIN_RING_DESC,
 		.nb_align = EM_TXD_ALIGN,
 	};
+
+	dev_info->speed_capa = ETH_LINK_SPEED_10M_HD | ETH_LINK_SPEED_10M |
+			ETH_LINK_SPEED_100M_HD | ETH_LINK_SPEED_100M |
+			ETH_LINK_SPEED_1G;
 }
 
 /* return 0 means link status changed, -1 means not changed */
diff --git a/drivers/net/e1000/igb_ethdev.c b/drivers/net/e1000/igb_ethdev.c
index b4c8982..743fe1b 100644
--- a/drivers/net/e1000/igb_ethdev.c
+++ b/drivers/net/e1000/igb_ethdev.c
@@ -1910,6 +1910,10 @@ eth_igb_infos_get(struct rte_eth_dev *dev, struct rte_eth_dev_info *dev_info)
 
 	dev_info->rx_desc_lim = rx_desc_lim;
 	dev_info->tx_desc_lim = tx_desc_lim;
+
+	dev_info->speed_capa = ETH_LINK_SPEED_10M_HD | ETH_LINK_SPEED_10M |
+			ETH_LINK_SPEED_100M_HD | ETH_LINK_SPEED_100M |
+			ETH_LINK_SPEED_1G;
 }
 
 static void
diff --git a/drivers/net/fm10k/fm10k_ethdev.c b/drivers/net/fm10k/fm10k_ethdev.c
index 378faf2..4d8c6bf 100644
--- a/drivers/net/fm10k/fm10k_ethdev.c
+++ b/drivers/net/fm10k/fm10k_ethdev.c
@@ -1333,6 +1333,10 @@ fm10k_dev_infos_get(struct rte_eth_dev *dev,
 		.nb_min = FM10K_MIN_TX_DESC,
 		.nb_align = FM10K_MULT_TX_DESC,
 	};
+
+	dev_info->speed_capa = ETH_LINK_SPEED_1G | ETH_LINK_SPEED_2_5G |
+			ETH_LINK_SPEED_10G | ETH_LINK_SPEED_25G |
+			ETH_LINK_SPEED_40G;
 }
 
 static int
diff --git a/drivers/net/i40e/i40e_ethdev.c b/drivers/net/i40e/i40e_ethdev.c
index 17b58a8..3b2a4ae 100644
--- a/drivers/net/i40e/i40e_ethdev.c
+++ b/drivers/net/i40e/i40e_ethdev.c
@@ -2265,6 +2265,7 @@ static void
 i40e_dev_info_get(struct rte_eth_dev *dev, struct rte_eth_dev_info *dev_info)
 {
 	struct i40e_pf *pf = I40E_DEV_PRIVATE_TO_PF(dev->data->dev_private);
+	struct i40e_hw *hw = I40E_DEV_PRIVATE_TO_HW(dev->data->dev_private);
 	struct i40e_vsi *vsi = pf->main_vsi;
 
 	dev_info->max_rx_queues = vsi->nb_qps;
@@ -2336,6 +2337,13 @@ i40e_dev_info_get(struct rte_eth_dev *dev, struct rte_eth_dev_info *dev_info)
 		dev_info->max_rx_queues += dev_info->vmdq_queue_num;
 		dev_info->max_tx_queues += dev_info->vmdq_queue_num;
 	}
+
+	if (i40e_is_40G_device(hw->device_id))
+		/* For XL710 */
+		dev_info->speed_capa = ETH_LINK_SPEED_1G | ETH_LINK_SPEED_10G;
+	else
+		/* For X710 */
+		dev_info->speed_capa = ETH_LINK_SPEED_10G | ETH_LINK_SPEED_40G;
 }
 
 static int
diff --git a/drivers/net/ixgbe/ixgbe_ethdev.c b/drivers/net/ixgbe/ixgbe_ethdev.c
index 1fa17b5..1c108a0 100644
--- a/drivers/net/ixgbe/ixgbe_ethdev.c
+++ b/drivers/net/ixgbe/ixgbe_ethdev.c
@@ -2891,6 +2891,14 @@ ixgbe_dev_info_get(struct rte_eth_dev *dev, struct rte_eth_dev_info *dev_info)
 	dev_info->hash_key_size = IXGBE_HKEY_MAX_INDEX * sizeof(uint32_t);
 	dev_info->reta_size = ixgbe_reta_size_get(hw->mac.type);
 	dev_info->flow_type_rss_offloads = IXGBE_RSS_OFFLOAD_ALL;
+
+	dev_info->speed_capa = ETH_LINK_SPEED_1G | ETH_LINK_SPEED_10G;
+	if (hw->mac.type == ixgbe_mac_X540 ||
+	    hw->mac.type == ixgbe_mac_X540_vf ||
+	    hw->mac.type == ixgbe_mac_X550 ||
+	    hw->mac.type == ixgbe_mac_X550_vf) {
+		dev_info->speed_capa |= ETH_LINK_SPEED_100M;
+	}
 }
 
 static void
diff --git a/drivers/net/mlx4/mlx4.c b/drivers/net/mlx4/mlx4.c
index f41817b..7397cbf 100644
--- a/drivers/net/mlx4/mlx4.c
+++ b/drivers/net/mlx4/mlx4.c
@@ -4264,6 +4264,8 @@ mlx4_dev_infos_get(struct rte_eth_dev *dev, struct rte_eth_dev_info *info)
 		 0);
 	if (priv_get_ifname(priv, &ifname) == 0)
 		info->if_index = if_nametoindex(ifname);
+	info->speed_capa = ETH_LINK_SPEED_10G | ETH_LINK_SPEED_40G |
+			ETH_LINK_SPEED_56G;
 	priv_unlock(priv);
 }
 
diff --git a/drivers/net/mlx5/mlx5_ethdev.c b/drivers/net/mlx5/mlx5_ethdev.c
index 1159fa3..7494f69 100644
--- a/drivers/net/mlx5/mlx5_ethdev.c
+++ b/drivers/net/mlx5/mlx5_ethdev.c
@@ -523,6 +523,9 @@ mlx5_dev_infos_get(struct rte_eth_dev *dev, struct rte_eth_dev_info *info)
 	 * size if it is not fixed.
 	 * The API should be updated to solve this problem. */
 	info->reta_size = priv->ind_table_max_size;
+	info->speed_capa = ETH_LINK_SPEED_1G | ETH_LINK_SPEED_10G |
+			ETH_LINK_SPEED_25G | ETH_LINK_SPEED_40G |
+			ETH_LINK_SPEED_50G;
 	priv_unlock(priv);
 }
 
diff --git a/drivers/net/nfp/nfp_net.c b/drivers/net/nfp/nfp_net.c
index 059b554..be1a364 100644
--- a/drivers/net/nfp/nfp_net.c
+++ b/drivers/net/nfp/nfp_net.c
@@ -1071,6 +1071,8 @@ nfp_net_infos_get(struct rte_eth_dev *dev, struct rte_eth_dev_info *dev_info)
 
 	dev_info->reta_size = NFP_NET_CFG_RSS_ITBL_SZ;
 	dev_info->hash_key_size = NFP_NET_CFG_RSS_KEY_SZ;
+
+	dev_info->speed_capa = ETH_LINK_SPEED_50G;
 }
 
 static uint32_t
diff --git a/lib/librte_ether/rte_ethdev.h b/lib/librte_ether/rte_ethdev.h
index b68e017..017e24b 100644
--- a/lib/librte_ether/rte_ethdev.h
+++ b/lib/librte_ether/rte_ethdev.h
@@ -242,6 +242,23 @@ struct rte_eth_stats {
 };
 
 /**
+ * Device supported speeds bitmap flags
+ */
+#define ETH_LINK_SPEED_10M_HD   (1 <<  1)  /**<  10 Mbps half-duplex */
+#define ETH_LINK_SPEED_10M      (1 <<  2)  /**<  10 Mbps full-duplex */
+#define ETH_LINK_SPEED_100M_HD  (1 <<  3)  /**< 100 Mbps half-duplex */
+#define ETH_LINK_SPEED_100M     (1 <<  4)  /**< 100 Mbps full-duplex */
+#define ETH_LINK_SPEED_1G       (1 <<  5)  /**<   1 Gbps */
+#define ETH_LINK_SPEED_2_5G     (1 <<  6)  /**< 2.5 Gbps */
+#define ETH_LINK_SPEED_5G       (1 <<  7)  /**<   5 Gbps */
+#define ETH_LINK_SPEED_10G      (1 <<  8)  /**<  10 Gbps */
+#define ETH_LINK_SPEED_20G      (1 <<  9)  /**<  20 Gbps */
+#define ETH_LINK_SPEED_25G      (1 << 10)  /**<  25 Gbps */
+#define ETH_LINK_SPEED_40G      (1 << 11)  /**<  40 Gbps */
+#define ETH_LINK_SPEED_50G      (1 << 12)  /**<  50 Gbps */
+#define ETH_LINK_SPEED_56G      (1 << 13)  /**<  56 Gbps */
+
+/**
  * Ethernet numeric link speeds in Mbps
  */
 #define ETH_LINK_SPEED_AUTONEG     0 /**< Auto-negotiate link speed. */
@@ -850,6 +867,9 @@ struct rte_eth_conf {
 #define DEV_TX_OFFLOAD_OUTER_IPV4_CKSUM 0x00000080 /**< Used for tunneling packet. */
 #define DEV_TX_OFFLOAD_QINQ_INSERT 0x00000100
 
+/**
+ * Ethernet device information
+ */
 struct rte_eth_dev_info {
 	struct rte_pci_device *pci_dev; /**< Device PCI information. */
 	const char *driver_name; /**< Device Driver name. */
@@ -878,6 +898,7 @@ struct rte_eth_dev_info {
 	uint16_t vmdq_pool_base;  /**< First ID of VMDQ pools. */
 	struct rte_eth_desc_lim rx_desc_lim;  /**< RX descriptors limits */
 	struct rte_eth_desc_lim tx_desc_lim;  /**< TX descriptors limits */
+	uint32_t speed_capa;  /**< Supported speeds bitmap (ETH_LINK_SPEED_). */
 };
 
 /**
-- 
2.7.0

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

* [PATCH v10 6/8] ethdev: redesign link speed config
  2016-03-14 21:55         ` [PATCH v10 0/8] ethdev: 100G and link speed API refactoring Thomas Monjalon
                             ` (4 preceding siblings ...)
  2016-03-14 21:55           ` [PATCH v10 5/8] ethdev: add speed capabilities Thomas Monjalon
@ 2016-03-14 21:55           ` Thomas Monjalon
  2016-03-14 21:55           ` [PATCH v10 7/8] ethdev: convert speed number to bitmap flag Thomas Monjalon
                             ` (5 subsequent siblings)
  11 siblings, 0 replies; 167+ messages in thread
From: Thomas Monjalon @ 2016-03-14 21:55 UTC (permalink / raw)
  To: marcdevel, bruce.richardson, declan.doherty, konstantin.ananyev,
	wenzhuo.lu, helin.zhang, jing.d.chen, harish.patil,
	rahul.lakkireddy, johndale, vido, adrien.mazarguil,
	alejandro.lucero
  Cc: dev

From: Marc Sune <marcdevel@gmail.com>

This patch redesigns the API to set the link speed/s configuration
of an ethernet port. Specifically:

- it allows to define a set of advertised speeds for
  auto-negociation.
- it allows to disable link auto-negociation (single fixed speed).
- default: auto-negociate all supported speeds.

A flag autoneg in struct rte_eth_link indicates if link speed was a
result of auto-negociation or was fixed by configuration.

Signed-off-by: Marc Sune <marcdevel@gmail.com>
Tested-by: Nelio Laranjeiro <nelio.laranjeiro@6wind.com>
Signed-off-by: Thomas Monjalon <thomas.monjalon@6wind.com>
---

PLEASE REVIEW CAREFULLY THIS PATCH

 app/test-pmd/cmdline.c                    | 26 ++++----
 doc/guides/rel_notes/release_16_04.rst    |  9 +++
 drivers/net/af_packet/rte_eth_af_packet.c |  1 +
 drivers/net/bnx2x/bnx2x_ethdev.c          |  4 +-
 drivers/net/bonding/rte_eth_bond_8023ad.c |  2 +-
 drivers/net/e1000/em_ethdev.c             | 99 +++++++++++++++----------------
 drivers/net/e1000/igb_ethdev.c            | 94 +++++++++++++++--------------
 drivers/net/i40e/i40e_ethdev.c            | 48 +++++++--------
 drivers/net/i40e/i40e_ethdev_vf.c         |  7 ++-
 drivers/net/ixgbe/ixgbe_ethdev.c          | 46 ++++++--------
 drivers/net/mlx4/mlx4.c                   |  2 +
 drivers/net/mpipe/mpipe_tilegx.c          |  2 +
 drivers/net/null/rte_eth_null.c           |  1 +
 drivers/net/pcap/rte_eth_pcap.c           |  1 +
 drivers/net/ring/rte_eth_ring.c           |  1 +
 drivers/net/szedata2/rte_eth_szedata2.c   |  2 +-
 drivers/net/vmxnet3/vmxnet3_ethdev.c      |  1 +
 drivers/net/xenvirt/rte_eth_xenvirt.c     |  1 +
 examples/ip_pipeline/config_parse.c       |  3 +-
 lib/librte_ether/rte_ethdev.h             | 29 +++++----
 20 files changed, 195 insertions(+), 184 deletions(-)

diff --git a/app/test-pmd/cmdline.c b/app/test-pmd/cmdline.c
index 874129a..3bc7bb4 100644
--- a/app/test-pmd/cmdline.c
+++ b/app/test-pmd/cmdline.c
@@ -984,7 +984,7 @@ struct cmd_config_speed_all {
 };
 
 static int
-parse_and_check_speed_duplex(char *speedstr, char *duplexstr, uint16_t *speed)
+parse_and_check_speed_duplex(char *speedstr, char *duplexstr, uint32_t *speed)
 {
 
 	int duplex;
@@ -1001,20 +1001,22 @@ parse_and_check_speed_duplex(char *speedstr, char *duplexstr, uint16_t *speed)
 	}
 
 	if (!strcmp(speedstr, "10")) {
-		*speed = ETH_SPEED_NUM_10M;
+		*speed = (duplex == ETH_LINK_HALF_DUPLEX) ?
+				ETH_LINK_SPEED_10M_HD : ETH_LINK_SPEED_10M;
 	} else if (!strcmp(speedstr, "100")) {
-		*speed = ETH_SPEED_NUM_100M;
+		*speed = (duplex == ETH_LINK_HALF_DUPLEX) ?
+				ETH_LINK_SPEED_100M_HD : ETH_LINK_SPEED_100M;
 	} else {
 		if (duplex != ETH_LINK_FULL_DUPLEX) {
 			printf("Invalid speed/duplex parameters\n");
 			return -1;
 		}
 		if (!strcmp(speedstr, "1000")) {
-			*speed = ETH_SPEED_NUM_1G;
+			*speed = ETH_LINK_SPEED_1G;
 		} else if (!strcmp(speedstr, "10000")) {
-			*speed = ETH_SPEED_NUM_10G;
+			*speed = ETH_LINK_SPEED_10G;
 		} else if (!strcmp(speedstr, "40000")) {
-			*speed = ETH_SPEED_NUM_40G;
+			*speed = ETH_LINK_SPEED_40G;
 		} else if (!strcmp(speedstr, "auto")) {
 			*speed = ETH_LINK_SPEED_AUTONEG;
 		} else {
@@ -1032,8 +1034,7 @@ cmd_config_speed_all_parsed(void *parsed_result,
 			__attribute__((unused)) void *data)
 {
 	struct cmd_config_speed_all *res = parsed_result;
-	uint16_t link_speed = ETH_LINK_SPEED_AUTONEG;
-	uint16_t link_duplex = 0;
+	uint32_t link_speed;
 	portid_t pid;
 
 	if (!all_ports_stopped()) {
@@ -1046,8 +1047,7 @@ cmd_config_speed_all_parsed(void *parsed_result,
 		return;
 
 	FOREACH_PORT(pid, ports) {
-		ports[pid].dev_conf.link_speed = link_speed;
-		ports[pid].dev_conf.link_duplex = link_duplex;
+		ports[pid].dev_conf.link_speeds = link_speed;
 	}
 
 	cmd_reconfig_device_queue(RTE_PORT_ALL, 1, 1);
@@ -1105,8 +1105,7 @@ cmd_config_speed_specific_parsed(void *parsed_result,
 				__attribute__((unused)) void *data)
 {
 	struct cmd_config_speed_specific *res = parsed_result;
-	uint16_t link_speed = ETH_LINK_SPEED_AUTONEG;
-	uint16_t link_duplex = 0;
+	uint32_t link_speed;
 
 	if (!all_ports_stopped()) {
 		printf("Please stop all ports first\n");
@@ -1120,8 +1119,7 @@ cmd_config_speed_specific_parsed(void *parsed_result,
 			&link_speed) < 0)
 		return;
 
-	ports[res->id].dev_conf.link_speed = link_speed;
-	ports[res->id].dev_conf.link_duplex = link_duplex;
+	ports[res->id].dev_conf.link_speeds = link_speed;
 
 	cmd_reconfig_device_queue(RTE_PORT_ALL, 1, 1);
 }
diff --git a/doc/guides/rel_notes/release_16_04.rst b/doc/guides/rel_notes/release_16_04.rst
index fd24a6f..f6d00f5 100644
--- a/doc/guides/rel_notes/release_16_04.rst
+++ b/doc/guides/rel_notes/release_16_04.rst
@@ -52,6 +52,12 @@ This section should contain new features added in this release. Sample format:
   The structure ``rte_eth_dev_info`` has now a ``speed_capa`` bitmap, which
   allows the application to know the supported speeds of each device.
 
+* **Added bitmap of link speeds to advertise.**
+
+  Allow defining a set of advertised speeds for auto-negotiation,
+  explicitly disabling link auto-negotiation (single speed)
+  and full auto-negotiation.
+
 * **Virtio 1.0.**
 
   Enabled virtio 1.0 support for virtio pmd driver.
@@ -216,6 +222,9 @@ This section should contain API changes. Sample format:
 * The ethdev structure ``rte_eth_dev_info`` was changed to support device
   speed capabilities.
 
+* The ethdev structures ``rte_eth_link`` and ``rte_eth_conf`` were changed to
+  support the new link API.
+
 * The functions ``rte_eth_dev_udp_tunnel_add`` and ``rte_eth_dev_udp_tunnel_delete``
   have been renamed into ``rte_eth_dev_udp_tunnel_port_add`` and
   ``rte_eth_dev_udp_tunnel_port_delete``.
diff --git a/drivers/net/af_packet/rte_eth_af_packet.c b/drivers/net/af_packet/rte_eth_af_packet.c
index ff0d299..d6b14e9 100644
--- a/drivers/net/af_packet/rte_eth_af_packet.c
+++ b/drivers/net/af_packet/rte_eth_af_packet.c
@@ -119,6 +119,7 @@ static struct rte_eth_link pmd_link = {
 	.link_speed = ETH_SPEED_NUM_10G,
 	.link_duplex = ETH_LINK_FULL_DUPLEX,
 	.link_status = ETH_LINK_DOWN,
+	.link_autoneg = ETH_LINK_SPEED_AUTONEG
 };
 
 static uint16_t
diff --git a/drivers/net/bnx2x/bnx2x_ethdev.c b/drivers/net/bnx2x/bnx2x_ethdev.c
index b86784e..d3d88a7 100644
--- a/drivers/net/bnx2x/bnx2x_ethdev.c
+++ b/drivers/net/bnx2x/bnx2x_ethdev.c
@@ -44,9 +44,9 @@ bnx2x_link_update(struct rte_eth_dev *dev)
 		case DUPLEX_HALF:
 			dev->data->dev_link.link_duplex = ETH_LINK_HALF_DUPLEX;
 			break;
-		default:
-			dev->data->dev_link.link_duplex = ETH_LINK_AUTONEG_DUPLEX;
 	}
+	dev->data->dev_link.link_autoneg = (dev->data->dev_conf.link_speeds &
+			ETH_LINK_SPEED_AUTONEG);
 	dev->data->dev_link.link_status = sc->link_vars.link_up;
 }
 
diff --git a/drivers/net/bonding/rte_eth_bond_8023ad.c b/drivers/net/bonding/rte_eth_bond_8023ad.c
index 5f9c9b3..3b446e1 100644
--- a/drivers/net/bonding/rte_eth_bond_8023ad.c
+++ b/drivers/net/bonding/rte_eth_bond_8023ad.c
@@ -708,7 +708,7 @@ link_speed_key(uint16_t speed) {
 	uint16_t key_speed;
 
 	switch (speed) {
-	case ETH_LINK_SPEED_AUTONEG:
+	case ETH_SPEED_NUM_NONE:
 		key_speed = 0x00;
 		break;
 	case ETH_SPEED_NUM_10M:
diff --git a/drivers/net/e1000/em_ethdev.c b/drivers/net/e1000/em_ethdev.c
index dddffff..d2f1b25 100644
--- a/drivers/net/e1000/em_ethdev.c
+++ b/drivers/net/e1000/em_ethdev.c
@@ -509,6 +509,9 @@ eth_em_start(struct rte_eth_dev *dev)
 	struct rte_intr_handle *intr_handle = &dev->pci_dev->intr_handle;
 	int ret, mask;
 	uint32_t intr_vector = 0;
+	uint32_t *speeds;
+	int num_speeds;
+	bool autoneg;
 
 	PMD_INIT_FUNC_TRACE();
 
@@ -583,56 +586,46 @@ eth_em_start(struct rte_eth_dev *dev)
 	E1000_WRITE_REG(hw, E1000_ITR, UINT16_MAX);
 
 	/* Setup link speed and duplex */
-	switch (dev->data->dev_conf.link_speed) {
-	case ETH_LINK_SPEED_AUTONEG:
-		if (dev->data->dev_conf.link_duplex == ETH_LINK_AUTONEG_DUPLEX)
-			hw->phy.autoneg_advertised = E1000_ALL_SPEED_DUPLEX;
-		else if (dev->data->dev_conf.link_duplex ==
-					ETH_LINK_HALF_DUPLEX)
-			hw->phy.autoneg_advertised = E1000_ALL_HALF_DUPLEX;
-		else if (dev->data->dev_conf.link_duplex ==
-					ETH_LINK_FULL_DUPLEX)
-			hw->phy.autoneg_advertised = E1000_ALL_FULL_DUPLEX;
-		else
-			goto error_invalid_config;
-		break;
-	case ETH_SPEED_NUM_10M:
-		if (dev->data->dev_conf.link_duplex == ETH_LINK_AUTONEG_DUPLEX)
-			hw->phy.autoneg_advertised = E1000_ALL_10_SPEED;
-		else if (dev->data->dev_conf.link_duplex ==
-					ETH_LINK_HALF_DUPLEX)
-			hw->phy.autoneg_advertised = ADVERTISE_10_HALF;
-		else if (dev->data->dev_conf.link_duplex ==
-					ETH_LINK_FULL_DUPLEX)
-			hw->phy.autoneg_advertised = ADVERTISE_10_FULL;
-		else
-			goto error_invalid_config;
-		break;
-	case ETH_SPEED_NUM_100M:
-		if (dev->data->dev_conf.link_duplex == ETH_LINK_AUTONEG_DUPLEX)
-			hw->phy.autoneg_advertised = E1000_ALL_100_SPEED;
-		else if (dev->data->dev_conf.link_duplex ==
-					ETH_LINK_HALF_DUPLEX)
-			hw->phy.autoneg_advertised = ADVERTISE_100_HALF;
-		else if (dev->data->dev_conf.link_duplex ==
-					ETH_LINK_FULL_DUPLEX)
-			hw->phy.autoneg_advertised = ADVERTISE_100_FULL;
-		else
+	speeds = &dev->data->dev_conf.link_speeds;
+	if (*speeds == ETH_LINK_SPEED_AUTONEG) {
+		hw->phy.autoneg_advertised = E1000_ALL_SPEED_DUPLEX;
+	} else {
+		num_speeds = 0;
+		autoneg = (*speeds & ETH_LINK_SPEED_AUTONEG);
+
+		/* Reset */
+		hw->phy.autoneg_advertised = 0;
+
+		if (*speeds & ~(ETH_LINK_SPEED_10M_HD | ETH_LINK_SPEED_10M |
+				ETH_LINK_SPEED_100M_HD | ETH_LINK_SPEED_100M |
+				ETH_LINK_SPEED_1G)) {
+			num_speeds = -1;
 			goto error_invalid_config;
-		break;
-	case ETH_SPEED_NUM_1G:
-		if ((dev->data->dev_conf.link_duplex ==
-				ETH_LINK_AUTONEG_DUPLEX) ||
-			(dev->data->dev_conf.link_duplex ==
-					ETH_LINK_FULL_DUPLEX))
-			hw->phy.autoneg_advertised = ADVERTISE_1000_FULL;
-		else
+		}
+		if (*speeds & ETH_LINK_SPEED_10M_HD) {
+			hw->phy.autoneg_advertised |= ADVERTISE_10_HALF;
+			num_speeds++;
+		}
+		if (*speeds & ETH_LINK_SPEED_10M) {
+			hw->phy.autoneg_advertised |= ADVERTISE_10_FULL;
+			num_speeds++;
+		}
+		if (*speeds & ETH_LINK_SPEED_100M_HD) {
+			hw->phy.autoneg_advertised |= ADVERTISE_100_HALF;
+			num_speeds++;
+		}
+		if (*speeds & ETH_LINK_SPEED_100M) {
+			hw->phy.autoneg_advertised |= ADVERTISE_100_FULL;
+			num_speeds++;
+		}
+		if (*speeds & ETH_LINK_SPEED_1G) {
+			hw->phy.autoneg_advertised |= ADVERTISE_1000_FULL;
+			num_speeds++;
+		}
+		if (num_speeds == 0 || (!autoneg && (num_speeds > 2)))
 			goto error_invalid_config;
-		break;
-	case ETH_SPEED_NUM_10G:
-	default:
-		goto error_invalid_config;
 	}
+
 	e1000_setup_link(hw);
 
 	if (rte_intr_allow_others(intr_handle)) {
@@ -665,9 +658,8 @@ eth_em_start(struct rte_eth_dev *dev)
 	return 0;
 
 error_invalid_config:
-	PMD_INIT_LOG(ERR, "Invalid link_speed/link_duplex (%u/%u) for port %u",
-		     dev->data->dev_conf.link_speed,
-		     dev->data->dev_conf.link_duplex, dev->data->port_id);
+	PMD_INIT_LOG(ERR, "Invalid advertised speeds (%u) for port %u",
+		     dev->data->dev_conf.link_speeds, dev->data->port_id);
 	em_dev_clear_queues(dev);
 	return -EINVAL;
 }
@@ -1075,8 +1067,11 @@ eth_em_link_update(struct rte_eth_dev *dev, int wait_to_complete)
 
 	/* Now we check if a transition has happened */
 	if (link_check && (link.link_status == 0)) {
-		hw->mac.ops.get_link_up_info(hw, &link.link_speed,
-			&link.link_duplex);
+		uint16_t duplex, speed;
+		hw->mac.ops.get_link_up_info(hw, &speed, &duplex);
+		link.link_duplex = duplex ? ETH_LINK_FULL_DUPLEX :
+				ETH_LINK_HALF_DUPLEX;
+		link.link_speed = speed;
 		link.link_status = ETH_LINK_UP;
 	} else if (!link_check && (link.link_status == ETH_LINK_UP)) {
 		link.link_speed = 0;
diff --git a/drivers/net/e1000/igb_ethdev.c b/drivers/net/e1000/igb_ethdev.c
index 743fe1b..ca82872 100644
--- a/drivers/net/e1000/igb_ethdev.c
+++ b/drivers/net/e1000/igb_ethdev.c
@@ -1121,6 +1121,9 @@ eth_igb_start(struct rte_eth_dev *dev)
 	int ret, mask;
 	uint32_t intr_vector = 0;
 	uint32_t ctrl_ext;
+	uint32_t *speeds;
+	int num_speeds;
+	bool autoneg;
 
 	PMD_INIT_FUNC_TRACE();
 
@@ -1221,48 +1224,46 @@ eth_igb_start(struct rte_eth_dev *dev)
 	}
 
 	/* Setup link speed and duplex */
-	switch (dev->data->dev_conf.link_speed) {
-	case ETH_LINK_SPEED_AUTONEG:
-		if (dev->data->dev_conf.link_duplex == ETH_LINK_AUTONEG_DUPLEX)
-			hw->phy.autoneg_advertised = E1000_ALL_SPEED_DUPLEX;
-		else if (dev->data->dev_conf.link_duplex == ETH_LINK_HALF_DUPLEX)
-			hw->phy.autoneg_advertised = E1000_ALL_HALF_DUPLEX;
-		else if (dev->data->dev_conf.link_duplex == ETH_LINK_FULL_DUPLEX)
-			hw->phy.autoneg_advertised = E1000_ALL_FULL_DUPLEX;
-		else
-			goto error_invalid_config;
-		break;
-	case ETH_SPEED_NUM_10M:
-		if (dev->data->dev_conf.link_duplex == ETH_LINK_AUTONEG_DUPLEX)
-			hw->phy.autoneg_advertised = E1000_ALL_10_SPEED;
-		else if (dev->data->dev_conf.link_duplex == ETH_LINK_HALF_DUPLEX)
-			hw->phy.autoneg_advertised = ADVERTISE_10_HALF;
-		else if (dev->data->dev_conf.link_duplex == ETH_LINK_FULL_DUPLEX)
-			hw->phy.autoneg_advertised = ADVERTISE_10_FULL;
-		else
-			goto error_invalid_config;
-		break;
-	case ETH_SPEED_NUM_100M:
-		if (dev->data->dev_conf.link_duplex == ETH_LINK_AUTONEG_DUPLEX)
-			hw->phy.autoneg_advertised = E1000_ALL_100_SPEED;
-		else if (dev->data->dev_conf.link_duplex == ETH_LINK_HALF_DUPLEX)
-			hw->phy.autoneg_advertised = ADVERTISE_100_HALF;
-		else if (dev->data->dev_conf.link_duplex == ETH_LINK_FULL_DUPLEX)
-			hw->phy.autoneg_advertised = ADVERTISE_100_FULL;
-		else
+	speeds = &dev->data->dev_conf.link_speeds;
+	if (*speeds == ETH_LINK_SPEED_AUTONEG) {
+		hw->phy.autoneg_advertised = E1000_ALL_SPEED_DUPLEX;
+	} else {
+		num_speeds = 0;
+		autoneg = (*speeds & ETH_LINK_SPEED_AUTONEG);
+
+		/* Reset */
+		hw->phy.autoneg_advertised = 0;
+
+		if (*speeds & ~(ETH_LINK_SPEED_10M_HD | ETH_LINK_SPEED_10M |
+				ETH_LINK_SPEED_100M_HD | ETH_LINK_SPEED_100M |
+				ETH_LINK_SPEED_1G)) {
+			num_speeds = -1;
 			goto error_invalid_config;
-		break;
-	case ETH_SPEED_NUM_1G:
-		if ((dev->data->dev_conf.link_duplex == ETH_LINK_AUTONEG_DUPLEX) ||
-				(dev->data->dev_conf.link_duplex == ETH_LINK_FULL_DUPLEX))
-			hw->phy.autoneg_advertised = ADVERTISE_1000_FULL;
-		else
+		}
+		if (*speeds & ETH_LINK_SPEED_10M_HD) {
+			hw->phy.autoneg_advertised |= ADVERTISE_10_HALF;
+			num_speeds++;
+		}
+		if (*speeds & ETH_LINK_SPEED_10M) {
+			hw->phy.autoneg_advertised |= ADVERTISE_10_FULL;
+			num_speeds++;
+		}
+		if (*speeds & ETH_LINK_SPEED_100M_HD) {
+			hw->phy.autoneg_advertised |= ADVERTISE_100_HALF;
+			num_speeds++;
+		}
+		if (*speeds & ETH_LINK_SPEED_100M) {
+			hw->phy.autoneg_advertised |= ADVERTISE_100_FULL;
+			num_speeds++;
+		}
+		if (*speeds & ETH_LINK_SPEED_1G) {
+			hw->phy.autoneg_advertised |= ADVERTISE_1000_FULL;
+			num_speeds++;
+		}
+		if (num_speeds == 0 || (!autoneg && (num_speeds > 2)))
 			goto error_invalid_config;
-		break;
-	case ETH_SPEED_NUM_10G:
-	default:
-		goto error_invalid_config;
 	}
+
 	e1000_setup_link(hw);
 
 	if (rte_intr_allow_others(intr_handle)) {
@@ -1294,9 +1295,8 @@ eth_igb_start(struct rte_eth_dev *dev)
 	return 0;
 
 error_invalid_config:
-	PMD_INIT_LOG(ERR, "Invalid link_speed/link_duplex (%u/%u) for port %u",
-		     dev->data->dev_conf.link_speed,
-		     dev->data->dev_conf.link_duplex, dev->data->port_id);
+	PMD_INIT_LOG(ERR, "Invalid advertised speeds (%u) for port %u",
+		     dev->data->dev_conf.link_speeds, dev->data->port_id);
 	igb_dev_clear_queues(dev);
 	return -EINVAL;
 }
@@ -2023,13 +2023,19 @@ eth_igb_link_update(struct rte_eth_dev *dev, int wait_to_complete)
 
 	/* Now we check if a transition has happened */
 	if (link_check) {
-		hw->mac.ops.get_link_up_info(hw, &link.link_speed,
-					  &link.link_duplex);
+		uint16_t duplex, speed;
+		hw->mac.ops.get_link_up_info(hw, &speed, &duplex);
+		link.link_duplex = duplex ? ETH_LINK_FULL_DUPLEX :
+				ETH_LINK_HALF_DUPLEX;
+		link.link_speed = speed;
 		link.link_status = ETH_LINK_UP;
+		link.link_autoneg = (dev->data->dev_conf.link_speeds &
+				ETH_LINK_SPEED_AUTONEG);
 	} else if (!link_check) {
 		link.link_speed = 0;
 		link.link_duplex = ETH_LINK_HALF_DUPLEX;
 		link.link_status = ETH_LINK_DOWN;
+		link.link_autoneg = ETH_LINK_SPEED_FIXED;
 	}
 	rte_igb_dev_atomic_write_link_status(dev, &link);
 
diff --git a/drivers/net/i40e/i40e_ethdev.c b/drivers/net/i40e/i40e_ethdev.c
index 3b2a4ae..a0aaca0 100644
--- a/drivers/net/i40e/i40e_ethdev.c
+++ b/drivers/net/i40e/i40e_ethdev.c
@@ -1358,27 +1358,20 @@ i40e_vsi_disable_queues_intr(struct i40e_vsi *vsi)
 }
 
 static inline uint8_t
-i40e_parse_link_speed(uint16_t eth_link_speed)
+i40e_parse_link_speeds(uint16_t link_speeds)
 {
 	uint8_t link_speed = I40E_LINK_SPEED_UNKNOWN;
 
-	switch (eth_link_speed) {
-	case ETH_SPEED_NUM_40G:
-		link_speed = I40E_LINK_SPEED_40GB;
-		break;
-	case ETH_SPEED_NUM_20G:
-		link_speed = I40E_LINK_SPEED_20GB;
-		break;
-	case ETH_SPEED_NUM_10G:
-		link_speed = I40E_LINK_SPEED_10GB;
-		break;
-	case ETH_SPEED_NUM_1G:
-		link_speed = I40E_LINK_SPEED_1GB;
-		break;
-	case ETH_SPEED_NUM_100M:
-		link_speed = I40E_LINK_SPEED_100MB;
-		break;
-	}
+	if (link_speeds & ETH_LINK_SPEED_40G)
+		link_speed |= I40E_LINK_SPEED_40GB;
+	if (link_speeds & ETH_LINK_SPEED_20G)
+		link_speed |= I40E_LINK_SPEED_20GB;
+	if (link_speeds & ETH_LINK_SPEED_10G)
+		link_speed |= I40E_LINK_SPEED_10GB;
+	if (link_speeds & ETH_LINK_SPEED_1G)
+		link_speed |= I40E_LINK_SPEED_1GB;
+	if (link_speeds & ETH_LINK_SPEED_100M)
+		link_speed |= I40E_LINK_SPEED_100MB;
 
 	return link_speed;
 }
@@ -1404,9 +1397,9 @@ i40e_apply_link_speed(struct rte_eth_dev *dev)
 	struct i40e_hw *hw = I40E_DEV_PRIVATE_TO_HW(dev->data->dev_private);
 	struct rte_eth_conf *conf = &dev->data->dev_conf;
 
-	speed = i40e_parse_link_speed(conf->link_speed);
+	speed = i40e_parse_link_speeds(conf->link_speeds);
 	abilities |= I40E_AQ_PHY_ENABLE_ATOMIC_LINK;
-	if (conf->link_speed == ETH_LINK_SPEED_AUTONEG)
+	if (conf->link_speeds & ETH_LINK_SPEED_AUTONEG)
 		abilities |= I40E_AQ_PHY_AN_ENABLED;
 	else
 		abilities |= I40E_AQ_PHY_LINK_ENABLED;
@@ -1426,10 +1419,8 @@ i40e_dev_start(struct rte_eth_dev *dev)
 
 	hw->adapter_stopped = 0;
 
-	if ((dev->data->dev_conf.link_duplex != ETH_LINK_AUTONEG_DUPLEX) &&
-		(dev->data->dev_conf.link_duplex != ETH_LINK_FULL_DUPLEX)) {
-		PMD_INIT_LOG(ERR, "Invalid link_duplex (%hu) for port %hhu",
-			     dev->data->dev_conf.link_duplex,
+	if (!(dev->data->dev_conf.link_speeds & ETH_LINK_SPEED_AUTONEG)) {
+		PMD_INIT_LOG(ERR, "Invalid link_speeds for port %hhu; autonegotiation disabled",
 			     dev->data->port_id);
 		return -EINVAL;
 	}
@@ -1502,6 +1493,12 @@ i40e_dev_start(struct rte_eth_dev *dev)
 	}
 
 	/* Apply link configure */
+	if (dev->data->dev_conf.link_speeds & ~(ETH_LINK_SPEED_100M |
+				ETH_LINK_SPEED_1G | ETH_LINK_SPEED_10G |
+				ETH_LINK_SPEED_20G | ETH_LINK_SPEED_40G)) {
+		PMD_DRV_LOG(ERR, "Invalid link setting");
+		goto err_up;
+	}
 	ret = i40e_apply_link_speed(dev);
 	if (I40E_SUCCESS != ret) {
 		PMD_DRV_LOG(ERR, "Fail to apply link setting");
@@ -1786,6 +1783,9 @@ i40e_dev_link_update(struct rte_eth_dev *dev,
 		break;
 	}
 
+	link.link_autoneg = (dev->data->dev_conf.link_speeds &
+			ETH_LINK_SPEED_AUTONEG);
+
 out:
 	rte_i40e_dev_atomic_write_link_status(dev, &link);
 	if (link.link_status == old.link_status)
diff --git a/drivers/net/i40e/i40e_ethdev_vf.c b/drivers/net/i40e/i40e_ethdev_vf.c
index 7ac5c48..03c03ea 100644
--- a/drivers/net/i40e/i40e_ethdev_vf.c
+++ b/drivers/net/i40e/i40e_ethdev_vf.c
@@ -1911,12 +1911,13 @@ i40evf_dev_link_update(struct rte_eth_dev *dev,
 	 * DPDK pf host provide interfacet to acquire link status
 	 * while Linux driver does not
 	 */
-	if (vf->version_major == I40E_DPDK_VERSION_MAJOR)
+	if (vf->version_major == I40E_DPDK_VERSION_MAJOR) {
 		i40evf_get_link_status(dev, &new_link);
-	else {
+	} else {
 		/* Always assume it's up, for Linux driver PF host */
-		new_link.link_duplex = ETH_LINK_AUTONEG_DUPLEX;
 		new_link.link_speed  = ETH_SPEED_NUM_10G;
+		new_link.link_duplex = ETH_LINK_FULL_DUPLEX;
+		new_link.link_autoneg = ETH_LINK_SPEED_AUTONEG;
 		new_link.link_status = ETH_LINK_UP;
 	}
 	i40evf_dev_atomic_write_link_status(dev, &new_link);
diff --git a/drivers/net/ixgbe/ixgbe_ethdev.c b/drivers/net/ixgbe/ixgbe_ethdev.c
index 1c108a0..7f150e5 100644
--- a/drivers/net/ixgbe/ixgbe_ethdev.c
+++ b/drivers/net/ixgbe/ixgbe_ethdev.c
@@ -2035,14 +2035,13 @@ ixgbe_dev_start(struct rte_eth_dev *dev)
 	int mask = 0;
 	int status;
 	uint16_t vf, idx;
+	uint32_t *link_speeds;
 
 	PMD_INIT_FUNC_TRACE();
 
 	/* IXGBE devices don't support half duplex */
-	if ((dev->data->dev_conf.link_duplex != ETH_LINK_AUTONEG_DUPLEX) &&
-			(dev->data->dev_conf.link_duplex != ETH_LINK_FULL_DUPLEX)) {
-		PMD_INIT_LOG(ERR, "Invalid link_duplex (%hu) for port %hhu",
-			     dev->data->dev_conf.link_duplex,
+	if (!(dev->data->dev_conf.link_speeds & ETH_LINK_SPEED_AUTONEG)) {
+		PMD_INIT_LOG(ERR, "Invalid link_speeds for port %hhu; autonegotiation disabled",
 			     dev->data->port_id);
 		return -EINVAL;
 	}
@@ -2132,32 +2131,21 @@ ixgbe_dev_start(struct rte_eth_dev *dev)
 	if (err)
 		goto error;
 
-	switch(dev->data->dev_conf.link_speed) {
-	case ETH_LINK_SPEED_AUTONEG:
-		speed = (hw->mac.type != ixgbe_mac_82598EB) ?
-				IXGBE_LINK_SPEED_82599_AUTONEG :
-				IXGBE_LINK_SPEED_82598_AUTONEG;
-		break;
-	case ETH_SPEED_NUM_100M:
-		/*
-		 * Invalid for 82598 but error will be detected by
-		 * ixgbe_setup_link()
-		 */
-		speed = IXGBE_LINK_SPEED_100_FULL;
-		break;
-	case ETH_SPEED_NUM_1G:
-		speed = IXGBE_LINK_SPEED_1GB_FULL;
-		break;
-	case ETH_SPEED_NUM_10G:
-		speed = IXGBE_LINK_SPEED_10GB_FULL;
-		break;
-	default:
-		PMD_INIT_LOG(ERR, "Invalid link_speed (%hu) for port %hhu",
-			     dev->data->dev_conf.link_speed,
-			     dev->data->port_id);
+	link_speeds = &dev->data->dev_conf.link_speeds;
+	if (*link_speeds & ~(ETH_LINK_SPEED_100M | ETH_LINK_SPEED_1G |
+			ETH_LINK_SPEED_10G)) {
+		PMD_INIT_LOG(ERR, "Invalid link setting");
 		goto error;
 	}
 
+	speed = 0x0;
+	if (*link_speeds & ETH_LINK_SPEED_10G)
+		speed |= IXGBE_LINK_SPEED_10GB_FULL;
+	if (*link_speeds & ETH_LINK_SPEED_1G)
+		speed |= IXGBE_LINK_SPEED_1GB_FULL;
+	if (*link_speeds & ETH_LINK_SPEED_100M)
+		speed |= IXGBE_LINK_SPEED_100_FULL;
+
 	err = ixgbe_setup_link(hw, speed, link_up);
 	if (err)
 		goto error;
@@ -2981,7 +2969,7 @@ ixgbe_dev_link_update(struct rte_eth_dev *dev, int wait_to_complete)
 
 	if (diag != 0) {
 		link.link_speed = ETH_SPEED_NUM_100M;
-		link.link_duplex = ETH_LINK_HALF_DUPLEX;
+		link.link_duplex = ETH_LINK_FULL_DUPLEX;
 		rte_ixgbe_dev_atomic_write_link_status(dev, &link);
 		if (link.link_status == old.link_status)
 			return -1;
@@ -3000,7 +2988,7 @@ ixgbe_dev_link_update(struct rte_eth_dev *dev, int wait_to_complete)
 	switch (link_speed) {
 	default:
 	case IXGBE_LINK_SPEED_UNKNOWN:
-		link.link_duplex = ETH_LINK_HALF_DUPLEX;
+		link.link_duplex = ETH_LINK_FULL_DUPLEX;
 		link.link_speed = ETH_SPEED_NUM_100M;
 		break;
 
diff --git a/drivers/net/mlx4/mlx4.c b/drivers/net/mlx4/mlx4.c
index 7397cbf..54f8c70 100644
--- a/drivers/net/mlx4/mlx4.c
+++ b/drivers/net/mlx4/mlx4.c
@@ -4634,6 +4634,8 @@ mlx4_link_update_unlocked(struct rte_eth_dev *dev, int wait_to_complete)
 		dev_link.link_speed = link_speed;
 	dev_link.link_duplex = ((edata.duplex == DUPLEX_HALF) ?
 				ETH_LINK_HALF_DUPLEX : ETH_LINK_FULL_DUPLEX);
+	dev_link.link_autoneg = (dev->data->dev_conf.link_speeds &
+			ETH_LINK_SPEED_AUTONEG);
 	if (memcmp(&dev_link, &dev->data->dev_link, sizeof(dev_link))) {
 		/* Link status changed. */
 		dev->data->dev_link = dev_link;
diff --git a/drivers/net/mpipe/mpipe_tilegx.c b/drivers/net/mpipe/mpipe_tilegx.c
index fc1f90d..1ca05c2 100644
--- a/drivers/net/mpipe/mpipe_tilegx.c
+++ b/drivers/net/mpipe/mpipe_tilegx.c
@@ -388,6 +388,8 @@ mpipe_link_update(struct rte_eth_dev *dev, int wait_to_complete)
 
 		speed = state & GXIO_MPIPE_LINK_SPEED_MASK;
 
+		new.link_autoneg = (dev->data->dev_conf.link_speeds &
+				ETH_LINK_SPEED_AUTONEG);
 		if (speed == GXIO_MPIPE_LINK_1G) {
 			new.link_speed = ETH_SPEED_NUM_1G;
 			new.link_duplex = ETH_LINK_FULL_DUPLEX;
diff --git a/drivers/net/null/rte_eth_null.c b/drivers/net/null/rte_eth_null.c
index 3f37c54..fa06b9d 100644
--- a/drivers/net/null/rte_eth_null.c
+++ b/drivers/net/null/rte_eth_null.c
@@ -96,6 +96,7 @@ static struct rte_eth_link pmd_link = {
 	.link_speed = ETH_SPEED_NUM_10G,
 	.link_duplex = ETH_LINK_FULL_DUPLEX,
 	.link_status = ETH_LINK_DOWN,
+	.link_autoneg = ETH_LINK_SPEED_AUTONEG,
 };
 
 static uint16_t
diff --git a/drivers/net/pcap/rte_eth_pcap.c b/drivers/net/pcap/rte_eth_pcap.c
index 5251b9f..650b521 100644
--- a/drivers/net/pcap/rte_eth_pcap.c
+++ b/drivers/net/pcap/rte_eth_pcap.c
@@ -128,6 +128,7 @@ static struct rte_eth_link pmd_link = {
 		.link_speed = ETH_SPEED_NUM_10G,
 		.link_duplex = ETH_LINK_FULL_DUPLEX,
 		.link_status = ETH_LINK_DOWN,
+		.link_autoneg = ETH_LINK_SPEED_FIXED,
 };
 
 static int
diff --git a/drivers/net/ring/rte_eth_ring.c b/drivers/net/ring/rte_eth_ring.c
index bd18508..8c0bf7b 100644
--- a/drivers/net/ring/rte_eth_ring.c
+++ b/drivers/net/ring/rte_eth_ring.c
@@ -74,6 +74,7 @@ static struct rte_eth_link pmd_link = {
 		.link_speed = ETH_SPEED_NUM_10G,
 		.link_duplex = ETH_LINK_FULL_DUPLEX,
 		.link_status = ETH_LINK_DOWN,
+		.link_autoneg = ETH_LINK_SPEED_AUTONEG
 };
 
 static uint16_t
diff --git a/drivers/net/szedata2/rte_eth_szedata2.c b/drivers/net/szedata2/rte_eth_szedata2.c
index 9d46987..38be554 100644
--- a/drivers/net/szedata2/rte_eth_szedata2.c
+++ b/drivers/net/szedata2/rte_eth_szedata2.c
@@ -111,7 +111,7 @@ static struct ether_addr eth_addr = {
 };
 static const char *drivername = "SZEdata2 PMD";
 static struct rte_eth_link pmd_link = {
-		.link_speed = ETH_SPEED_NUM_10G,
+		.link_speed = ETH_LINK_SPEED_10G,
 		.link_duplex = ETH_LINK_FULL_DUPLEX,
 		.link_status = ETH_LINK_DOWN
 };
diff --git a/drivers/net/vmxnet3/vmxnet3_ethdev.c b/drivers/net/vmxnet3/vmxnet3_ethdev.c
index 64a035c..2bb6ee9 100644
--- a/drivers/net/vmxnet3/vmxnet3_ethdev.c
+++ b/drivers/net/vmxnet3/vmxnet3_ethdev.c
@@ -739,6 +739,7 @@ vmxnet3_dev_link_update(struct rte_eth_dev *dev, __attribute__((unused)) int wai
 		link.link_status = ETH_LINK_UP;
 		link.link_duplex = ETH_LINK_FULL_DUPLEX;
 		link.link_speed = ETH_SPEED_NUM_10G;
+		link.link_autoneg = ETH_LINK_SPEED_FIXED;
 	}
 
 	vmxnet3_dev_atomic_write_link_status(dev, &link);
diff --git a/drivers/net/xenvirt/rte_eth_xenvirt.c b/drivers/net/xenvirt/rte_eth_xenvirt.c
index 77d3ba1..b9638d9 100644
--- a/drivers/net/xenvirt/rte_eth_xenvirt.c
+++ b/drivers/net/xenvirt/rte_eth_xenvirt.c
@@ -73,6 +73,7 @@ static struct rte_eth_link pmd_link = {
 		.link_speed = ETH_SPEED_NUM_10G,
 		.link_duplex = ETH_LINK_FULL_DUPLEX,
 		.link_status = ETH_LINK_DOWN,
+		.link_autoneg = ETH_LINK_SPEED_FIXED
 };
 
 static void
diff --git a/examples/ip_pipeline/config_parse.c b/examples/ip_pipeline/config_parse.c
index e39c23e..28112f7 100644
--- a/examples/ip_pipeline/config_parse.c
+++ b/examples/ip_pipeline/config_parse.c
@@ -87,8 +87,7 @@ static const struct app_link_params link_params_default = {
 	.pci_bdf = {0},
 
 	.conf = {
-		.link_speed = 0,
-		.link_duplex = 0,
+		.link_speeds = 0,
 		.rxmode = {
 			.mq_mode = ETH_MQ_RX_NONE,
 
diff --git a/lib/librte_ether/rte_ethdev.h b/lib/librte_ether/rte_ethdev.h
index 017e24b..08881de 100644
--- a/lib/librte_ether/rte_ethdev.h
+++ b/lib/librte_ether/rte_ethdev.h
@@ -244,6 +244,8 @@ struct rte_eth_stats {
 /**
  * Device supported speeds bitmap flags
  */
+#define ETH_LINK_SPEED_FIXED    (0 <<  0)  /**< Disable autoneg (fixed speed) */
+#define ETH_LINK_SPEED_AUTONEG  (1 <<  0)  /**< Autonegotiate (all speeds) */
 #define ETH_LINK_SPEED_10M_HD   (1 <<  1)  /**<  10 Mbps half-duplex */
 #define ETH_LINK_SPEED_10M      (1 <<  2)  /**<  10 Mbps full-duplex */
 #define ETH_LINK_SPEED_100M_HD  (1 <<  3)  /**< 100 Mbps half-duplex */
@@ -261,7 +263,7 @@ struct rte_eth_stats {
 /**
  * Ethernet numeric link speeds in Mbps
  */
-#define ETH_LINK_SPEED_AUTONEG     0 /**< Auto-negotiate link speed. */
+#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 */
@@ -278,15 +280,15 @@ struct rte_eth_stats {
  * A structure used to retrieve link-level information of an Ethernet port.
  */
 struct rte_eth_link {
-	uint16_t link_speed;      /**< ETH_SPEED_NUM_ */
-	uint16_t link_duplex;     /**< ETH_LINK_[HALF/FULL]_DUPLEX */
-	uint8_t  link_status : 1; /**< ETH_LINK_[DOWN/UP] */
-}__attribute__((aligned(8)));     /**< aligned for atomic64 read/write */
+	uint16_t link_speed;        /**< ETH_SPEED_NUM_ */
+	uint16_t link_duplex  : 1;  /**< ETH_LINK_[HALF/FULL]_DUPLEX */
+	uint16_t link_autoneg : 1;  /**< ETH_LINK_SPEED_[AUTONEG/FIXED] */
+	uint16_t link_status  : 1;  /**< ETH_LINK_[DOWN/UP] */
+} __attribute__((aligned(8)));      /**< aligned for atomic64 read/write */
 
 /* Utility constants */
-#define ETH_LINK_AUTONEG_DUPLEX 0       /**< Auto-negotiate duplex. */
-#define ETH_LINK_HALF_DUPLEX    1       /**< Half-duplex connection. */
-#define ETH_LINK_FULL_DUPLEX    2       /**< Full-duplex connection. */
+#define ETH_LINK_HALF_DUPLEX    0 /**< Half-duplex connection. */
+#define ETH_LINK_FULL_DUPLEX    1 /**< Full-duplex connection. */
 #define ETH_LINK_DOWN           0 /**< Link is down. */
 #define ETH_LINK_UP             1 /**< Link is up. */
 
@@ -802,10 +804,13 @@ struct rte_intr_conf {
  * configuration settings may be needed.
  */
 struct rte_eth_conf {
-	uint16_t link_speed;
-	/**< ETH_SPEED_NUM_ or 0 for autonegotiation */
-	uint16_t link_duplex;
-	/**< ETH_LINK_[HALF_DUPLEX|FULL_DUPLEX], or 0 for autonegotation */
+	uint32_t link_speeds; /**< bitmap of ETH_LINK_SPEED_XXX of speeds to be
+				used. ETH_LINK_SPEED_FIXED disables link
+				autonegotiation, and a unique speed shall be
+				set. Otherwise, the bitmap defines the set of
+				speeds to be advertised. If the special value
+				ETH_LINK_SPEED_AUTONEG (0) is used, all speeds
+				supported are advertised. */
 	struct rte_eth_rxmode rxmode; /**< Port RX configuration. */
 	struct rte_eth_txmode txmode; /**< Port TX configuration. */
 	uint32_t lpbk_mode; /**< Loopback operation mode. By default the value
-- 
2.7.0

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

* [PATCH v10 7/8] ethdev: convert speed number to bitmap flag
  2016-03-14 21:55         ` [PATCH v10 0/8] ethdev: 100G and link speed API refactoring Thomas Monjalon
                             ` (5 preceding siblings ...)
  2016-03-14 21:55           ` [PATCH v10 6/8] ethdev: redesign link speed config Thomas Monjalon
@ 2016-03-14 21:55           ` Thomas Monjalon
  2016-03-14 21:55           ` [PATCH v10 8/8] ethdev: add 100G link speed Thomas Monjalon
                             ` (4 subsequent siblings)
  11 siblings, 0 replies; 167+ messages in thread
From: Thomas Monjalon @ 2016-03-14 21:55 UTC (permalink / raw)
  To: marcdevel, bruce.richardson, declan.doherty, konstantin.ananyev,
	wenzhuo.lu, helin.zhang, jing.d.chen, harish.patil,
	rahul.lakkireddy, johndale, vido, adrien.mazarguil,
	alejandro.lucero
  Cc: dev

From: Marc Sune <marcdevel@gmail.com>

It is a helper for the bitmap configuration.

Signed-off-by: Marc Sune <marcdevel@gmail.com>
Signed-off-by: Thomas Monjalon <thomas.monjalon@6wind.com>
---
 lib/librte_ether/rte_ethdev.c          | 31 +++++++++++++++++++++++++++++++
 lib/librte_ether/rte_ethdev.h          | 13 +++++++++++++
 lib/librte_ether/rte_ether_version.map |  1 +
 3 files changed, 45 insertions(+)

diff --git a/lib/librte_ether/rte_ethdev.c b/lib/librte_ether/rte_ethdev.c
index f0e7473..4594f41 100644
--- a/lib/librte_ether/rte_ethdev.c
+++ b/lib/librte_ether/rte_ethdev.c
@@ -862,6 +862,37 @@ rte_eth_dev_tx_queue_config(struct rte_eth_dev *dev, uint16_t nb_queues)
 	return 0;
 }
 
+uint32_t
+rte_eth_speed_bitflag(uint32_t speed, int duplex)
+{
+	switch (speed) {
+	case ETH_SPEED_NUM_10M:
+		return duplex ? ETH_LINK_SPEED_10M : ETH_LINK_SPEED_10M_HD;
+	case ETH_SPEED_NUM_100M:
+		return duplex ? ETH_LINK_SPEED_100M : ETH_LINK_SPEED_100M_HD;
+	case ETH_SPEED_NUM_1G:
+		return ETH_LINK_SPEED_1G;
+	case ETH_SPEED_NUM_2_5G:
+		return ETH_LINK_SPEED_2_5G;
+	case ETH_SPEED_NUM_5G:
+		return ETH_LINK_SPEED_5G;
+	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;
+	default:
+		return 0;
+	}
+}
+
 int
 rte_eth_dev_configure(uint8_t port_id, uint16_t nb_rx_q, uint16_t nb_tx_q,
 		      const struct rte_eth_conf *dev_conf)
diff --git a/lib/librte_ether/rte_ethdev.h b/lib/librte_ether/rte_ethdev.h
index 08881de..5e3bd04 100644
--- a/lib/librte_ether/rte_ethdev.h
+++ b/lib/librte_ether/rte_ethdev.h
@@ -1869,6 +1869,19 @@ struct eth_driver {
 void rte_eth_driver_register(struct eth_driver *eth_drv);
 
 /**
+ * Convert a numerical speed in Mbps to a bitmap flag that can be used in
+ * the bitmap link_speeds of the struct rte_eth_conf
+ *
+ * @param speed
+ *   Numerical speed value in Mbps
+ * @param duplex
+ *   ETH_LINK_[HALF/FULL]_DUPLEX (only for 10/100M speeds)
+ * @return
+ *   0 if the speed cannot be mapped
+ */
+uint32_t rte_eth_speed_bitflag(uint32_t speed, int duplex);
+
+/**
  * Configure an Ethernet device.
  * This function must be invoked first before any other function in the
  * Ethernet API. This function can also be re-invoked when a device is in the
diff --git a/lib/librte_ether/rte_ether_version.map b/lib/librte_ether/rte_ether_version.map
index 5cb4d79..13d9f2e 100644
--- a/lib/librte_ether/rte_ether_version.map
+++ b/lib/librte_ether/rte_ether_version.map
@@ -124,6 +124,7 @@ DPDK_16.04 {
 	rte_eth_dev_set_vlan_ether_type;
 	rte_eth_dev_udp_tunnel_port_add;
 	rte_eth_dev_udp_tunnel_port_delete;
+	rte_eth_speed_bitflag;
 	rte_eth_tx_buffer_count_callback;
 	rte_eth_tx_buffer_drop_callback;
 	rte_eth_tx_buffer_init;
-- 
2.7.0

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

* [PATCH v10 8/8] ethdev: add 100G link speed
  2016-03-14 21:55         ` [PATCH v10 0/8] ethdev: 100G and link speed API refactoring Thomas Monjalon
                             ` (6 preceding siblings ...)
  2016-03-14 21:55           ` [PATCH v10 7/8] ethdev: convert speed number to bitmap flag Thomas Monjalon
@ 2016-03-14 21:55           ` Thomas Monjalon
  2016-03-15  0:04           ` [PATCH v10 0/8] ethdev: 100G and link speed API refactoring Matej Vido
                             ` (3 subsequent siblings)
  11 siblings, 0 replies; 167+ messages in thread
From: Thomas Monjalon @ 2016-03-14 21:55 UTC (permalink / raw)
  To: marcdevel, bruce.richardson, declan.doherty, konstantin.ananyev,
	wenzhuo.lu, helin.zhang, jing.d.chen, harish.patil,
	rahul.lakkireddy, johndale, vido, adrien.mazarguil,
	alejandro.lucero
  Cc: dev

The link speed configuration is now done with bitmaps so 100G speed
requires only a new bit flag.
The actual link speed is a number so its size must be increased from
16-bit to 32-bit.

Signed-off-by: Marc Sune <marcdevel@gmail.com>
Tested-by: Nelio Laranjeiro <nelio.laranjeiro@6wind.com>
Signed-off-by: Thomas Monjalon <thomas.monjalon@6wind.com>
---
 app/test-pmd/cmdline.c                      | 12 +++++++-----
 doc/guides/rel_notes/release_16_04.rst      |  5 +++++
 doc/guides/testpmd_app_ug/testpmd_funcs.rst |  2 +-
 drivers/net/fm10k/fm10k_ethdev.c            |  2 +-
 drivers/net/mlx5/mlx5_ethdev.c              |  2 +-
 drivers/net/nfp/nfp_net.c                   |  2 +-
 drivers/net/szedata2/rte_eth_szedata2.c     |  1 +
 lib/librte_ether/rte_ethdev.c               |  2 ++
 lib/librte_ether/rte_ethdev.h               |  4 +++-
 9 files changed, 22 insertions(+), 10 deletions(-)

diff --git a/app/test-pmd/cmdline.c b/app/test-pmd/cmdline.c
index 3bc7bb4..3337b7b 100644
--- a/app/test-pmd/cmdline.c
+++ b/app/test-pmd/cmdline.c
@@ -549,7 +549,7 @@ static void cmd_help_long_parsed(void *parsed_result,
 			"    Detach physical or virtual dev by port_id\n\n"
 
 			"port config (port_id|all)"
-			" speed (10|100|1000|10000|40000|auto)"
+			" speed (10|100|1000|10000|40000|100000|auto)"
 			" duplex (half|full|auto)\n"
 			"    Set speed and duplex for all ports or port_id\n\n"
 
@@ -1017,6 +1017,8 @@ parse_and_check_speed_duplex(char *speedstr, char *duplexstr, uint32_t *speed)
 			*speed = ETH_LINK_SPEED_10G;
 		} else if (!strcmp(speedstr, "40000")) {
 			*speed = ETH_LINK_SPEED_40G;
+		} else if (!strcmp(speedstr, "100000")) {
+			*speed = ETH_LINK_SPEED_100G;
 		} else if (!strcmp(speedstr, "auto")) {
 			*speed = ETH_LINK_SPEED_AUTONEG;
 		} else {
@@ -1064,7 +1066,7 @@ cmdline_parse_token_string_t cmd_config_speed_all_item1 =
 	TOKEN_STRING_INITIALIZER(struct cmd_config_speed_all, item1, "speed");
 cmdline_parse_token_string_t cmd_config_speed_all_value1 =
 	TOKEN_STRING_INITIALIZER(struct cmd_config_speed_all, value1,
-						"10#100#1000#10000#40000#auto");
+						"10#100#1000#10000#40000#100000#auto");
 cmdline_parse_token_string_t cmd_config_speed_all_item2 =
 	TOKEN_STRING_INITIALIZER(struct cmd_config_speed_all, item2, "duplex");
 cmdline_parse_token_string_t cmd_config_speed_all_value2 =
@@ -1074,7 +1076,7 @@ cmdline_parse_token_string_t cmd_config_speed_all_value2 =
 cmdline_parse_inst_t cmd_config_speed_all = {
 	.f = cmd_config_speed_all_parsed,
 	.data = NULL,
-	.help_str = "port config all speed 10|100|1000|10000|40000|auto duplex "
+	.help_str = "port config all speed 10|100|1000|10000|40000|100000|auto duplex "
 							"half|full|auto",
 	.tokens = {
 		(void *)&cmd_config_speed_all_port,
@@ -1138,7 +1140,7 @@ cmdline_parse_token_string_t cmd_config_speed_specific_item1 =
 								"speed");
 cmdline_parse_token_string_t cmd_config_speed_specific_value1 =
 	TOKEN_STRING_INITIALIZER(struct cmd_config_speed_specific, value1,
-						"10#100#1000#10000#40000#auto");
+						"10#100#1000#10000#40000#100000#auto");
 cmdline_parse_token_string_t cmd_config_speed_specific_item2 =
 	TOKEN_STRING_INITIALIZER(struct cmd_config_speed_specific, item2,
 								"duplex");
@@ -1149,7 +1151,7 @@ cmdline_parse_token_string_t cmd_config_speed_specific_value2 =
 cmdline_parse_inst_t cmd_config_speed_specific = {
 	.f = cmd_config_speed_specific_parsed,
 	.data = NULL,
-	.help_str = "port config X speed 10|100|1000|10000|40000|auto duplex "
+	.help_str = "port config X speed 10|100|1000|10000|40000|100000|auto duplex "
 							"half|full|auto",
 	.tokens = {
 		(void *)&cmd_config_speed_specific_port,
diff --git a/doc/guides/rel_notes/release_16_04.rst b/doc/guides/rel_notes/release_16_04.rst
index f6d00f5..4700899 100644
--- a/doc/guides/rel_notes/release_16_04.rst
+++ b/doc/guides/rel_notes/release_16_04.rst
@@ -157,6 +157,11 @@ EAL
 Drivers
 ~~~~~~~
 
+* **ethdev: Fixed overflow for 100Gbps.**
+
+  100Gbps in Mbps (100000) was exceeding 16-bit max value of ``link_speed``
+  in ``rte_eth_link``.
+
 * **ethdev: Fixed byte order consistency between fdir flow and mask.**
 
   Fixed issue in ethdev library that the structure for setting
diff --git a/doc/guides/testpmd_app_ug/testpmd_funcs.rst b/doc/guides/testpmd_app_ug/testpmd_funcs.rst
index efaf2b5..cb49495 100644
--- a/doc/guides/testpmd_app_ug/testpmd_funcs.rst
+++ b/doc/guides/testpmd_app_ug/testpmd_funcs.rst
@@ -1155,7 +1155,7 @@ port config - speed
 
 Set the speed and duplex mode for all ports or a specific port::
 
-   testpmd> port config (port_id|all) speed (10|100|1000|10000|auto) \
+   testpmd> port config (port_id|all) speed (10|100|1000|10000|40000|100000|auto) \
             duplex (half|full|auto)
 
 port config - queues/descriptors
diff --git a/drivers/net/fm10k/fm10k_ethdev.c b/drivers/net/fm10k/fm10k_ethdev.c
index 4d8c6bf..b4a0523 100644
--- a/drivers/net/fm10k/fm10k_ethdev.c
+++ b/drivers/net/fm10k/fm10k_ethdev.c
@@ -1336,7 +1336,7 @@ fm10k_dev_infos_get(struct rte_eth_dev *dev,
 
 	dev_info->speed_capa = ETH_LINK_SPEED_1G | ETH_LINK_SPEED_2_5G |
 			ETH_LINK_SPEED_10G | ETH_LINK_SPEED_25G |
-			ETH_LINK_SPEED_40G;
+			ETH_LINK_SPEED_40G | ETH_LINK_SPEED_100G;
 }
 
 static int
diff --git a/drivers/net/mlx5/mlx5_ethdev.c b/drivers/net/mlx5/mlx5_ethdev.c
index 7494f69..6f82a3d 100644
--- a/drivers/net/mlx5/mlx5_ethdev.c
+++ b/drivers/net/mlx5/mlx5_ethdev.c
@@ -525,7 +525,7 @@ mlx5_dev_infos_get(struct rte_eth_dev *dev, struct rte_eth_dev_info *info)
 	info->reta_size = priv->ind_table_max_size;
 	info->speed_capa = ETH_LINK_SPEED_1G | ETH_LINK_SPEED_10G |
 			ETH_LINK_SPEED_25G | ETH_LINK_SPEED_40G |
-			ETH_LINK_SPEED_50G;
+			ETH_LINK_SPEED_50G | ETH_LINK_SPEED_100G;
 	priv_unlock(priv);
 }
 
diff --git a/drivers/net/nfp/nfp_net.c b/drivers/net/nfp/nfp_net.c
index be1a364..00f0ce9 100644
--- a/drivers/net/nfp/nfp_net.c
+++ b/drivers/net/nfp/nfp_net.c
@@ -1072,7 +1072,7 @@ nfp_net_infos_get(struct rte_eth_dev *dev, struct rte_eth_dev_info *dev_info)
 	dev_info->reta_size = NFP_NET_CFG_RSS_ITBL_SZ;
 	dev_info->hash_key_size = NFP_NET_CFG_RSS_KEY_SZ;
 
-	dev_info->speed_capa = ETH_LINK_SPEED_50G;
+	dev_info->speed_capa = ETH_LINK_SPEED_50G | ETH_LINK_SPEED_100G;
 }
 
 static uint32_t
diff --git a/drivers/net/szedata2/rte_eth_szedata2.c b/drivers/net/szedata2/rte_eth_szedata2.c
index 38be554..fa7c09d 100644
--- a/drivers/net/szedata2/rte_eth_szedata2.c
+++ b/drivers/net/szedata2/rte_eth_szedata2.c
@@ -1218,6 +1218,7 @@ eth_dev_info(struct rte_eth_dev *dev,
 	dev_info->max_tx_queues = (uint16_t)internals->nb_tx_queues;
 	dev_info->min_rx_bufsize = 0;
 	dev_info->pci_dev = NULL;
+	dev_info->speed_capa = ETH_LINK_SPEED_100G;
 }
 
 static void
diff --git a/lib/librte_ether/rte_ethdev.c b/lib/librte_ether/rte_ethdev.c
index 4594f41..ab39296 100644
--- a/lib/librte_ether/rte_ethdev.c
+++ b/lib/librte_ether/rte_ethdev.c
@@ -888,6 +888,8 @@ rte_eth_speed_bitflag(uint32_t speed, int duplex)
 		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;
 	}
diff --git a/lib/librte_ether/rte_ethdev.h b/lib/librte_ether/rte_ethdev.h
index 5e3bd04..e215d55 100644
--- a/lib/librte_ether/rte_ethdev.h
+++ b/lib/librte_ether/rte_ethdev.h
@@ -259,6 +259,7 @@ struct rte_eth_stats {
 #define ETH_LINK_SPEED_40G      (1 << 11)  /**<  40 Gbps */
 #define ETH_LINK_SPEED_50G      (1 << 12)  /**<  50 Gbps */
 #define ETH_LINK_SPEED_56G      (1 << 13)  /**<  56 Gbps */
+#define ETH_LINK_SPEED_100G     (1 << 14)  /**< 100 Gbps */
 
 /**
  * Ethernet numeric link speeds in Mbps
@@ -275,12 +276,13 @@ struct rte_eth_stats {
 #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 */
 
 /**
  * A structure used to retrieve link-level information of an Ethernet port.
  */
 struct rte_eth_link {
-	uint16_t link_speed;        /**< ETH_SPEED_NUM_ */
+	uint32_t link_speed;        /**< ETH_SPEED_NUM_ */
 	uint16_t link_duplex  : 1;  /**< ETH_LINK_[HALF/FULL]_DUPLEX */
 	uint16_t link_autoneg : 1;  /**< ETH_LINK_SPEED_[AUTONEG/FIXED] */
 	uint16_t link_status  : 1;  /**< ETH_LINK_[DOWN/UP] */
-- 
2.7.0

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

* Re: [PATCH v10 0/8] ethdev: 100G and link speed API refactoring
  2016-03-14 21:55         ` [PATCH v10 0/8] ethdev: 100G and link speed API refactoring Thomas Monjalon
                             ` (7 preceding siblings ...)
  2016-03-14 21:55           ` [PATCH v10 8/8] ethdev: add 100G link speed Thomas Monjalon
@ 2016-03-15  0:04           ` Matej Vido
  2016-03-15  7:12             ` Thomas Monjalon
  2016-03-15  8:38           ` Nélio Laranjeiro
                             ` (2 subsequent siblings)
  11 siblings, 1 reply; 167+ messages in thread
From: Matej Vido @ 2016-03-15  0:04 UTC (permalink / raw)
  To: Thomas Monjalon, marcdevel, bruce.richardson, declan.doherty,
	konstantin.ananyev, wenzhuo.lu, helin.zhang, jing.d.chen,
	harish.patil, rahul.lakkireddy, johndale, adrien.mazarguil,
	alejandro.lucero
  Cc: dev

Hi,

patch http://dpdk.org/dev/patchwork/patch/10202/
which was applied to dpdk-next-net/rel_16_04 tree changes filling
of items in rte_eth_link structure for szedata2 driver. These changes
for szedata2 driver are not compliant with changes in this patch series.
I'm not sure how it should be addressed.

Regards,
Matej


Dňa 14.03.2016 o 22:55 Thomas Monjalon napísal(a):
> Re-spin of the Marc's patchset.
> The first version was sent 10 months ago!
> There are still too few tests and reviews but it is now time to move
> forward with this rework.
> Some issues were remaining in v9 and were difficult to see because it
> was mainly one big patch. That's why I've split it in several steps
> and fixed/reworked some pieces.
> There will be an exception to integrate this feature in 16.04-rc2.
> Please test and review shortly, thanks!
>
> --------
>
> This series of patches adds the following capabilities:
>
> * speed_capa bitmap in rte_eth_dev_info, which is filled by the PMDs
>    according to the physical device capabilities.
> * refactors link API in ethdev to allow the definition of the advertised
>    link speeds, fix speed (no auto-negociation) or advertise all supported
>    speeds (default).
>
> WARNING: this patch series, specifically the patch 6/8, is NOT tested for
> most of the drivers.
> Reviewing and testing are required by PMD maintainers.
>
> --------
>
> Marc Sune (6):
>    ethdev: use constants for link duplex
>    app/testpmd: move speed and duplex parsing in a function
>    ethdev: rename link speed constants
>    ethdev: add speed capabilities
>    ethdev: redesign link speed config
>    ethdev: convert speed number to bitmap flag
>
> Thomas Monjalon (2):
>    ethdev: use constants for link state
>    ethdev: add 100G link speed
>
> v10:
>      - rebase
>      - rework release notes
>      - rearrange patch splitting
>      - fix doxygen comments
>      - fix typos
>      - removed log format of link.link_speed as %d (keep %u)
>      - complete ETH_LINK_[DOWN/UP] replacement from 0/1
>      - change ETH_LINK_SPEED_AUTONEG to 1
>      - replace ETH_LINK_SPEED_NEG by ETH_LINK_SPEED_AUTONEG (1)
>      - replace ETH_LINK_SPEED_NO_AUTONEG by ETH_LINK_SPEED_FIXED (0)
>      - rework rte_eth_speed_to_bm_flag to rte_eth_speed_bitflag
>      - complete 100G support in testpmd
>
> v9: rebased to current HEAD. Reverted numeric speed to 32 bit in struct
>      rte_eth_link (no atomic link get > 64bit). Fixed mlx5 driver compilation
>      and link speeds. Moved documentation to release_16_04.rst and fixed several
>      issues. Upgrade NIC notes with speed capabilities.
>
> v8: Rebased to current HEAD. Modified em driver impl. to not touch base files.
>      Merged patch 5 into 3 (map file). Changed numeric speed to a 64 bit value.
>      Filled-in speed capabilities for drivers bnx2x, cxgbe, mlx5 and nfp in
>      addition to the ones of previous patch sets.
>
> v7: Rebased to current HEAD. Moved documentation to v2.3. Still needs testing
>      from PMD maintainers.
>
> v6: Move link_duplex to be part of bitfield. Fixed i40 autoneg flag link
>      update code. Added rte_eth_speed_to_bm_flag() to .map file. Fixed other
>      spelling issues. Rebased to current HEAD.
>
> v5: revert to v2 speed capabilities patch. Fixed MLX4 speed capabilities
>      (thanks N. Laranjeiro). Refactored link speed API to allow setting
>      advertised speeds (3/4). Added NO_AUTONEG option to explicitely disable
>      auto-negociation. Updated 2.2 rel. notes (4/4). Rebased to current HEAD.
>
> v4: fixed errata in the documentation of field speeds of rte_eth_conf, and
>      commit 1/2 message. rebased to v2.1.0. v3 was incorrectly based on
>      ~2.1.0-rc1.
>
> v3: rebase to v2.1. unified ETH_LINK_SPEED and ETH_SPEED_CAP into ETH_SPEED.
>      Converted field speed in struct rte_eth_conf to speed, to allow a bitmap
>      for defining the announced speeds, as suggested M. Brorup. Fixed spelling
>      issues.
>
> v2: rebase, converted speed_capa into 32 bits bitmap, fixed alignment
>      (checkpatch).
>
>
>   app/test-pipeline/init.c                           |   2 +-
>   app/test-pmd/cmdline.c                             | 125 ++++++++++-----------
>   app/test-pmd/testpmd.c                             |   2 +-
>   app/test/test_pmd_perf.c                           |   2 +-
>   app/test/virtual_pmd.c                             |   8 +-
>   doc/guides/nics/overview.rst                       |   1 +
>   doc/guides/rel_notes/release_16_04.rst             |  22 ++++
>   doc/guides/testpmd_app_ug/testpmd_funcs.rst        |   2 +-
>   drivers/net/af_packet/rte_eth_af_packet.c          |   9 +-
>   drivers/net/bnx2x/bnx2x_ethdev.c                   |   7 +-
>   drivers/net/bnx2x/elink.c                          |   2 +-
>   drivers/net/bonding/rte_eth_bond_8023ad.c          |  14 +--
>   drivers/net/bonding/rte_eth_bond_api.c             |   4 +-
>   drivers/net/bonding/rte_eth_bond_pmd.c             |  12 +-
>   drivers/net/cxgbe/base/t4_hw.c                     |   8 +-
>   drivers/net/cxgbe/cxgbe_ethdev.c                   |   1 +
>   drivers/net/e1000/em_ethdev.c                      | 111 +++++++++---------
>   drivers/net/e1000/igb_ethdev.c                     | 104 +++++++++--------
>   drivers/net/fm10k/fm10k_ethdev.c                   |   6 +-
>   drivers/net/i40e/i40e_ethdev.c                     |  76 +++++++------
>   drivers/net/i40e/i40e_ethdev_vf.c                  |  11 +-
>   drivers/net/ixgbe/ixgbe_ethdev.c                   |  76 ++++++-------
>   drivers/net/mlx4/mlx4.c                            |   4 +
>   drivers/net/mlx5/mlx5_ethdev.c                     |   3 +
>   drivers/net/mpipe/mpipe_tilegx.c                   |  18 +--
>   drivers/net/nfp/nfp_net.c                          |   6 +-
>   drivers/net/null/rte_eth_null.c                    |   9 +-
>   drivers/net/pcap/rte_eth_pcap.c                    |   9 +-
>   drivers/net/ring/rte_eth_ring.c                    |  13 ++-
>   drivers/net/szedata2/rte_eth_szedata2.c            |   7 +-
>   drivers/net/virtio/virtio_ethdev.c                 |   8 +-
>   drivers/net/virtio/virtio_ethdev.h                 |   2 -
>   drivers/net/vmxnet3/vmxnet3_ethdev.c               |   5 +-
>   drivers/net/xenvirt/rte_eth_xenvirt.c              |   9 +-
>   examples/exception_path/main.c                     |   2 +-
>   examples/ip_fragmentation/main.c                   |   2 +-
>   examples/ip_pipeline/config_parse.c                |   3 +-
>   examples/ip_pipeline/init.c                        |   2 +-
>   examples/ip_reassembly/main.c                      |   2 +-
>   examples/ipsec-secgw/ipsec-secgw.c                 |   2 +-
>   examples/ipv4_multicast/main.c                     |   2 +-
>   examples/kni/main.c                                |   2 +-
>   examples/l2fwd-crypto/main.c                       |   2 +-
>   examples/l2fwd-ivshmem/host/host.c                 |   2 +-
>   examples/l2fwd-jobstats/main.c                     |   2 +-
>   examples/l2fwd-keepalive/main.c                    |   2 +-
>   examples/l2fwd/main.c                              |   2 +-
>   examples/l3fwd-acl/main.c                          |   2 +-
>   examples/l3fwd-power/main.c                        |   2 +-
>   examples/l3fwd/main.c                              |   2 +-
>   examples/link_status_interrupt/main.c              |   2 +-
>   examples/load_balancer/init.c                      |   2 +-
>   .../client_server_mp/mp_server/init.c              |   2 +-
>   examples/multi_process/l2fwd_fork/main.c           |   2 +-
>   examples/multi_process/symmetric_mp/main.c         |   2 +-
>   examples/performance-thread/l3fwd-thread/main.c    |   2 +-
>   lib/librte_ether/rte_ethdev.c                      |  33 ++++++
>   lib/librte_ether/rte_ethdev.h                      |  91 +++++++++++----
>   lib/librte_ether/rte_ether_version.map             |   1 +
>   59 files changed, 503 insertions(+), 365 deletions(-)
>

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

* Re: [PATCH v10 1/8] ethdev: use constants for link state
  2016-03-14 21:55           ` [PATCH v10 1/8] ethdev: use constants for link state Thomas Monjalon
@ 2016-03-15  1:26             ` Zhang, Helin
  0 siblings, 0 replies; 167+ messages in thread
From: Zhang, Helin @ 2016-03-15  1:26 UTC (permalink / raw)
  To: Thomas Monjalon, marcdevel, Richardson, Bruce, Doherty, Declan,
	Ananyev, Konstantin, Lu, Wenzhuo, Chen, Jing D, harish.patil,
	rahul.lakkireddy, johndale, vido, adrien.mazarguil,
	alejandro.lucero
  Cc: dev



> -----Original Message-----
> From: Thomas Monjalon [mailto:thomas.monjalon@6wind.com]
> Sent: Tuesday, March 15, 2016 5:56 AM
> To: marcdevel@gmail.com; Richardson, Bruce <bruce.richardson@intel.com>;
> Doherty, Declan <declan.doherty@intel.com>; Ananyev, Konstantin
> <konstantin.ananyev@intel.com>; Lu, Wenzhuo <wenzhuo.lu@intel.com>;
> Zhang, Helin <helin.zhang@intel.com>; Chen, Jing D <jing.d.chen@intel.com>;
> harish.patil@qlogic.com; rahul.lakkireddy@chelsio.com; johndale@cisco.com;
> vido@cesnet.cz; adrien.mazarguil@6wind.com;
> alejandro.lucero@netronome.com
> Cc: dev@dpdk.org
> Subject: [PATCH v10 1/8] ethdev: use constants for link state
> 
> Define and use ETH_LINK_UP and ETH_LINK_DOWN where appropriate.
> 
> Signed-off-by: Marc Sune <marcdevel@gmail.com>
> Signed-off-by: Thomas Monjalon <thomas.monjalon@6wind.com>
> ---


................

> diff --git a/lib/librte_ether/rte_ethdev.h b/lib/librte_ether/rte_ethdev.h index
> d867976..6704a82 100644
> --- a/lib/librte_ether/rte_ethdev.h
> +++ b/lib/librte_ether/rte_ethdev.h
> @@ -247,7 +247,7 @@ struct rte_eth_stats {  struct rte_eth_link {
>  	uint16_t link_speed;      /**< ETH_LINK_SPEED_[10, 100, 1000, 10000] */
>  	uint16_t link_duplex;     /**< ETH_LINK_[HALF_DUPLEX, FULL_DUPLEX]
> */
> -	uint8_t  link_status : 1; /**< 1 -> link up, 0 -> link down */
> +	uint8_t  link_status : 1; /**< ETH_LINK_[DOWN/UP] */
>  }__attribute__((aligned(8)));     /**< aligned for atomic64 read/write */
> 
>  #define ETH_LINK_SPEED_AUTONEG  0       /**< Auto-negotiate link
> speed. */
> @@ -259,9 +259,12 @@ struct rte_eth_link {
>  #define ETH_LINK_SPEED_20G      20000   /**< 20 gigabits/second. */
>  #define ETH_LINK_SPEED_40G      40000   /**< 40 gigabits/second. */
> 
> +/* Utility constants */
>  #define ETH_LINK_AUTONEG_DUPLEX 0       /**< Auto-negotiate duplex.
> */
>  #define ETH_LINK_HALF_DUPLEX    1       /**< Half-duplex connection. */
>  #define ETH_LINK_FULL_DUPLEX    2       /**< Full-duplex connection. */
> +#define ETH_LINK_DOWN           0 /**< Link is down. */
> +#define ETH_LINK_UP             1 /**< Link is up. */
I was thinking if there is a link state of ETH_LINK_UNKOWN is needed?
Sometimes, it cannot get the real link status from hardware.
Any comments about this from others?

/Helin

> 
>  /**
>   * A structure used to configure the ring threshold registers of an RX/TX
> --
> 2.7.0

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

* Re: [PATCH v10 0/8] ethdev: 100G and link speed API refactoring
  2016-03-15  0:04           ` [PATCH v10 0/8] ethdev: 100G and link speed API refactoring Matej Vido
@ 2016-03-15  7:12             ` Thomas Monjalon
  2016-03-15  7:45               ` Matej Vido
  0 siblings, 1 reply; 167+ messages in thread
From: Thomas Monjalon @ 2016-03-15  7:12 UTC (permalink / raw)
  To: Matej Vido
  Cc: marcdevel, bruce.richardson, declan.doherty, konstantin.ananyev,
	wenzhuo.lu, helin.zhang, jing.d.chen, harish.patil,
	rahul.lakkireddy, johndale, adrien.mazarguil, alejandro.lucero,
	dev

2016-03-15 01:04, Matej Vido:
> Hi,
> 
> patch http://dpdk.org/dev/patchwork/patch/10202/
> which was applied to dpdk-next-net/rel_16_04 tree changes filling
> of items in rte_eth_link structure for szedata2 driver. These changes
> for szedata2 driver are not compliant with changes in this patch series.
> I'm not sure how it should be addressed.

The branch dpdk-next-net/rel_16_04 is going to be rebased for RC1 integration.
This series targets RC2.
Please prepare a patch to replace the szedata2 changes of this patch, and
it will be merged in the series for a v11.
Thanks

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

* Re: [PATCH v10 0/8] ethdev: 100G and link speed API refactoring
  2016-03-15  7:12             ` Thomas Monjalon
@ 2016-03-15  7:45               ` Matej Vido
  0 siblings, 0 replies; 167+ messages in thread
From: Matej Vido @ 2016-03-15  7:45 UTC (permalink / raw)
  To: Thomas Monjalon
  Cc: marcdevel, bruce.richardson, declan.doherty, konstantin.ananyev,
	wenzhuo.lu, helin.zhang, jing.d.chen, harish.patil,
	rahul.lakkireddy, johndale, adrien.mazarguil, alejandro.lucero,
	dev

Dňa 15.03.2016 o 08:12 Thomas Monjalon napísal(a):
> 2016-03-15 01:04, Matej Vido:
>> Hi,
>>
>> patch http://dpdk.org/dev/patchwork/patch/10202/
>> which was applied to dpdk-next-net/rel_16_04 tree changes filling
>> of items in rte_eth_link structure for szedata2 driver. These changes
>> for szedata2 driver are not compliant with changes in this patch series.
>> I'm not sure how it should be addressed.
> The branch dpdk-next-net/rel_16_04 is going to be rebased for RC1 integration.
> This series targets RC2.
> Please prepare a patch to replace the szedata2 changes of this patch, and
> it will be merged in the series for a v11.
> Thanks
Ok, I'll do.

Regards,
Matej

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

* Re: [PATCH v10 0/8] ethdev: 100G and link speed API refactoring
  2016-03-14 21:55         ` [PATCH v10 0/8] ethdev: 100G and link speed API refactoring Thomas Monjalon
                             ` (8 preceding siblings ...)
  2016-03-15  0:04           ` [PATCH v10 0/8] ethdev: 100G and link speed API refactoring Matej Vido
@ 2016-03-15  8:38           ` Nélio Laranjeiro
  2016-03-15 13:12           ` [PATCH 0/4] szedata2: " Matej Vido
  2016-03-17 18:08           ` [PATCH v11 0/8] ethdev: 100G and link speed API refactoring Thomas Monjalon
  11 siblings, 0 replies; 167+ messages in thread
From: Nélio Laranjeiro @ 2016-03-15  8:38 UTC (permalink / raw)
  To: Thomas Monjalon
  Cc: marcdevel, bruce.richardson, declan.doherty, konstantin.ananyev,
	wenzhuo.lu, helin.zhang, jing.d.chen, harish.patil,
	rahul.lakkireddy, johndale, vido, adrien.mazarguil,
	alejandro.lucero, dev

On Mon, Mar 14, 2016 at 10:55:38PM +0100, Thomas Monjalon wrote:
> Re-spin of the Marc's patchset.
> The first version was sent 10 months ago!
> There are still too few tests and reviews but it is now time to move
> forward with this rework.
> Some issues were remaining in v9 and were difficult to see because it
> was mainly one big patch. That's why I've split it in several steps
> and fixed/reworked some pieces.
> There will be an exception to integrate this feature in 16.04-rc2.
> Please test and review shortly, thanks!
>[...] 

Tested-by: Nelio Laranjeiro <nelio.laranjeiro@6wind.com>

 1. On Mellanox ConnectX-3, Connexct-4 100G, ConnectX-4 Lx, speed is
    correctly displayed according to the negotiated link speed.
    
 2. Configuring speed tested, not working as expected.

-- 
Nélio Laranjeiro
6WIND

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

* [PATCH 0/4] szedata2: 100G and link speed API refactoring
  2016-03-14 21:55         ` [PATCH v10 0/8] ethdev: 100G and link speed API refactoring Thomas Monjalon
                             ` (9 preceding siblings ...)
  2016-03-15  8:38           ` Nélio Laranjeiro
@ 2016-03-15 13:12           ` Matej Vido
  2016-03-15 13:12             ` [PATCH 1/4] szedata2: use constants for link state Matej Vido
                               ` (3 more replies)
  2016-03-17 18:08           ` [PATCH v11 0/8] ethdev: 100G and link speed API refactoring Thomas Monjalon
  11 siblings, 4 replies; 167+ messages in thread
From: Matej Vido @ 2016-03-15 13:12 UTC (permalink / raw)
  To: thomas.monjalon; +Cc: marcdevel, dev

This patch series adds link speed API changes to szedata2 driver
based on current dpdk-next-net/rel_16_04 tree.
Changes are split into commits as in v10 of patch series:
http://dpdk.org/ml/archives/dev/2016-March/035731.html


Matej Vido (4):
  szedata2: use constants for link state
  szedata2: rename link speed constants
  szedata2: redesign link speed config
  szedata2: add 100G link speed

 drivers/net/szedata2/rte_eth_szedata2.c | 13 ++++++++-----
 1 file changed, 8 insertions(+), 5 deletions(-)

-- 
1.9.1

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

* [PATCH 1/4] szedata2: use constants for link state
  2016-03-15 13:12           ` [PATCH 0/4] szedata2: " Matej Vido
@ 2016-03-15 13:12             ` Matej Vido
  2016-03-15 13:12             ` [PATCH 2/4] szedata2: rename link speed constants Matej Vido
                               ` (2 subsequent siblings)
  3 siblings, 0 replies; 167+ messages in thread
From: Matej Vido @ 2016-03-15 13:12 UTC (permalink / raw)
  To: thomas.monjalon; +Cc: marcdevel, dev

Use ETH_LINK_UP and ETH_LINK_DOWN constants.

Signed-off-by: Matej Vido <vido@cesnet.cz>
---
 drivers/net/szedata2/rte_eth_szedata2.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/net/szedata2/rte_eth_szedata2.c b/drivers/net/szedata2/rte_eth_szedata2.c
index 81c806e..c65067e 100644
--- a/drivers/net/szedata2/rte_eth_szedata2.c
+++ b/drivers/net/szedata2/rte_eth_szedata2.c
@@ -1172,7 +1172,7 @@ eth_link_update(struct rte_eth_dev *dev,
 	link.link_duplex = ETH_LINK_FULL_DUPLEX;
 
 	link.link_status = (cgmii_ibuf_is_enabled(ibuf) &&
-			cgmii_ibuf_is_link_up(ibuf)) ? 1 : 0;
+			cgmii_ibuf_is_link_up(ibuf)) ? ETH_LINK_UP : ETH_LINK_DOWN;
 
 	rte_atomic64_cmpset((uint64_t *)dev_link, *(uint64_t *)dev_link,
 			*(uint64_t *)link_ptr);
-- 
1.9.1

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

* [PATCH 2/4] szedata2: rename link speed constants
  2016-03-15 13:12           ` [PATCH 0/4] szedata2: " Matej Vido
  2016-03-15 13:12             ` [PATCH 1/4] szedata2: use constants for link state Matej Vido
@ 2016-03-15 13:12             ` Matej Vido
  2016-03-15 13:12             ` [PATCH 3/4] szedata2: redesign link speed config Matej Vido
  2016-03-15 13:12             ` [PATCH 4/4] szedata2: add 100G link speed Matej Vido
  3 siblings, 0 replies; 167+ messages in thread
From: Matej Vido @ 2016-03-15 13:12 UTC (permalink / raw)
  To: thomas.monjalon; +Cc: marcdevel, dev

The speed numbers ETH_LINK_SPEED_ are renamed ETH_SPEED_NUM_.

Signed-off-by: Matej Vido <vido@cesnet.cz>
---
 drivers/net/szedata2/rte_eth_szedata2.c | 8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/drivers/net/szedata2/rte_eth_szedata2.c b/drivers/net/szedata2/rte_eth_szedata2.c
index c65067e..854cb5c 100644
--- a/drivers/net/szedata2/rte_eth_szedata2.c
+++ b/drivers/net/szedata2/rte_eth_szedata2.c
@@ -1149,10 +1149,10 @@ eth_link_update(struct rte_eth_dev *dev,
 
 	switch (cgmii_link_speed(ibuf)) {
 	case SZEDATA2_LINK_SPEED_10G:
-		link.link_speed = ETH_LINK_SPEED_10G;
+		link.link_speed = ETH_SPEED_NUM_10G;
 		break;
 	case SZEDATA2_LINK_SPEED_40G:
-		link.link_speed = ETH_LINK_SPEED_40G;
+		link.link_speed = ETH_SPEED_NUM_40G;
 		break;
 	case SZEDATA2_LINK_SPEED_100G:
 		/*
@@ -1161,10 +1161,10 @@ eth_link_update(struct rte_eth_dev *dev,
 		 * will be changed to support 100Gbps speed change
 		 * this value to 100G.
 		 */
-		link.link_speed = ETH_LINK_SPEED_10G;
+		link.link_speed = ETH_SPEED_NUM_10G;
 		break;
 	default:
-		link.link_speed = ETH_LINK_SPEED_10G;
+		link.link_speed = ETH_SPEED_NUM_10G;
 		break;
 	}
 
-- 
1.9.1

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

* [PATCH 3/4] szedata2: redesign link speed config
  2016-03-15 13:12           ` [PATCH 0/4] szedata2: " Matej Vido
  2016-03-15 13:12             ` [PATCH 1/4] szedata2: use constants for link state Matej Vido
  2016-03-15 13:12             ` [PATCH 2/4] szedata2: rename link speed constants Matej Vido
@ 2016-03-15 13:12             ` Matej Vido
  2016-03-15 13:12             ` [PATCH 4/4] szedata2: add 100G link speed Matej Vido
  3 siblings, 0 replies; 167+ messages in thread
From: Matej Vido @ 2016-03-15 13:12 UTC (permalink / raw)
  To: thomas.monjalon; +Cc: marcdevel, dev

This patch sets value of flag link_autoneg in struct rte_eth_link
to ETH_LINK_SPEED_FIXED.

Signed-off-by: Matej Vido <vido@cesnet.cz>
---
 drivers/net/szedata2/rte_eth_szedata2.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/drivers/net/szedata2/rte_eth_szedata2.c b/drivers/net/szedata2/rte_eth_szedata2.c
index 854cb5c..0708e4a 100644
--- a/drivers/net/szedata2/rte_eth_szedata2.c
+++ b/drivers/net/szedata2/rte_eth_szedata2.c
@@ -1174,6 +1174,8 @@ eth_link_update(struct rte_eth_dev *dev,
 	link.link_status = (cgmii_ibuf_is_enabled(ibuf) &&
 			cgmii_ibuf_is_link_up(ibuf)) ? ETH_LINK_UP : ETH_LINK_DOWN;
 
+	link.link_autoneg = ETH_LINK_SPEED_FIXED;
+
 	rte_atomic64_cmpset((uint64_t *)dev_link, *(uint64_t *)dev_link,
 			*(uint64_t *)link_ptr);
 
-- 
1.9.1

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

* [PATCH 4/4] szedata2: add 100G link speed
  2016-03-15 13:12           ` [PATCH 0/4] szedata2: " Matej Vido
                               ` (2 preceding siblings ...)
  2016-03-15 13:12             ` [PATCH 3/4] szedata2: redesign link speed config Matej Vido
@ 2016-03-15 13:12             ` Matej Vido
  2016-03-15 13:41               ` Thomas Monjalon
  3 siblings, 1 reply; 167+ messages in thread
From: Matej Vido @ 2016-03-15 13:12 UTC (permalink / raw)
  To: thomas.monjalon; +Cc: marcdevel, dev

Temporary 10G constant is replaced with 100G constant.
Item speed_capa from struct rte_eth_dev_info is set with 100G flag.

Signed-off-by: Matej Vido <vido@cesnet.cz>
---
 drivers/net/szedata2/rte_eth_szedata2.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/drivers/net/szedata2/rte_eth_szedata2.c b/drivers/net/szedata2/rte_eth_szedata2.c
index 0708e4a..f1855a5 100644
--- a/drivers/net/szedata2/rte_eth_szedata2.c
+++ b/drivers/net/szedata2/rte_eth_szedata2.c
@@ -1036,6 +1036,7 @@ eth_dev_info(struct rte_eth_dev *dev,
 	dev_info->max_rx_queues = internals->max_rx_queues;
 	dev_info->max_tx_queues = internals->max_tx_queues;
 	dev_info->min_rx_bufsize = 0;
+	dev_info->speed_capa = ETH_LINK_SPEED_100G;
 }
 
 static void
@@ -1161,7 +1162,7 @@ eth_link_update(struct rte_eth_dev *dev,
 		 * will be changed to support 100Gbps speed change
 		 * this value to 100G.
 		 */
-		link.link_speed = ETH_SPEED_NUM_10G;
+		link.link_speed = ETH_SPEED_NUM_100G;
 		break;
 	default:
 		link.link_speed = ETH_SPEED_NUM_10G;
-- 
1.9.1

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

* Re: [PATCH 4/4] szedata2: add 100G link speed
  2016-03-15 13:12             ` [PATCH 4/4] szedata2: add 100G link speed Matej Vido
@ 2016-03-15 13:41               ` Thomas Monjalon
  2016-03-15 13:47                 ` Matej Vido
  2016-03-15 13:50                 ` Matej Vido
  0 siblings, 2 replies; 167+ messages in thread
From: Thomas Monjalon @ 2016-03-15 13:41 UTC (permalink / raw)
  To: Matej Vido; +Cc: marcdevel, dev

Thanks for the series completing the ethdev rework with the same splitting.

2016-03-15 14:12, Matej Vido:
> Temporary 10G constant is replaced with 100G constant.
> Item speed_capa from struct rte_eth_dev_info is set with 100G flag.
[...]
> @@ -1161,7 +1162,7 @@ eth_link_update(struct rte_eth_dev *dev,
>  		 * will be changed to support 100Gbps speed change
>  		 * this value to 100G.
>  		 */
> -		link.link_speed = ETH_SPEED_NUM_10G;
> +		link.link_speed = ETH_SPEED_NUM_100G;

Shouldn't we remove the above comment?

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

* Re: [PATCH 4/4] szedata2: add 100G link speed
  2016-03-15 13:41               ` Thomas Monjalon
@ 2016-03-15 13:47                 ` Matej Vido
  2016-03-15 13:50                 ` Matej Vido
  1 sibling, 0 replies; 167+ messages in thread
From: Matej Vido @ 2016-03-15 13:47 UTC (permalink / raw)
  To: dev



Dňa 15.03.2016 o 14:41 Thomas Monjalon napísal(a):
> Thanks for the series completing the ethdev rework with the same splitting.
>
> 2016-03-15 14:12, Matej Vido:
>> Temporary 10G constant is replaced with 100G constant.
>> Item speed_capa from struct rte_eth_dev_info is set with 100G flag.
> [...]
>> @@ -1161,7 +1162,7 @@ eth_link_update(struct rte_eth_dev *dev,
>>   		 * will be changed to support 100Gbps speed change
>>   		 * this value to 100G.
>>   		 */
>> -		link.link_speed = ETH_SPEED_NUM_10G;
>> +		link.link_speed = ETH_SPEED_NUM_100G;
> Shouldn't we remove the above comment?
Yes, I forgot

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

* Re: [PATCH 4/4] szedata2: add 100G link speed
  2016-03-15 13:41               ` Thomas Monjalon
  2016-03-15 13:47                 ` Matej Vido
@ 2016-03-15 13:50                 ` Matej Vido
  2016-03-15 20:51                   ` Thomas Monjalon
  1 sibling, 1 reply; 167+ messages in thread
From: Matej Vido @ 2016-03-15 13:50 UTC (permalink / raw)
  To: Thomas Monjalon; +Cc: marcdevel, dev



Dňa 15.03.2016 o 14:41 Thomas Monjalon napísal(a):
> Thanks for the series completing the ethdev rework with the same splitting.
>
> 2016-03-15 14:12, Matej Vido:
>> Temporary 10G constant is replaced with 100G constant.
>> Item speed_capa from struct rte_eth_dev_info is set with 100G flag.
> [...]
>> @@ -1161,7 +1162,7 @@ eth_link_update(struct rte_eth_dev *dev,
>>   		 * will be changed to support 100Gbps speed change
>>   		 * this value to 100G.
>>   		 */
>> -		link.link_speed = ETH_SPEED_NUM_10G;
>> +		link.link_speed = ETH_SPEED_NUM_100G;
> Shouldn't we remove the above comment?
Yes, I forgot. Should I remove the comment and send again or could you 
do it when merging with original series?

Matej

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

* Re: [PATCH 4/4] szedata2: add 100G link speed
  2016-03-15 13:50                 ` Matej Vido
@ 2016-03-15 20:51                   ` Thomas Monjalon
  0 siblings, 0 replies; 167+ messages in thread
From: Thomas Monjalon @ 2016-03-15 20:51 UTC (permalink / raw)
  To: Matej Vido; +Cc: marcdevel, dev

2016-03-15 14:50, Matej Vido:
> 
> Dňa 15.03.2016 o 14:41 Thomas Monjalon napísal(a):
> > Thanks for the series completing the ethdev rework with the same splitting.
> >
> > 2016-03-15 14:12, Matej Vido:
> >> Temporary 10G constant is replaced with 100G constant.
> >> Item speed_capa from struct rte_eth_dev_info is set with 100G flag.
> > [...]
> >> @@ -1161,7 +1162,7 @@ eth_link_update(struct rte_eth_dev *dev,
> >>   		 * will be changed to support 100Gbps speed change
> >>   		 * this value to 100G.
> >>   		 */
> >> -		link.link_speed = ETH_SPEED_NUM_10G;
> >> +		link.link_speed = ETH_SPEED_NUM_100G;
> > Shouldn't we remove the above comment?
> Yes, I forgot. Should I remove the comment and send again or could you 
> do it when merging with original series?

I'll do it, thanks.

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

* [PATCH v11 0/8] ethdev: 100G and link speed API refactoring
  2016-03-14 21:55         ` [PATCH v10 0/8] ethdev: 100G and link speed API refactoring Thomas Monjalon
                             ` (10 preceding siblings ...)
  2016-03-15 13:12           ` [PATCH 0/4] szedata2: " Matej Vido
@ 2016-03-17 18:08           ` Thomas Monjalon
  2016-03-17 18:08             ` [PATCH v11 1/8] ethdev: use constants for link state Thomas Monjalon
                               ` (10 more replies)
  11 siblings, 11 replies; 167+ messages in thread
From: Thomas Monjalon @ 2016-03-17 18:08 UTC (permalink / raw)
  To: marcdevel, bruce.richardson, declan.doherty, konstantin.ananyev,
	wenzhuo.lu, helin.zhang, jing.d.chen, harish.patil,
	rahul.lakkireddy, johndale, vido, adrien.mazarguil,
	alejandro.lucero
  Cc: dev

There are still too few tests and reviews, especially for
autonegotiation with Intel devices (patch #6).
I would not be surprised to see some bugs in this rework.

The capabilities must be adapted per device. It can be
improved in a separate patch.

It will be integrated in 16.04-rc2.
Please test and review shortly, thanks!

--------

This series of patches adds the following capabilities:

* speed_capa bitmap in rte_eth_dev_info, which is filled by the PMDs
  according to the physical device capabilities.
* refactors link API in ethdev to allow the definition of the advertised
  link speeds, fix speed (no auto-negociation) or advertise all supported
  speeds (default).

--------

v11:
    - rebase on 16.04-rc1
    - replace on more link status value in e1000 driver
    - merge szedata2 patches
    - remove szedata2 temporary comments in code and doc

v10:
    - rebase
    - rework release notes
    - rearrange patch splitting
    - fix doxygen comments
    - fix typos
    - removed log format of link.link_speed as %d (keep %u)
    - complete ETH_LINK_[DOWN/UP] replacement from 0/1
    - change ETH_LINK_SPEED_AUTONEG to 1
    - replace ETH_LINK_SPEED_NEG by ETH_LINK_SPEED_AUTONEG (1)
    - replace ETH_LINK_SPEED_NO_AUTONEG by ETH_LINK_SPEED_FIXED (0)
    - rework rte_eth_speed_to_bm_flag to rte_eth_speed_bitflag
    - complete 100G support in testpmd

v9: rebased to current HEAD. Reverted numeric speed to 32 bit in struct
    rte_eth_link (no atomic link get > 64bit). Fixed mlx5 driver compilation
    and link speeds. Moved documentation to release_16_04.rst and fixed several
    issues. Upgrade NIC notes with speed capabilities.

v8: Rebased to current HEAD. Modified em driver impl. to not touch base files.
    Merged patch 5 into 3 (map file). Changed numeric speed to a 64 bit value.
    Filled-in speed capabilities for drivers bnx2x, cxgbe, mlx5 and nfp in
    addition to the ones of previous patch sets.

v7: Rebased to current HEAD. Moved documentation to v2.3. Still needs testing
    from PMD maintainers.

v6: Move link_duplex to be part of bitfield. Fixed i40 autoneg flag link
    update code. Added rte_eth_speed_to_bm_flag() to .map file. Fixed other
    spelling issues. Rebased to current HEAD.

v5: revert to v2 speed capabilities patch. Fixed MLX4 speed capabilities
    (thanks N. Laranjeiro). Refactored link speed API to allow setting
    advertised speeds (3/4). Added NO_AUTONEG option to explicitely disable
    auto-negociation. Updated 2.2 rel. notes (4/4). Rebased to current HEAD.

v4: fixed errata in the documentation of field speeds of rte_eth_conf, and
    commit 1/2 message. rebased to v2.1.0. v3 was incorrectly based on
    ~2.1.0-rc1.

v3: rebase to v2.1. unified ETH_LINK_SPEED and ETH_SPEED_CAP into ETH_SPEED.
    Converted field speed in struct rte_eth_conf to speed, to allow a bitmap
    for defining the announced speeds, as suggested M. Brorup. Fixed spelling
    issues.

v2: rebase, converted speed_capa into 32 bits bitmap, fixed alignment
    (checkpatch).

--------

Marc Sune (6):
  ethdev: use constants for link duplex
  app/testpmd: move speed and duplex parsing in a function
  ethdev: rename link speed constants
  ethdev: add speed capabilities
  ethdev: redesign link speed config
  ethdev: convert speed number to bitmap flag

Thomas Monjalon (2):
  ethdev: use constants for link state
  ethdev: add 100G link speed

 app/test-pipeline/init.c                           |   2 +-
 app/test-pmd/cmdline.c                             | 125 ++++++++++-----------
 app/test-pmd/testpmd.c                             |   2 +-
 app/test/test_pmd_perf.c                           |   2 +-
 app/test/virtual_pmd.c                             |   8 +-
 doc/guides/nics/overview.rst                       |   1 +
 doc/guides/nics/szedata2.rst                       |   6 -
 doc/guides/rel_notes/release_16_04.rst             |  22 ++++
 doc/guides/testpmd_app_ug/testpmd_funcs.rst        |   2 +-
 drivers/net/af_packet/rte_eth_af_packet.c          |   9 +-
 drivers/net/bnx2x/bnx2x_ethdev.c                   |   7 +-
 drivers/net/bnx2x/elink.c                          |   2 +-
 drivers/net/bonding/rte_eth_bond_8023ad.c          |  14 +--
 drivers/net/bonding/rte_eth_bond_api.c             |   4 +-
 drivers/net/bonding/rte_eth_bond_pmd.c             |  12 +-
 drivers/net/cxgbe/base/t4_hw.c                     |   8 +-
 drivers/net/cxgbe/cxgbe_ethdev.c                   |   1 +
 drivers/net/e1000/em_ethdev.c                      | 113 +++++++++----------
 drivers/net/e1000/igb_ethdev.c                     | 104 +++++++++--------
 drivers/net/fm10k/fm10k_ethdev.c                   |   6 +-
 drivers/net/i40e/i40e_ethdev.c                     |  76 +++++++------
 drivers/net/i40e/i40e_ethdev_vf.c                  |  11 +-
 drivers/net/ixgbe/ixgbe_ethdev.c                   |  76 ++++++-------
 drivers/net/mlx4/mlx4.c                            |   4 +
 drivers/net/mlx5/mlx5_ethdev.c                     |   3 +
 drivers/net/mpipe/mpipe_tilegx.c                   |  18 +--
 drivers/net/nfp/nfp_net.c                          |   6 +-
 drivers/net/null/rte_eth_null.c                    |   9 +-
 drivers/net/pcap/rte_eth_pcap.c                    |   9 +-
 drivers/net/ring/rte_eth_ring.c                    |  13 ++-
 drivers/net/szedata2/rte_eth_szedata2.c            |  19 ++--
 drivers/net/virtio/virtio_ethdev.c                 |   8 +-
 drivers/net/virtio/virtio_ethdev.h                 |   2 -
 drivers/net/vmxnet3/vmxnet3_ethdev.c               |   5 +-
 drivers/net/xenvirt/rte_eth_xenvirt.c              |   9 +-
 examples/exception_path/main.c                     |   2 +-
 examples/ip_fragmentation/main.c                   |   2 +-
 examples/ip_pipeline/config_parse.c                |   3 +-
 examples/ip_pipeline/init.c                        |   2 +-
 examples/ip_reassembly/main.c                      |   2 +-
 examples/ipsec-secgw/ipsec-secgw.c                 |   2 +-
 examples/ipv4_multicast/main.c                     |   2 +-
 examples/kni/main.c                                |   2 +-
 examples/l2fwd-crypto/main.c                       |   2 +-
 examples/l2fwd-ivshmem/host/host.c                 |   2 +-
 examples/l2fwd-jobstats/main.c                     |   2 +-
 examples/l2fwd-keepalive/main.c                    |   2 +-
 examples/l2fwd/main.c                              |   2 +-
 examples/l3fwd-acl/main.c                          |   2 +-
 examples/l3fwd-power/main.c                        |   2 +-
 examples/l3fwd/main.c                              |   2 +-
 examples/link_status_interrupt/main.c              |   2 +-
 examples/load_balancer/init.c                      |   2 +-
 .../client_server_mp/mp_server/init.c              |   2 +-
 examples/multi_process/l2fwd_fork/main.c           |   2 +-
 examples/multi_process/symmetric_mp/main.c         |   2 +-
 examples/performance-thread/l3fwd-thread/main.c    |   2 +-
 lib/librte_ether/rte_ethdev.c                      |  33 ++++++
 lib/librte_ether/rte_ethdev.h                      |  91 +++++++++++----
 lib/librte_ether/rte_ether_version.map             |   1 +
 60 files changed, 508 insertions(+), 380 deletions(-)

-- 
2.7.0

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

* [PATCH v11 1/8] ethdev: use constants for link state
  2016-03-17 18:08           ` [PATCH v11 0/8] ethdev: 100G and link speed API refactoring Thomas Monjalon
@ 2016-03-17 18:08             ` Thomas Monjalon
  2016-03-17 18:08             ` [PATCH v11 2/8] ethdev: use constants for link duplex Thomas Monjalon
                               ` (9 subsequent siblings)
  10 siblings, 0 replies; 167+ messages in thread
From: Thomas Monjalon @ 2016-03-17 18:08 UTC (permalink / raw)
  To: marcdevel, bruce.richardson, declan.doherty, konstantin.ananyev,
	wenzhuo.lu, helin.zhang, jing.d.chen, harish.patil,
	rahul.lakkireddy, johndale, vido, adrien.mazarguil,
	alejandro.lucero
  Cc: dev

Define and use ETH_LINK_UP and ETH_LINK_DOWN where appropriate.

Signed-off-by: Marc Sune <marcdevel@gmail.com>
Signed-off-by: Thomas Monjalon <thomas.monjalon@6wind.com>
---
 app/test-pipeline/init.c                                 |  2 +-
 app/test-pmd/testpmd.c                                   |  2 +-
 app/test/test_pmd_perf.c                                 |  2 +-
 app/test/virtual_pmd.c                                   |  6 +++---
 drivers/net/af_packet/rte_eth_af_packet.c                |  6 +++---
 drivers/net/bnx2x/bnx2x_ethdev.c                         |  2 +-
 drivers/net/bnx2x/elink.c                                |  2 +-
 drivers/net/bonding/rte_eth_bond_api.c                   |  4 ++--
 drivers/net/bonding/rte_eth_bond_pmd.c                   | 12 ++++++------
 drivers/net/e1000/em_ethdev.c                            |  8 ++++----
 drivers/net/e1000/igb_ethdev.c                           |  4 ++--
 drivers/net/fm10k/fm10k_ethdev.c                         |  2 +-
 drivers/net/i40e/i40e_ethdev_vf.c                        |  2 +-
 drivers/net/ixgbe/ixgbe_ethdev.c                         |  4 ++--
 drivers/net/mpipe/mpipe_tilegx.c                         | 12 ++++++------
 drivers/net/nfp/nfp_net.c                                |  2 +-
 drivers/net/null/rte_eth_null.c                          |  6 +++---
 drivers/net/pcap/rte_eth_pcap.c                          |  6 +++---
 drivers/net/ring/rte_eth_ring.c                          | 10 +++++-----
 drivers/net/szedata2/rte_eth_szedata2.c                  |  2 +-
 drivers/net/virtio/virtio_ethdev.c                       |  6 +++---
 drivers/net/vmxnet3/vmxnet3_ethdev.c                     |  2 +-
 drivers/net/xenvirt/rte_eth_xenvirt.c                    |  6 +++---
 examples/exception_path/main.c                           |  2 +-
 examples/ip_fragmentation/main.c                         |  2 +-
 examples/ip_pipeline/init.c                              |  2 +-
 examples/ip_reassembly/main.c                            |  2 +-
 examples/ipsec-secgw/ipsec-secgw.c                       |  2 +-
 examples/ipv4_multicast/main.c                           |  2 +-
 examples/kni/main.c                                      |  2 +-
 examples/l2fwd-crypto/main.c                             |  2 +-
 examples/l2fwd-ivshmem/host/host.c                       |  2 +-
 examples/l2fwd-jobstats/main.c                           |  2 +-
 examples/l2fwd-keepalive/main.c                          |  2 +-
 examples/l2fwd/main.c                                    |  2 +-
 examples/l3fwd-acl/main.c                                |  2 +-
 examples/l3fwd-power/main.c                              |  2 +-
 examples/l3fwd/main.c                                    |  2 +-
 examples/link_status_interrupt/main.c                    |  2 +-
 examples/load_balancer/init.c                            |  2 +-
 examples/multi_process/client_server_mp/mp_server/init.c |  2 +-
 examples/multi_process/l2fwd_fork/main.c                 |  2 +-
 examples/multi_process/symmetric_mp/main.c               |  2 +-
 examples/performance-thread/l3fwd-thread/main.c          |  2 +-
 lib/librte_ether/rte_ethdev.h                            |  5 ++++-
 45 files changed, 80 insertions(+), 77 deletions(-)

diff --git a/app/test-pipeline/init.c b/app/test-pipeline/init.c
index db2196b..aef082f 100644
--- a/app/test-pipeline/init.c
+++ b/app/test-pipeline/init.c
@@ -205,7 +205,7 @@ app_ports_check_link(void)
 			link.link_speed / 1000,
 			link.link_status ? "UP" : "DOWN");
 
-		if (link.link_status == 0)
+		if (link.link_status == ETH_LINK_DOWN)
 			all_ports_up = 0;
 	}
 
diff --git a/app/test-pmd/testpmd.c b/app/test-pmd/testpmd.c
index 38b9051..f713f39 100644
--- a/app/test-pmd/testpmd.c
+++ b/app/test-pmd/testpmd.c
@@ -1641,7 +1641,7 @@ check_all_ports_link_status(uint32_t port_mask)
 				continue;
 			}
 			/* clear all_ports_up flag if any link down */
-			if (link.link_status == 0) {
+			if (link.link_status == ETH_LINK_DOWN) {
 				all_ports_up = 0;
 				break;
 			}
diff --git a/app/test/test_pmd_perf.c b/app/test/test_pmd_perf.c
index 48e16c9..59803f7 100644
--- a/app/test/test_pmd_perf.c
+++ b/app/test/test_pmd_perf.c
@@ -192,7 +192,7 @@ check_all_ports_link_status(uint8_t port_num, uint32_t port_mask)
 				continue;
 			}
 			/* clear all_ports_up flag if any link down */
-			if (link.link_status == 0) {
+			if (link.link_status == ETH_LINK_DOWN) {
 				all_ports_up = 0;
 				break;
 			}
diff --git a/app/test/virtual_pmd.c b/app/test/virtual_pmd.c
index a538c8a..b1d40d7 100644
--- a/app/test/virtual_pmd.c
+++ b/app/test/virtual_pmd.c
@@ -79,7 +79,7 @@ static void  virtual_ethdev_stop(struct rte_eth_dev *eth_dev __rte_unused)
 	void *pkt = NULL;
 	struct virtual_ethdev_private *prv = eth_dev->data->dev_private;
 
-	eth_dev->data->dev_link.link_status = 0;
+	eth_dev->data->dev_link.link_status = ETH_LINK_DOWN;
 	eth_dev->data->dev_started = 0;
 	while (rte_ring_dequeue(prv->rx_queue, &pkt) != -ENOENT)
 		rte_pktmbuf_free(pkt);
@@ -199,7 +199,7 @@ virtual_ethdev_link_update_success(struct rte_eth_dev *bonded_eth_dev,
 		int wait_to_complete __rte_unused)
 {
 	if (!bonded_eth_dev->data->dev_started)
-		bonded_eth_dev->data->dev_link.link_status = 0;
+		bonded_eth_dev->data->dev_link.link_status = ETH_LINK_DOWN;
 
 	return 0;
 }
@@ -603,7 +603,7 @@ virtual_ethdev_create(const char *name, struct ether_addr *mac_addr,
 
 	TAILQ_INIT(&(eth_dev->link_intr_cbs));
 
-	eth_dev->data->dev_link.link_status = 0;
+	eth_dev->data->dev_link.link_status = ETH_LINK_DOWN;
 	eth_dev->data->dev_link.link_speed = ETH_LINK_SPEED_10000;
 	eth_dev->data->dev_link.link_duplex = ETH_LINK_FULL_DUPLEX;
 
diff --git a/drivers/net/af_packet/rte_eth_af_packet.c b/drivers/net/af_packet/rte_eth_af_packet.c
index 5544528..dee7b59 100644
--- a/drivers/net/af_packet/rte_eth_af_packet.c
+++ b/drivers/net/af_packet/rte_eth_af_packet.c
@@ -118,7 +118,7 @@ static const char *drivername = "AF_PACKET PMD";
 static struct rte_eth_link pmd_link = {
 	.link_speed = 10000,
 	.link_duplex = ETH_LINK_FULL_DUPLEX,
-	.link_status = 0
+	.link_status = ETH_LINK_DOWN,
 };
 
 static uint16_t
@@ -234,7 +234,7 @@ eth_af_packet_tx(void *queue, struct rte_mbuf **bufs, uint16_t nb_pkts)
 static int
 eth_dev_start(struct rte_eth_dev *dev)
 {
-	dev->data->dev_link.link_status = 1;
+	dev->data->dev_link.link_status = ETH_LINK_UP;
 	return 0;
 }
 
@@ -257,7 +257,7 @@ eth_dev_stop(struct rte_eth_dev *dev)
 			close(sockfd);
 	}
 
-	dev->data->dev_link.link_status = 0;
+	dev->data->dev_link.link_status = ETH_LINK_DOWN;
 }
 
 static int
diff --git a/drivers/net/bnx2x/bnx2x_ethdev.c b/drivers/net/bnx2x/bnx2x_ethdev.c
index fe8cfd0..dc9ce84 100644
--- a/drivers/net/bnx2x/bnx2x_ethdev.c
+++ b/drivers/net/bnx2x/bnx2x_ethdev.c
@@ -266,7 +266,7 @@ bnx2xvf_dev_link_update(struct rte_eth_dev *dev, __rte_unused int wait_to_comple
 	if (sc->old_bulletin.valid_bitmap & (1 << CHANNEL_DOWN)) {
 		PMD_DRV_LOG(ERR, "PF indicated channel is down."
 				"VF device is no longer operational");
-		dev->data->dev_link.link_status = 0;
+		dev->data->dev_link.link_status = ETH_LINK_DOWN;
 	}
 
 	return old_link_status == dev->data->dev_link.link_status ? -1 : 0;
diff --git a/drivers/net/bnx2x/elink.c b/drivers/net/bnx2x/elink.c
index da2366e..b9149b8 100644
--- a/drivers/net/bnx2x/elink.c
+++ b/drivers/net/bnx2x/elink.c
@@ -6312,7 +6312,7 @@ elink_status_t elink_link_update(struct elink_params * params,
 	for (phy_index = ELINK_INT_PHY; phy_index < params->num_phys;
 	     phy_index++) {
 		phy_vars[phy_index].flow_ctrl = 0;
-		phy_vars[phy_index].link_status = 0;
+		phy_vars[phy_index].link_status = ETH_LINK_DOWN;
 		phy_vars[phy_index].line_speed = 0;
 		phy_vars[phy_index].duplex = DUPLEX_FULL;
 		phy_vars[phy_index].phy_link_up = 0;
diff --git a/drivers/net/bonding/rte_eth_bond_api.c b/drivers/net/bonding/rte_eth_bond_api.c
index 3fca764..718e443 100644
--- a/drivers/net/bonding/rte_eth_bond_api.c
+++ b/drivers/net/bonding/rte_eth_bond_api.c
@@ -205,7 +205,7 @@ rte_eth_bond_create(const char *name, uint8_t mode, uint8_t socket_id)
 
 	TAILQ_INIT(&(eth_dev->link_intr_cbs));
 
-	eth_dev->data->dev_link.link_status = 0;
+	eth_dev->data->dev_link.link_status = ETH_LINK_DOWN;
 
 	eth_dev->data->mac_addrs = rte_zmalloc_socket(name, ETHER_ADDR_LEN, 0,
 			socket_id);
@@ -419,7 +419,7 @@ __eth_bond_slave_add_lock_free(uint8_t bonded_port_id, uint8_t slave_port_id)
 	if (bonded_eth_dev->data->dev_started) {
 		rte_eth_link_get_nowait(slave_port_id, &link_props);
 
-		 if (link_props.link_status == 1) {
+		 if (link_props.link_status == ETH_LINK_UP) {
 			if (internals->active_slave_count == 0 &&
 			    !internals->user_defined_primary_port)
 				bond_ethdev_primary_set(internals,
diff --git a/drivers/net/bonding/rte_eth_bond_pmd.c b/drivers/net/bonding/rte_eth_bond_pmd.c
index 011150a..66d0856 100644
--- a/drivers/net/bonding/rte_eth_bond_pmd.c
+++ b/drivers/net/bonding/rte_eth_bond_pmd.c
@@ -1500,7 +1500,7 @@ bond_ethdev_start(struct rte_eth_dev *eth_dev)
 		return -1;
 	}
 
-	eth_dev->data->dev_link.link_status = 0;
+	eth_dev->data->dev_link.link_status = ETH_LINK_DOWN;
 	eth_dev->data->dev_started = 1;
 
 	internals = eth_dev->data->dev_private;
@@ -1617,7 +1617,7 @@ bond_ethdev_stop(struct rte_eth_dev *eth_dev)
 	internals->active_slave_count = 0;
 	internals->link_status_polling_enabled = 0;
 
-	eth_dev->data->dev_link.link_status = 0;
+	eth_dev->data->dev_link.link_status = ETH_LINK_DOWN;
 	eth_dev->data->dev_started = 0;
 }
 
@@ -1783,7 +1783,7 @@ bond_ethdev_link_update(struct rte_eth_dev *bonded_eth_dev,
 
 	if (!bonded_eth_dev->data->dev_started ||
 		internals->active_slave_count == 0) {
-		bonded_eth_dev->data->dev_link.link_status = 0;
+		bonded_eth_dev->data->dev_link.link_status = ETH_LINK_DOWN;
 		return 0;
 	} else {
 		struct rte_eth_dev *slave_eth_dev;
@@ -1794,7 +1794,7 @@ bond_ethdev_link_update(struct rte_eth_dev *bonded_eth_dev,
 
 			(*slave_eth_dev->dev_ops->link_update)(slave_eth_dev,
 					wait_to_complete);
-			if (slave_eth_dev->data->dev_link.link_status == 1) {
+			if (slave_eth_dev->data->dev_link.link_status == ETH_LINK_UP) {
 				link_up = 1;
 				break;
 			}
@@ -1963,7 +1963,7 @@ bond_ethdev_lsc_event_callback(uint8_t port_id, enum rte_eth_event_type type,
 		/* if no active slave ports then set this port to be primary port */
 		if (internals->active_slave_count < 1) {
 			/* If first active slave, then change link status */
-			bonded_eth_dev->data->dev_link.link_status = 1;
+			bonded_eth_dev->data->dev_link.link_status = ETH_LINK_UP;
 			internals->current_primary_port = port_id;
 			lsc_flag = 1;
 
@@ -1991,7 +1991,7 @@ bond_ethdev_lsc_event_callback(uint8_t port_id, enum rte_eth_event_type type,
 		 * link properties */
 		if (internals->active_slave_count < 1) {
 			lsc_flag = 1;
-			bonded_eth_dev->data->dev_link.link_status = 0;
+			bonded_eth_dev->data->dev_link.link_status = ETH_LINK_DOWN;
 
 			link_properties_reset(bonded_eth_dev);
 		}
diff --git a/drivers/net/e1000/em_ethdev.c b/drivers/net/e1000/em_ethdev.c
index a8c26ed..58093c6 100644
--- a/drivers/net/e1000/em_ethdev.c
+++ b/drivers/net/e1000/em_ethdev.c
@@ -1102,14 +1102,14 @@ eth_em_link_update(struct rte_eth_dev *dev, int wait_to_complete)
 	old = link;
 
 	/* Now we check if a transition has happened */
-	if (link_check && (link.link_status == 0)) {
+	if (link_check && (link.link_status == ETH_LINK_DOWN)) {
 		hw->mac.ops.get_link_up_info(hw, &link.link_speed,
 			&link.link_duplex);
-		link.link_status = 1;
-	} else if (!link_check && (link.link_status == 1)) {
+		link.link_status = ETH_LINK_UP;
+	} else if (!link_check && (link.link_status == ETH_LINK_UP)) {
 		link.link_speed = 0;
 		link.link_duplex = 0;
-		link.link_status = 0;
+		link.link_status = ETH_LINK_DOWN;
 	}
 	rte_em_dev_atomic_write_link_status(dev, &link);
 
diff --git a/drivers/net/e1000/igb_ethdev.c b/drivers/net/e1000/igb_ethdev.c
index 9a34d01..311f866 100644
--- a/drivers/net/e1000/igb_ethdev.c
+++ b/drivers/net/e1000/igb_ethdev.c
@@ -2030,11 +2030,11 @@ eth_igb_link_update(struct rte_eth_dev *dev, int wait_to_complete)
 	if (link_check) {
 		hw->mac.ops.get_link_up_info(hw, &link.link_speed,
 					  &link.link_duplex);
-		link.link_status = 1;
+		link.link_status = ETH_LINK_UP;
 	} else if (!link_check) {
 		link.link_speed = 0;
 		link.link_duplex = 0;
-		link.link_status = 0;
+		link.link_status = ETH_LINK_DOWN;
 	}
 	rte_igb_dev_atomic_write_link_status(dev, &link);
 
diff --git a/drivers/net/fm10k/fm10k_ethdev.c b/drivers/net/fm10k/fm10k_ethdev.c
index 4b07a8b..edc8c11 100644
--- a/drivers/net/fm10k/fm10k_ethdev.c
+++ b/drivers/net/fm10k/fm10k_ethdev.c
@@ -1249,7 +1249,7 @@ fm10k_link_update(struct rte_eth_dev *dev,
 	 * is no 50Gbps Ethernet. */
 	dev->data->dev_link.link_speed  = 0;
 	dev->data->dev_link.link_duplex = ETH_LINK_FULL_DUPLEX;
-	dev->data->dev_link.link_status = 1;
+	dev->data->dev_link.link_status = ETH_LINK_UP;
 
 	return 0;
 }
diff --git a/drivers/net/i40e/i40e_ethdev_vf.c b/drivers/net/i40e/i40e_ethdev_vf.c
index 6b7b350..de00aff 100644
--- a/drivers/net/i40e/i40e_ethdev_vf.c
+++ b/drivers/net/i40e/i40e_ethdev_vf.c
@@ -1959,7 +1959,7 @@ i40evf_dev_link_update(struct rte_eth_dev *dev,
 		/* Always assume it's up, for Linux driver PF host */
 		new_link.link_duplex = ETH_LINK_AUTONEG_DUPLEX;
 		new_link.link_speed  = ETH_LINK_SPEED_10000;
-		new_link.link_status = 1;
+		new_link.link_status = ETH_LINK_UP;
 	}
 	i40evf_dev_atomic_write_link_status(dev, &new_link);
 
diff --git a/drivers/net/ixgbe/ixgbe_ethdev.c b/drivers/net/ixgbe/ixgbe_ethdev.c
index 5371720..be28f7e 100644
--- a/drivers/net/ixgbe/ixgbe_ethdev.c
+++ b/drivers/net/ixgbe/ixgbe_ethdev.c
@@ -2995,7 +2995,7 @@ ixgbe_dev_link_update(struct rte_eth_dev *dev, int wait_to_complete)
 	int link_up;
 	int diag;
 
-	link.link_status = 0;
+	link.link_status = ETH_LINK_DOWN;
 	link.link_speed = 0;
 	link.link_duplex = 0;
 	memset(&old, 0, sizeof(old));
@@ -3024,7 +3024,7 @@ ixgbe_dev_link_update(struct rte_eth_dev *dev, int wait_to_complete)
 			return -1;
 		return 0;
 	}
-	link.link_status = 1;
+	link.link_status = ETH_LINK_UP;
 	link.link_duplex = ETH_LINK_FULL_DUPLEX;
 
 	switch (link_speed) {
diff --git a/drivers/net/mpipe/mpipe_tilegx.c b/drivers/net/mpipe/mpipe_tilegx.c
index aef7600..1e04b75 100644
--- a/drivers/net/mpipe/mpipe_tilegx.c
+++ b/drivers/net/mpipe/mpipe_tilegx.c
@@ -397,11 +397,11 @@ mpipe_link_update(struct rte_eth_dev *dev, int wait_to_complete)
 		if (speed == GXIO_MPIPE_LINK_1G) {
 			new.link_speed = ETH_LINK_SPEED_1000;
 			new.link_duplex = ETH_LINK_FULL_DUPLEX;
-			new.link_status = 1;
+			new.link_status = ETH_LINK_UP;
 		} else if (speed == GXIO_MPIPE_LINK_10G) {
 			new.link_speed = ETH_LINK_SPEED_10000;
 			new.link_duplex = ETH_LINK_FULL_DUPLEX;
-			new.link_status = 1;
+			new.link_status = ETH_LINK_UP;
 		}
 
 		rc = mpipe_link_compare(&old, &new);
@@ -848,9 +848,9 @@ mpipe_start(struct rte_eth_dev *dev)
 
 	/* Start xmit/recv on queues. */
 	for (queue = 0; queue < priv->nb_tx_queues; queue++)
-		mpipe_tx_queue(priv, queue)->q.link_status = 1;
+		mpipe_tx_queue(priv, queue)->q.link_status = ETH_LINK_UP;
 	for (queue = 0; queue < priv->nb_rx_queues; queue++)
-		mpipe_rx_queue(priv, queue)->q.link_status = 1;
+		mpipe_rx_queue(priv, queue)->q.link_status = ETH_LINK_UP;
 	priv->running = 1;
 
 	return 0;
@@ -865,9 +865,9 @@ mpipe_stop(struct rte_eth_dev *dev)
 	int rc;
 
 	for (queue = 0; queue < priv->nb_tx_queues; queue++)
-		mpipe_tx_queue(priv, queue)->q.link_status = 0;
+		mpipe_tx_queue(priv, queue)->q.link_status = ETH_LINK_DOWN;
 	for (queue = 0; queue < priv->nb_rx_queues; queue++)
-		mpipe_rx_queue(priv, queue)->q.link_status = 0;
+		mpipe_rx_queue(priv, queue)->q.link_status = ETH_LINK_DOWN;
 
 	/* Make sure the link_status writes land. */
 	rte_wmb();
diff --git a/drivers/net/nfp/nfp_net.c b/drivers/net/nfp/nfp_net.c
index 8810704..7cb7d76 100644
--- a/drivers/net/nfp/nfp_net.c
+++ b/drivers/net/nfp/nfp_net.c
@@ -817,7 +817,7 @@ nfp_net_link_update(struct rte_eth_dev *dev, __rte_unused int wait_to_complete)
 	memset(&link, 0, sizeof(struct rte_eth_link));
 
 	if (nn_link_status & NFP_NET_CFG_STS_LINK)
-		link.link_status = 1;
+		link.link_status = ETH_LINK_UP;
 
 	link.link_duplex = ETH_LINK_FULL_DUPLEX;
 	/* Other cards can limit the tx and rx rate per VF */
diff --git a/drivers/net/null/rte_eth_null.c b/drivers/net/null/rte_eth_null.c
index 1c354ad..6adea91 100644
--- a/drivers/net/null/rte_eth_null.c
+++ b/drivers/net/null/rte_eth_null.c
@@ -91,7 +91,7 @@ static const char *drivername = "Null PMD";
 static struct rte_eth_link pmd_link = {
 	.link_speed = 10000,
 	.link_duplex = ETH_LINK_FULL_DUPLEX,
-	.link_status = 0
+	.link_status = ETH_LINK_DOWN,
 };
 
 static uint16_t
@@ -199,7 +199,7 @@ eth_dev_start(struct rte_eth_dev *dev)
 	if (dev == NULL)
 		return -EINVAL;
 
-	dev->data->dev_link.link_status = 1;
+	dev->data->dev_link.link_status = ETH_LINK_UP;
 	return 0;
 }
 
@@ -209,7 +209,7 @@ eth_dev_stop(struct rte_eth_dev *dev)
 	if (dev == NULL)
 		return;
 
-	dev->data->dev_link.link_status = 0;
+	dev->data->dev_link.link_status = ETH_LINK_DOWN;
 }
 
 static int
diff --git a/drivers/net/pcap/rte_eth_pcap.c b/drivers/net/pcap/rte_eth_pcap.c
index 5202086..b90c725 100644
--- a/drivers/net/pcap/rte_eth_pcap.c
+++ b/drivers/net/pcap/rte_eth_pcap.c
@@ -125,7 +125,7 @@ static const char *drivername = "Pcap PMD";
 static struct rte_eth_link pmd_link = {
 		.link_speed = 10000,
 		.link_duplex = ETH_LINK_FULL_DUPLEX,
-		.link_status = 0
+		.link_status = ETH_LINK_DOWN,
 };
 
 static int
@@ -428,7 +428,7 @@ eth_dev_start(struct rte_eth_dev *dev)
 
 status_up:
 
-	dev->data->dev_link.link_status = 1;
+	dev->data->dev_link.link_status = ETH_LINK_UP;
 	return 0;
 }
 
@@ -479,7 +479,7 @@ eth_dev_stop(struct rte_eth_dev *dev)
 	}
 
 status_down:
-	dev->data->dev_link.link_status = 0;
+	dev->data->dev_link.link_status = ETH_LINK_DOWN;
 }
 
 static int
diff --git a/drivers/net/ring/rte_eth_ring.c b/drivers/net/ring/rte_eth_ring.c
index ba19cd7..4335c6a 100644
--- a/drivers/net/ring/rte_eth_ring.c
+++ b/drivers/net/ring/rte_eth_ring.c
@@ -79,7 +79,7 @@ static const char *drivername = "Rings PMD";
 static struct rte_eth_link pmd_link = {
 		.link_speed = 10000,
 		.link_duplex = ETH_LINK_FULL_DUPLEX,
-		.link_status = 0
+		.link_status = ETH_LINK_DOWN,
 };
 
 static uint16_t
@@ -119,27 +119,27 @@ eth_dev_configure(struct rte_eth_dev *dev __rte_unused) { return 0; }
 static int
 eth_dev_start(struct rte_eth_dev *dev)
 {
-	dev->data->dev_link.link_status = 1;
+	dev->data->dev_link.link_status = ETH_LINK_UP;
 	return 0;
 }
 
 static void
 eth_dev_stop(struct rte_eth_dev *dev)
 {
-	dev->data->dev_link.link_status = 0;
+	dev->data->dev_link.link_status = ETH_LINK_DOWN;
 }
 
 static int
 eth_dev_set_link_down(struct rte_eth_dev *dev)
 {
-	dev->data->dev_link.link_status = 0;
+	dev->data->dev_link.link_status = ETH_LINK_DOWN;
 	return 0;
 }
 
 static int
 eth_dev_set_link_up(struct rte_eth_dev *dev)
 {
-	dev->data->dev_link.link_status = 1;
+	dev->data->dev_link.link_status = ETH_LINK_UP;
 	return 0;
 }
 
diff --git a/drivers/net/szedata2/rte_eth_szedata2.c b/drivers/net/szedata2/rte_eth_szedata2.c
index 81c806e..c65067e 100644
--- a/drivers/net/szedata2/rte_eth_szedata2.c
+++ b/drivers/net/szedata2/rte_eth_szedata2.c
@@ -1172,7 +1172,7 @@ eth_link_update(struct rte_eth_dev *dev,
 	link.link_duplex = ETH_LINK_FULL_DUPLEX;
 
 	link.link_status = (cgmii_ibuf_is_enabled(ibuf) &&
-			cgmii_ibuf_is_link_up(ibuf)) ? 1 : 0;
+			cgmii_ibuf_is_link_up(ibuf)) ? ETH_LINK_UP : ETH_LINK_DOWN;
 
 	rte_atomic64_cmpset((uint64_t *)dev_link, *(uint64_t *)dev_link,
 			*(uint64_t *)link_ptr);
diff --git a/drivers/net/virtio/virtio_ethdev.c b/drivers/net/virtio/virtio_ethdev.c
index 86c96c9..3ebc221 100644
--- a/drivers/net/virtio/virtio_ethdev.c
+++ b/drivers/net/virtio/virtio_ethdev.c
@@ -1410,16 +1410,16 @@ virtio_dev_link_update(struct rte_eth_dev *dev, __rte_unused int wait_to_complet
 				offsetof(struct virtio_net_config, status),
 				&status, sizeof(status));
 		if ((status & VIRTIO_NET_S_LINK_UP) == 0) {
-			link.link_status = 0;
+			link.link_status = ETH_LINK_DOWN;
 			PMD_INIT_LOG(DEBUG, "Port %d is down",
 				     dev->data->port_id);
 		} else {
-			link.link_status = 1;
+			link.link_status = ETH_LINK_UP;
 			PMD_INIT_LOG(DEBUG, "Port %d is up",
 				     dev->data->port_id);
 		}
 	} else {
-		link.link_status = 1;   /* Link up */
+		link.link_status = ETH_LINK_UP;
 	}
 	virtio_dev_atomic_write_link_status(dev, &link);
 
diff --git a/drivers/net/vmxnet3/vmxnet3_ethdev.c b/drivers/net/vmxnet3/vmxnet3_ethdev.c
index a5c9ba5..7fe3a53 100644
--- a/drivers/net/vmxnet3/vmxnet3_ethdev.c
+++ b/drivers/net/vmxnet3/vmxnet3_ethdev.c
@@ -760,7 +760,7 @@ vmxnet3_dev_link_update(struct rte_eth_dev *dev, __attribute__((unused)) int wai
 	ret = VMXNET3_READ_BAR1_REG(hw, VMXNET3_REG_CMD);
 
 	if (ret & 0x1) {
-		link.link_status = 1;
+		link.link_status = ETH_LINK_UP;
 		link.link_duplex = ETH_LINK_FULL_DUPLEX;
 		link.link_speed = ETH_LINK_SPEED_10000;
 	}
diff --git a/drivers/net/xenvirt/rte_eth_xenvirt.c b/drivers/net/xenvirt/rte_eth_xenvirt.c
index 3f31806..9453a06 100644
--- a/drivers/net/xenvirt/rte_eth_xenvirt.c
+++ b/drivers/net/xenvirt/rte_eth_xenvirt.c
@@ -72,7 +72,7 @@ static const char *drivername = "xen virtio PMD";
 static struct rte_eth_link pmd_link = {
 		.link_speed = 10000,
 		.link_duplex = ETH_LINK_FULL_DUPLEX,
-		.link_status = 0
+		.link_status = ETH_LINK_DOWN,
 };
 
 static void
@@ -290,7 +290,7 @@ eth_dev_start(struct rte_eth_dev *dev)
 	struct pmd_internals *pi = (struct pmd_internals *)dev->data->dev_private;
 	int rv;
 
-	dev->data->dev_link.link_status = 1;
+	dev->data->dev_link.link_status = ETH_LINK_UP;
 	while (!virtqueue_full(rxvq)) {
 		m = rte_rxmbuf_alloc(rxvq->mpool);
 		if (m == NULL)
@@ -318,7 +318,7 @@ eth_dev_stop(struct rte_eth_dev *dev)
 {
 	struct pmd_internals *pi = (struct pmd_internals *)dev->data->dev_private;
 
-	dev->data->dev_link.link_status = 0;
+	dev->data->dev_link.link_status = ETH_LINK_DOWN;
 	dev_stop_notify(pi->virtio_idx);
 }
 
diff --git a/examples/exception_path/main.c b/examples/exception_path/main.c
index b3fe170..bec9804 100644
--- a/examples/exception_path/main.c
+++ b/examples/exception_path/main.c
@@ -485,7 +485,7 @@ check_all_ports_link_status(uint8_t port_num, uint32_t port_mask)
 				continue;
 			}
 			/* clear all_ports_up flag if any link down */
-			if (link.link_status == 0) {
+			if (link.link_status == ETH_LINK_DOWN) {
 				all_ports_up = 0;
 				break;
 			}
diff --git a/examples/ip_fragmentation/main.c b/examples/ip_fragmentation/main.c
index 8021702..81a4918 100644
--- a/examples/ip_fragmentation/main.c
+++ b/examples/ip_fragmentation/main.c
@@ -631,7 +631,7 @@ check_all_ports_link_status(uint8_t port_num, uint32_t port_mask)
 				continue;
 			}
 			/* clear all_ports_up flag if any link down */
-			if (link.link_status == 0) {
+			if (link.link_status == ETH_LINK_DOWN) {
 				all_ports_up = 0;
 				break;
 			}
diff --git a/examples/ip_pipeline/init.c b/examples/ip_pipeline/init.c
index e59a6b4..83422e8 100644
--- a/examples/ip_pipeline/init.c
+++ b/examples/ip_pipeline/init.c
@@ -856,7 +856,7 @@ app_check_link(struct app_params *app)
 			link_params.link_speed / 1000,
 			link_params.link_status ? "UP" : "DOWN");
 
-		if (link_params.link_status == 0)
+		if (link_params.link_status == ETH_LINK_DOWN)
 			all_links_up = 0;
 	}
 
diff --git a/examples/ip_reassembly/main.c b/examples/ip_reassembly/main.c
index 19ec46c..c27e735 100644
--- a/examples/ip_reassembly/main.c
+++ b/examples/ip_reassembly/main.c
@@ -763,7 +763,7 @@ check_all_ports_link_status(uint8_t port_num, uint32_t port_mask)
 				continue;
 			}
 			/* clear all_ports_up flag if any link down */
-			if (link.link_status == 0) {
+			if (link.link_status == ETH_LINK_DOWN) {
 				all_ports_up = 0;
 				break;
 			}
diff --git a/examples/ipsec-secgw/ipsec-secgw.c b/examples/ipsec-secgw/ipsec-secgw.c
index d6c9a5d..393f9bd 100644
--- a/examples/ipsec-secgw/ipsec-secgw.c
+++ b/examples/ipsec-secgw/ipsec-secgw.c
@@ -945,7 +945,7 @@ check_all_ports_link_status(uint8_t port_num, uint32_t port_mask)
 				continue;
 			}
 			/* clear all_ports_up flag if any link down */
-			if (link.link_status == 0) {
+			if (link.link_status == ETH_LINK_DOWN) {
 				all_ports_up = 0;
 				break;
 			}
diff --git a/examples/ipv4_multicast/main.c b/examples/ipv4_multicast/main.c
index 5dbea1a..96b4157 100644
--- a/examples/ipv4_multicast/main.c
+++ b/examples/ipv4_multicast/main.c
@@ -642,7 +642,7 @@ check_all_ports_link_status(uint8_t port_num, uint32_t port_mask)
 				continue;
 			}
 			/* clear all_ports_up flag if any link down */
-			if (link.link_status == 0) {
+			if (link.link_status == ETH_LINK_DOWN) {
 				all_ports_up = 0;
 				break;
 			}
diff --git a/examples/kni/main.c b/examples/kni/main.c
index 6d434ad..a5297f2 100644
--- a/examples/kni/main.c
+++ b/examples/kni/main.c
@@ -670,7 +670,7 @@ check_all_ports_link_status(uint8_t port_num, uint32_t port_mask)
 				continue;
 			}
 			/* clear all_ports_up flag if any link down */
-			if (link.link_status == 0) {
+			if (link.link_status == ETH_LINK_DOWN) {
 				all_ports_up = 0;
 				break;
 			}
diff --git a/examples/l2fwd-crypto/main.c b/examples/l2fwd-crypto/main.c
index 762d22a..fef5b0c 100644
--- a/examples/l2fwd-crypto/main.c
+++ b/examples/l2fwd-crypto/main.c
@@ -1238,7 +1238,7 @@ check_all_ports_link_status(uint8_t port_num, uint32_t port_mask)
 				continue;
 			}
 			/* clear all_ports_up flag if any link down */
-			if (link.link_status == 0) {
+			if (link.link_status == ETH_LINK_DOWN) {
 				all_ports_up = 0;
 				break;
 			}
diff --git a/examples/l2fwd-ivshmem/host/host.c b/examples/l2fwd-ivshmem/host/host.c
index 6e6ed5e..4bd7c41 100644
--- a/examples/l2fwd-ivshmem/host/host.c
+++ b/examples/l2fwd-ivshmem/host/host.c
@@ -371,7 +371,7 @@ check_all_ports_link_status(uint8_t port_num, uint32_t port_mask)
 				continue;
 			}
 			/* clear all_ports_up flag if any link down */
-			if (link.link_status == 0) {
+			if (link.link_status == ETH_LINK_DOWN) {
 				all_ports_up = 0;
 				break;
 			}
diff --git a/examples/l2fwd-jobstats/main.c b/examples/l2fwd-jobstats/main.c
index d1e9bf7..9f3a77d 100644
--- a/examples/l2fwd-jobstats/main.c
+++ b/examples/l2fwd-jobstats/main.c
@@ -746,7 +746,7 @@ check_all_ports_link_status(uint8_t port_num, uint32_t port_mask)
 				continue;
 			}
 			/* clear all_ports_up flag if any link down */
-			if (link.link_status == 0) {
+			if (link.link_status == ETH_LINK_DOWN) {
 				all_ports_up = 0;
 				break;
 			}
diff --git a/examples/l2fwd-keepalive/main.c b/examples/l2fwd-keepalive/main.c
index 94b8677..8da89aa 100644
--- a/examples/l2fwd-keepalive/main.c
+++ b/examples/l2fwd-keepalive/main.c
@@ -499,7 +499,7 @@ check_all_ports_link_status(uint8_t port_num, uint32_t port_mask)
 				continue;
 			}
 			/* clear all_ports_up flag if any link down */
-			if (link.link_status == 0) {
+			if (link.link_status == ETH_LINK_DOWN) {
 				all_ports_up = 0;
 				break;
 			}
diff --git a/examples/l2fwd/main.c b/examples/l2fwd/main.c
index e175681..1ad9488 100644
--- a/examples/l2fwd/main.c
+++ b/examples/l2fwd/main.c
@@ -480,7 +480,7 @@ check_all_ports_link_status(uint8_t port_num, uint32_t port_mask)
 				continue;
 			}
 			/* clear all_ports_up flag if any link down */
-			if (link.link_status == 0) {
+			if (link.link_status == ETH_LINK_DOWN) {
 				all_ports_up = 0;
 				break;
 			}
diff --git a/examples/l3fwd-acl/main.c b/examples/l3fwd-acl/main.c
index 3a895b7..621872f 100644
--- a/examples/l3fwd-acl/main.c
+++ b/examples/l3fwd-acl/main.c
@@ -1858,7 +1858,7 @@ check_all_ports_link_status(uint8_t port_num, uint32_t port_mask)
 				continue;
 			}
 			/* clear all_ports_up flag if any link down */
-			if (link.link_status == 0) {
+			if (link.link_status == ETH_LINK_DOWN) {
 				all_ports_up = 0;
 				break;
 			}
diff --git a/examples/l3fwd-power/main.c b/examples/l3fwd-power/main.c
index e7ebe30..5934efe 100644
--- a/examples/l3fwd-power/main.c
+++ b/examples/l3fwd-power/main.c
@@ -1509,7 +1509,7 @@ check_all_ports_link_status(uint8_t port_num, uint32_t port_mask)
 				continue;
 			}
 			/* clear all_ports_up flag if any link down */
-			if (link.link_status == 0) {
+			if (link.link_status == ETH_LINK_DOWN) {
 				all_ports_up = 0;
 				break;
 			}
diff --git a/examples/l3fwd/main.c b/examples/l3fwd/main.c
index 8520f71..04eae16 100644
--- a/examples/l3fwd/main.c
+++ b/examples/l3fwd/main.c
@@ -746,7 +746,7 @@ check_all_ports_link_status(uint8_t port_num, uint32_t port_mask)
 				continue;
 			}
 			/* clear all_ports_up flag if any link down */
-			if (link.link_status == 0) {
+			if (link.link_status == ETH_LINK_DOWN) {
 				all_ports_up = 0;
 				break;
 			}
diff --git a/examples/link_status_interrupt/main.c b/examples/link_status_interrupt/main.c
index cbc29bc..9981598 100644
--- a/examples/link_status_interrupt/main.c
+++ b/examples/link_status_interrupt/main.c
@@ -523,7 +523,7 @@ check_all_ports_link_status(uint8_t port_num, uint32_t port_mask)
 				continue;
 			}
 			/* clear all_ports_up flag if any link down */
-			if (link.link_status == 0) {
+			if (link.link_status == ETH_LINK_DOWN) {
 				all_ports_up = 0;
 				break;
 			}
diff --git a/examples/load_balancer/init.c b/examples/load_balancer/init.c
index a96d778..e07850b 100644
--- a/examples/load_balancer/init.c
+++ b/examples/load_balancer/init.c
@@ -395,7 +395,7 @@ check_all_ports_link_status(uint8_t port_num, uint32_t port_mask)
 				continue;
 			}
 			/* clear all_ports_up flag if any link down */
-			if (link.link_status == 0) {
+			if (link.link_status == ETH_LINK_DOWN) {
 				all_ports_up = 0;
 				break;
 			}
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 1078ffd..ecb61c6 100644
--- a/examples/multi_process/client_server_mp/mp_server/init.c
+++ b/examples/multi_process/client_server_mp/mp_server/init.c
@@ -226,7 +226,7 @@ check_all_ports_link_status(uint8_t port_num, uint32_t port_mask)
 				continue;
 			}
 			/* clear all_ports_up flag if any link down */
-			if (link.link_status == 0) {
+			if (link.link_status == ETH_LINK_DOWN) {
 				all_ports_up = 0;
 				break;
 			}
diff --git a/examples/multi_process/l2fwd_fork/main.c b/examples/multi_process/l2fwd_fork/main.c
index aebf531..2dc8b82 100644
--- a/examples/multi_process/l2fwd_fork/main.c
+++ b/examples/multi_process/l2fwd_fork/main.c
@@ -900,7 +900,7 @@ check_all_ports_link_status(uint8_t port_num, uint32_t port_mask)
 				continue;
 			}
 			/* clear all_ports_up flag if any link down */
-			if (link.link_status == 0) {
+			if (link.link_status == ETH_LINK_DOWN) {
 				all_ports_up = 0;
 				break;
 			}
diff --git a/examples/multi_process/symmetric_mp/main.c b/examples/multi_process/symmetric_mp/main.c
index 72bad54..6bbff07 100644
--- a/examples/multi_process/symmetric_mp/main.c
+++ b/examples/multi_process/symmetric_mp/main.c
@@ -388,7 +388,7 @@ check_all_ports_link_status(uint8_t port_num, uint32_t port_mask)
 				continue;
 			}
 			/* clear all_ports_up flag if any link down */
-			if (link.link_status == 0) {
+			if (link.link_status == ETH_LINK_DOWN) {
 				all_ports_up = 0;
 				break;
 			}
diff --git a/examples/performance-thread/l3fwd-thread/main.c b/examples/performance-thread/l3fwd-thread/main.c
index 7bcca37..aa1fdc3 100644
--- a/examples/performance-thread/l3fwd-thread/main.c
+++ b/examples/performance-thread/l3fwd-thread/main.c
@@ -3407,7 +3407,7 @@ check_all_ports_link_status(uint8_t port_num, uint32_t port_mask)
 				continue;
 			}
 			/* clear all_ports_up flag if any link down */
-			if (link.link_status == 0) {
+			if (link.link_status == ETH_LINK_DOWN) {
 				all_ports_up = 0;
 				break;
 			}
diff --git a/lib/librte_ether/rte_ethdev.h b/lib/librte_ether/rte_ethdev.h
index b5704e1..ec8d6b1 100644
--- a/lib/librte_ether/rte_ethdev.h
+++ b/lib/librte_ether/rte_ethdev.h
@@ -247,7 +247,7 @@ struct rte_eth_stats {
 struct rte_eth_link {
 	uint16_t link_speed;      /**< ETH_LINK_SPEED_[10, 100, 1000, 10000] */
 	uint16_t link_duplex;     /**< ETH_LINK_[HALF_DUPLEX, FULL_DUPLEX] */
-	uint8_t  link_status : 1; /**< 1 -> link up, 0 -> link down */
+	uint8_t  link_status : 1; /**< ETH_LINK_[DOWN/UP] */
 }__attribute__((aligned(8)));     /**< aligned for atomic64 read/write */
 
 #define ETH_LINK_SPEED_AUTONEG  0       /**< Auto-negotiate link speed. */
@@ -259,9 +259,12 @@ struct rte_eth_link {
 #define ETH_LINK_SPEED_20G      20000   /**< 20 gigabits/second. */
 #define ETH_LINK_SPEED_40G      40000   /**< 40 gigabits/second. */
 
+/* Utility constants */
 #define ETH_LINK_AUTONEG_DUPLEX 0       /**< Auto-negotiate duplex. */
 #define ETH_LINK_HALF_DUPLEX    1       /**< Half-duplex connection. */
 #define ETH_LINK_FULL_DUPLEX    2       /**< Full-duplex connection. */
+#define ETH_LINK_DOWN           0 /**< Link is down. */
+#define ETH_LINK_UP             1 /**< Link is up. */
 
 /**
  * A structure used to configure the ring threshold registers of an RX/TX
-- 
2.7.0

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

* [PATCH v11 2/8] ethdev: use constants for link duplex
  2016-03-17 18:08           ` [PATCH v11 0/8] ethdev: 100G and link speed API refactoring Thomas Monjalon
  2016-03-17 18:08             ` [PATCH v11 1/8] ethdev: use constants for link state Thomas Monjalon
@ 2016-03-17 18:08             ` Thomas Monjalon
  2016-03-23  2:44               ` Zhang, Helin
  2016-03-17 18:09             ` [PATCH v11 3/8] app/testpmd: move speed and duplex parsing in a function Thomas Monjalon
                               ` (8 subsequent siblings)
  10 siblings, 1 reply; 167+ messages in thread
From: Thomas Monjalon @ 2016-03-17 18:08 UTC (permalink / raw)
  To: marcdevel, bruce.richardson, declan.doherty, konstantin.ananyev,
	wenzhuo.lu, helin.zhang, jing.d.chen, harish.patil,
	rahul.lakkireddy, johndale, vido, adrien.mazarguil,
	alejandro.lucero
  Cc: dev

From: Marc Sune <marcdevel@gmail.com>

Some duplex values are replaced from 0 to half-duplex when link is down.

Some drivers are still using their own constants for duplex modes.

Signed-off-by: Marc Sune <marcdevel@gmail.com>
---
 drivers/net/e1000/em_ethdev.c      | 2 +-
 drivers/net/e1000/igb_ethdev.c     | 2 +-
 drivers/net/ixgbe/ixgbe_ethdev.c   | 2 +-
 drivers/net/virtio/virtio_ethdev.c | 2 +-
 drivers/net/virtio/virtio_ethdev.h | 2 --
 lib/librte_ether/rte_ethdev.h      | 2 +-
 6 files changed, 5 insertions(+), 7 deletions(-)

diff --git a/drivers/net/e1000/em_ethdev.c b/drivers/net/e1000/em_ethdev.c
index 58093c6..943a270 100644
--- a/drivers/net/e1000/em_ethdev.c
+++ b/drivers/net/e1000/em_ethdev.c
@@ -1108,7 +1108,7 @@ eth_em_link_update(struct rte_eth_dev *dev, int wait_to_complete)
 		link.link_status = ETH_LINK_UP;
 	} else if (!link_check && (link.link_status == ETH_LINK_UP)) {
 		link.link_speed = 0;
-		link.link_duplex = 0;
+		link.link_duplex = ETH_LINK_HALF_DUPLEX;
 		link.link_status = ETH_LINK_DOWN;
 	}
 	rte_em_dev_atomic_write_link_status(dev, &link);
diff --git a/drivers/net/e1000/igb_ethdev.c b/drivers/net/e1000/igb_ethdev.c
index 311f866..ea156ce 100644
--- a/drivers/net/e1000/igb_ethdev.c
+++ b/drivers/net/e1000/igb_ethdev.c
@@ -2033,7 +2033,7 @@ eth_igb_link_update(struct rte_eth_dev *dev, int wait_to_complete)
 		link.link_status = ETH_LINK_UP;
 	} else if (!link_check) {
 		link.link_speed = 0;
-		link.link_duplex = 0;
+		link.link_duplex = ETH_LINK_HALF_DUPLEX;
 		link.link_status = ETH_LINK_DOWN;
 	}
 	rte_igb_dev_atomic_write_link_status(dev, &link);
diff --git a/drivers/net/ixgbe/ixgbe_ethdev.c b/drivers/net/ixgbe/ixgbe_ethdev.c
index be28f7e..35dac49 100644
--- a/drivers/net/ixgbe/ixgbe_ethdev.c
+++ b/drivers/net/ixgbe/ixgbe_ethdev.c
@@ -2997,7 +2997,7 @@ ixgbe_dev_link_update(struct rte_eth_dev *dev, int wait_to_complete)
 
 	link.link_status = ETH_LINK_DOWN;
 	link.link_speed = 0;
-	link.link_duplex = 0;
+	link.link_duplex = ETH_LINK_HALF_DUPLEX;
 	memset(&old, 0, sizeof(old));
 	rte_ixgbe_dev_atomic_read_link_status(dev, &old);
 
diff --git a/drivers/net/virtio/virtio_ethdev.c b/drivers/net/virtio/virtio_ethdev.c
index 3ebc221..63a368a 100644
--- a/drivers/net/virtio/virtio_ethdev.c
+++ b/drivers/net/virtio/virtio_ethdev.c
@@ -1401,7 +1401,7 @@ virtio_dev_link_update(struct rte_eth_dev *dev, __rte_unused int wait_to_complet
 	memset(&link, 0, sizeof(link));
 	virtio_dev_atomic_read_link_status(dev, &link);
 	old = link;
-	link.link_duplex = FULL_DUPLEX;
+	link.link_duplex = ETH_LINK_FULL_DUPLEX;
 	link.link_speed  = SPEED_10G;
 
 	if (vtpci_with_feature(hw, VIRTIO_NET_F_STATUS)) {
diff --git a/drivers/net/virtio/virtio_ethdev.h b/drivers/net/virtio/virtio_ethdev.h
index fed9571..66423a0 100644
--- a/drivers/net/virtio/virtio_ethdev.h
+++ b/drivers/net/virtio/virtio_ethdev.h
@@ -42,8 +42,6 @@
 #define SPEED_100	100
 #define SPEED_1000	1000
 #define SPEED_10G	10000
-#define HALF_DUPLEX	1
-#define FULL_DUPLEX	2
 
 #ifndef PAGE_SIZE
 #define PAGE_SIZE 4096
diff --git a/lib/librte_ether/rte_ethdev.h b/lib/librte_ether/rte_ethdev.h
index ec8d6b1..5379bee 100644
--- a/lib/librte_ether/rte_ethdev.h
+++ b/lib/librte_ether/rte_ethdev.h
@@ -246,7 +246,7 @@ struct rte_eth_stats {
  */
 struct rte_eth_link {
 	uint16_t link_speed;      /**< ETH_LINK_SPEED_[10, 100, 1000, 10000] */
-	uint16_t link_duplex;     /**< ETH_LINK_[HALF_DUPLEX, FULL_DUPLEX] */
+	uint16_t link_duplex;     /**< ETH_LINK_[HALF/FULL]_DUPLEX */
 	uint8_t  link_status : 1; /**< ETH_LINK_[DOWN/UP] */
 }__attribute__((aligned(8)));     /**< aligned for atomic64 read/write */
 
-- 
2.7.0

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

* [PATCH v11 3/8] app/testpmd: move speed and duplex parsing in a function
  2016-03-17 18:08           ` [PATCH v11 0/8] ethdev: 100G and link speed API refactoring Thomas Monjalon
  2016-03-17 18:08             ` [PATCH v11 1/8] ethdev: use constants for link state Thomas Monjalon
  2016-03-17 18:08             ` [PATCH v11 2/8] ethdev: use constants for link duplex Thomas Monjalon
@ 2016-03-17 18:09             ` Thomas Monjalon
  2016-03-17 18:09             ` [PATCH v11 4/8] ethdev: rename link speed constants Thomas Monjalon
                               ` (7 subsequent siblings)
  10 siblings, 0 replies; 167+ messages in thread
From: Thomas Monjalon @ 2016-03-17 18:09 UTC (permalink / raw)
  To: marcdevel, bruce.richardson, declan.doherty, konstantin.ananyev,
	wenzhuo.lu, helin.zhang, jing.d.chen, harish.patil,
	rahul.lakkireddy, johndale, vido, adrien.mazarguil,
	alejandro.lucero
  Cc: dev

From: Marc Sune <marcdevel@gmail.com>

The code for checking and parsing speed/duplex was duplicated.
The new function is also checking the speed/duplex combination.

Signed-off-by: Marc Sune <marcdevel@gmail.com>
---
 app/test-pmd/cmdline.c | 99 ++++++++++++++++++++++++--------------------------
 1 file changed, 47 insertions(+), 52 deletions(-)

diff --git a/app/test-pmd/cmdline.c b/app/test-pmd/cmdline.c
index 9d52b8c..37be5cd 100644
--- a/app/test-pmd/cmdline.c
+++ b/app/test-pmd/cmdline.c
@@ -983,6 +983,49 @@ struct cmd_config_speed_all {
 	cmdline_fixed_string_t value2;
 };
 
+static int
+parse_and_check_speed_duplex(char *speedstr, char *duplexstr, uint16_t *speed)
+{
+
+	int duplex;
+
+	if (!strcmp(duplexstr, "half")) {
+		duplex = ETH_LINK_HALF_DUPLEX;
+	} else if (!strcmp(duplexstr, "full")) {
+		duplex = ETH_LINK_FULL_DUPLEX;
+	} else if (!strcmp(duplexstr, "auto")) {
+		duplex = ETH_LINK_FULL_DUPLEX;
+	} else {
+		printf("Unknown duplex parameter\n");
+		return -1;
+	}
+
+	if (!strcmp(speedstr, "10")) {
+		*speed = ETH_LINK_SPEED_10;
+	} else if (!strcmp(speedstr, "100")) {
+		*speed = ETH_LINK_SPEED_100;
+	} else {
+		if (duplex != ETH_LINK_FULL_DUPLEX) {
+			printf("Invalid speed/duplex parameters\n");
+			return -1;
+		}
+		if (!strcmp(speedstr, "1000")) {
+			*speed = ETH_LINK_SPEED_1000;
+		} else if (!strcmp(speedstr, "10000")) {
+			*speed = ETH_LINK_SPEED_10G;
+		} else if (!strcmp(speedstr, "40000")) {
+			*speed = ETH_LINK_SPEED_40G;
+		} else if (!strcmp(speedstr, "auto")) {
+			*speed = ETH_LINK_SPEED_AUTONEG;
+		} else {
+			printf("Unknown speed parameter\n");
+			return -1;
+		}
+	}
+
+	return 0;
+}
+
 static void
 cmd_config_speed_all_parsed(void *parsed_result,
 			__attribute__((unused)) struct cmdline *cl,
@@ -998,33 +1041,9 @@ cmd_config_speed_all_parsed(void *parsed_result,
 		return;
 	}
 
-	if (!strcmp(res->value1, "10"))
-		link_speed = ETH_LINK_SPEED_10;
-	else if (!strcmp(res->value1, "100"))
-		link_speed = ETH_LINK_SPEED_100;
-	else if (!strcmp(res->value1, "1000"))
-		link_speed = ETH_LINK_SPEED_1000;
-	else if (!strcmp(res->value1, "10000"))
-		link_speed = ETH_LINK_SPEED_10G;
-	else if (!strcmp(res->value1, "40000"))
-		link_speed = ETH_LINK_SPEED_40G;
-	else if (!strcmp(res->value1, "auto"))
-		link_speed = ETH_LINK_SPEED_AUTONEG;
-	else {
-		printf("Unknown parameter\n");
+	if (parse_and_check_speed_duplex(res->value1, res->value2,
+			&link_speed) < 0)
 		return;
-	}
-
-	if (!strcmp(res->value2, "half"))
-		link_duplex = ETH_LINK_HALF_DUPLEX;
-	else if (!strcmp(res->value2, "full"))
-		link_duplex = ETH_LINK_FULL_DUPLEX;
-	else if (!strcmp(res->value2, "auto"))
-		link_duplex = ETH_LINK_AUTONEG_DUPLEX;
-	else {
-		printf("Unknown parameter\n");
-		return;
-	}
 
 	FOREACH_PORT(pid, ports) {
 		ports[pid].dev_conf.link_speed = link_speed;
@@ -1097,33 +1116,9 @@ cmd_config_speed_specific_parsed(void *parsed_result,
 	if (port_id_is_invalid(res->id, ENABLED_WARN))
 		return;
 
-	if (!strcmp(res->value1, "10"))
-		link_speed = ETH_LINK_SPEED_10;
-	else if (!strcmp(res->value1, "100"))
-		link_speed = ETH_LINK_SPEED_100;
-	else if (!strcmp(res->value1, "1000"))
-		link_speed = ETH_LINK_SPEED_1000;
-	else if (!strcmp(res->value1, "10000"))
-		link_speed = ETH_LINK_SPEED_10000;
-	else if (!strcmp(res->value1, "40000"))
-		link_speed = ETH_LINK_SPEED_40G;
-	else if (!strcmp(res->value1, "auto"))
-		link_speed = ETH_LINK_SPEED_AUTONEG;
-	else {
-		printf("Unknown parameter\n");
-		return;
-	}
-
-	if (!strcmp(res->value2, "half"))
-		link_duplex = ETH_LINK_HALF_DUPLEX;
-	else if (!strcmp(res->value2, "full"))
-		link_duplex = ETH_LINK_FULL_DUPLEX;
-	else if (!strcmp(res->value2, "auto"))
-		link_duplex = ETH_LINK_AUTONEG_DUPLEX;
-	else {
-		printf("Unknown parameter\n");
+	if (parse_and_check_speed_duplex(res->value1, res->value2,
+			&link_speed) < 0)
 		return;
-	}
 
 	ports[res->id].dev_conf.link_speed = link_speed;
 	ports[res->id].dev_conf.link_duplex = link_duplex;
-- 
2.7.0

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

* [PATCH v11 4/8] ethdev: rename link speed constants
  2016-03-17 18:08           ` [PATCH v11 0/8] ethdev: 100G and link speed API refactoring Thomas Monjalon
                               ` (2 preceding siblings ...)
  2016-03-17 18:09             ` [PATCH v11 3/8] app/testpmd: move speed and duplex parsing in a function Thomas Monjalon
@ 2016-03-17 18:09             ` Thomas Monjalon
  2016-03-23  2:52               ` Zhang, Helin
  2016-03-17 18:09             ` [PATCH v11 5/8] ethdev: add speed capabilities Thomas Monjalon
                               ` (6 subsequent siblings)
  10 siblings, 1 reply; 167+ messages in thread
From: Thomas Monjalon @ 2016-03-17 18:09 UTC (permalink / raw)
  To: marcdevel, bruce.richardson, declan.doherty, konstantin.ananyev,
	wenzhuo.lu, helin.zhang, jing.d.chen, harish.patil,
	rahul.lakkireddy, johndale, vido, adrien.mazarguil,
	alejandro.lucero
  Cc: dev

From: Marc Sune <marcdevel@gmail.com>

The speed numbers ETH_LINK_SPEED_ are renamed ETH_SPEED_NUM_.
The prefix ETH_LINK_SPEED_ is kept for AUTONEG and will be used
for bit flags in next patch.

Signed-off-by: Marc Sune <marcdevel@gmail.com>
---
 app/test-pmd/cmdline.c                    | 10 +++++-----
 app/test/virtual_pmd.c                    |  2 +-
 drivers/net/af_packet/rte_eth_af_packet.c |  2 +-
 drivers/net/bonding/rte_eth_bond_8023ad.c | 12 ++++++------
 drivers/net/cxgbe/base/t4_hw.c            |  8 ++++----
 drivers/net/e1000/em_ethdev.c             |  8 ++++----
 drivers/net/e1000/igb_ethdev.c            |  8 ++++----
 drivers/net/i40e/i40e_ethdev.c            | 30 +++++++++++++++---------------
 drivers/net/i40e/i40e_ethdev_vf.c         |  2 +-
 drivers/net/ixgbe/ixgbe_ethdev.c          | 22 +++++++++++-----------
 drivers/net/mpipe/mpipe_tilegx.c          |  4 ++--
 drivers/net/nfp/nfp_net.c                 |  2 +-
 drivers/net/null/rte_eth_null.c           |  2 +-
 drivers/net/pcap/rte_eth_pcap.c           |  2 +-
 drivers/net/ring/rte_eth_ring.c           |  2 +-
 drivers/net/szedata2/rte_eth_szedata2.c   |  8 ++++----
 drivers/net/vmxnet3/vmxnet3_ethdev.c      |  2 +-
 drivers/net/xenvirt/rte_eth_xenvirt.c     |  2 +-
 lib/librte_ether/rte_ethdev.h             | 29 ++++++++++++++++++-----------
 19 files changed, 82 insertions(+), 75 deletions(-)

diff --git a/app/test-pmd/cmdline.c b/app/test-pmd/cmdline.c
index 37be5cd..874129a 100644
--- a/app/test-pmd/cmdline.c
+++ b/app/test-pmd/cmdline.c
@@ -1001,20 +1001,20 @@ parse_and_check_speed_duplex(char *speedstr, char *duplexstr, uint16_t *speed)
 	}
 
 	if (!strcmp(speedstr, "10")) {
-		*speed = ETH_LINK_SPEED_10;
+		*speed = ETH_SPEED_NUM_10M;
 	} else if (!strcmp(speedstr, "100")) {
-		*speed = ETH_LINK_SPEED_100;
+		*speed = ETH_SPEED_NUM_100M;
 	} else {
 		if (duplex != ETH_LINK_FULL_DUPLEX) {
 			printf("Invalid speed/duplex parameters\n");
 			return -1;
 		}
 		if (!strcmp(speedstr, "1000")) {
-			*speed = ETH_LINK_SPEED_1000;
+			*speed = ETH_SPEED_NUM_1G;
 		} else if (!strcmp(speedstr, "10000")) {
-			*speed = ETH_LINK_SPEED_10G;
+			*speed = ETH_SPEED_NUM_10G;
 		} else if (!strcmp(speedstr, "40000")) {
-			*speed = ETH_LINK_SPEED_40G;
+			*speed = ETH_SPEED_NUM_40G;
 		} else if (!strcmp(speedstr, "auto")) {
 			*speed = ETH_LINK_SPEED_AUTONEG;
 		} else {
diff --git a/app/test/virtual_pmd.c b/app/test/virtual_pmd.c
index b1d40d7..b4bd2f2 100644
--- a/app/test/virtual_pmd.c
+++ b/app/test/virtual_pmd.c
@@ -604,7 +604,7 @@ virtual_ethdev_create(const char *name, struct ether_addr *mac_addr,
 	TAILQ_INIT(&(eth_dev->link_intr_cbs));
 
 	eth_dev->data->dev_link.link_status = ETH_LINK_DOWN;
-	eth_dev->data->dev_link.link_speed = ETH_LINK_SPEED_10000;
+	eth_dev->data->dev_link.link_speed = ETH_SPEED_NUM_10G;
 	eth_dev->data->dev_link.link_duplex = ETH_LINK_FULL_DUPLEX;
 
 	eth_dev->data->mac_addrs = rte_zmalloc(name, ETHER_ADDR_LEN, 0);
diff --git a/drivers/net/af_packet/rte_eth_af_packet.c b/drivers/net/af_packet/rte_eth_af_packet.c
index dee7b59..641f849 100644
--- a/drivers/net/af_packet/rte_eth_af_packet.c
+++ b/drivers/net/af_packet/rte_eth_af_packet.c
@@ -116,7 +116,7 @@ static const char *valid_arguments[] = {
 static const char *drivername = "AF_PACKET PMD";
 
 static struct rte_eth_link pmd_link = {
-	.link_speed = 10000,
+	.link_speed = ETH_SPEED_NUM_10G,
 	.link_duplex = ETH_LINK_FULL_DUPLEX,
 	.link_status = ETH_LINK_DOWN,
 };
diff --git a/drivers/net/bonding/rte_eth_bond_8023ad.c b/drivers/net/bonding/rte_eth_bond_8023ad.c
index 1b7e93a..ac8306f 100644
--- a/drivers/net/bonding/rte_eth_bond_8023ad.c
+++ b/drivers/net/bonding/rte_eth_bond_8023ad.c
@@ -711,22 +711,22 @@ link_speed_key(uint16_t speed) {
 	case ETH_LINK_SPEED_AUTONEG:
 		key_speed = 0x00;
 		break;
-	case ETH_LINK_SPEED_10:
+	case ETH_SPEED_NUM_10M:
 		key_speed = BOND_LINK_SPEED_KEY_10M;
 		break;
-	case ETH_LINK_SPEED_100:
+	case ETH_SPEED_NUM_100M:
 		key_speed = BOND_LINK_SPEED_KEY_100M;
 		break;
-	case ETH_LINK_SPEED_1000:
+	case ETH_SPEED_NUM_1G:
 		key_speed = BOND_LINK_SPEED_KEY_1000M;
 		break;
-	case ETH_LINK_SPEED_10G:
+	case ETH_SPEED_NUM_10G:
 		key_speed = BOND_LINK_SPEED_KEY_10G;
 		break;
-	case ETH_LINK_SPEED_20G:
+	case ETH_SPEED_NUM_20G:
 		key_speed = BOND_LINK_SPEED_KEY_20G;
 		break;
-	case ETH_LINK_SPEED_40G:
+	case ETH_SPEED_NUM_40G:
 		key_speed = BOND_LINK_SPEED_KEY_40G;
 		break;
 	default:
diff --git a/drivers/net/cxgbe/base/t4_hw.c b/drivers/net/cxgbe/base/t4_hw.c
index 884d2cf..79af806 100644
--- a/drivers/net/cxgbe/base/t4_hw.c
+++ b/drivers/net/cxgbe/base/t4_hw.c
@@ -2159,13 +2159,13 @@ int t4_handle_fw_rpl(struct adapter *adap, const __be64 *rpl)
 		if (stat & F_FW_PORT_CMD_TXPAUSE)
 			fc |= PAUSE_TX;
 		if (stat & V_FW_PORT_CMD_LSPEED(FW_PORT_CAP_SPEED_100M))
-			speed = ETH_LINK_SPEED_100;
+			speed = ETH_SPEED_NUM_100M;
 		else if (stat & V_FW_PORT_CMD_LSPEED(FW_PORT_CAP_SPEED_1G))
-			speed = ETH_LINK_SPEED_1000;
+			speed = ETH_SPEED_NUM_1G;
 		else if (stat & V_FW_PORT_CMD_LSPEED(FW_PORT_CAP_SPEED_10G))
-			speed = ETH_LINK_SPEED_10000;
+			speed = ETH_SPEED_NUM_10G;
 		else if (stat & V_FW_PORT_CMD_LSPEED(FW_PORT_CAP_SPEED_40G))
-			speed = ETH_LINK_SPEED_40G;
+			speed = ETH_SPEED_NUM_40G;
 
 		for_each_port(adap, i) {
 			pi = adap2pinfo(adap, i);
diff --git a/drivers/net/e1000/em_ethdev.c b/drivers/net/e1000/em_ethdev.c
index 943a270..b9dbc0f 100644
--- a/drivers/net/e1000/em_ethdev.c
+++ b/drivers/net/e1000/em_ethdev.c
@@ -625,7 +625,7 @@ eth_em_start(struct rte_eth_dev *dev)
 		else
 			goto error_invalid_config;
 		break;
-	case ETH_LINK_SPEED_10:
+	case ETH_SPEED_NUM_10M:
 		if (dev->data->dev_conf.link_duplex == ETH_LINK_AUTONEG_DUPLEX)
 			hw->phy.autoneg_advertised = E1000_ALL_10_SPEED;
 		else if (dev->data->dev_conf.link_duplex ==
@@ -637,7 +637,7 @@ eth_em_start(struct rte_eth_dev *dev)
 		else
 			goto error_invalid_config;
 		break;
-	case ETH_LINK_SPEED_100:
+	case ETH_SPEED_NUM_100M:
 		if (dev->data->dev_conf.link_duplex == ETH_LINK_AUTONEG_DUPLEX)
 			hw->phy.autoneg_advertised = E1000_ALL_100_SPEED;
 		else if (dev->data->dev_conf.link_duplex ==
@@ -649,7 +649,7 @@ eth_em_start(struct rte_eth_dev *dev)
 		else
 			goto error_invalid_config;
 		break;
-	case ETH_LINK_SPEED_1000:
+	case ETH_SPEED_NUM_1G:
 		if ((dev->data->dev_conf.link_duplex ==
 				ETH_LINK_AUTONEG_DUPLEX) ||
 			(dev->data->dev_conf.link_duplex ==
@@ -658,7 +658,7 @@ eth_em_start(struct rte_eth_dev *dev)
 		else
 			goto error_invalid_config;
 		break;
-	case ETH_LINK_SPEED_10000:
+	case ETH_SPEED_NUM_10G:
 	default:
 		goto error_invalid_config;
 	}
diff --git a/drivers/net/e1000/igb_ethdev.c b/drivers/net/e1000/igb_ethdev.c
index ea156ce..11786ef 100644
--- a/drivers/net/e1000/igb_ethdev.c
+++ b/drivers/net/e1000/igb_ethdev.c
@@ -1241,7 +1241,7 @@ eth_igb_start(struct rte_eth_dev *dev)
 		else
 			goto error_invalid_config;
 		break;
-	case ETH_LINK_SPEED_10:
+	case ETH_SPEED_NUM_10M:
 		if (dev->data->dev_conf.link_duplex == ETH_LINK_AUTONEG_DUPLEX)
 			hw->phy.autoneg_advertised = E1000_ALL_10_SPEED;
 		else if (dev->data->dev_conf.link_duplex == ETH_LINK_HALF_DUPLEX)
@@ -1251,7 +1251,7 @@ eth_igb_start(struct rte_eth_dev *dev)
 		else
 			goto error_invalid_config;
 		break;
-	case ETH_LINK_SPEED_100:
+	case ETH_SPEED_NUM_100M:
 		if (dev->data->dev_conf.link_duplex == ETH_LINK_AUTONEG_DUPLEX)
 			hw->phy.autoneg_advertised = E1000_ALL_100_SPEED;
 		else if (dev->data->dev_conf.link_duplex == ETH_LINK_HALF_DUPLEX)
@@ -1261,14 +1261,14 @@ eth_igb_start(struct rte_eth_dev *dev)
 		else
 			goto error_invalid_config;
 		break;
-	case ETH_LINK_SPEED_1000:
+	case ETH_SPEED_NUM_1G:
 		if ((dev->data->dev_conf.link_duplex == ETH_LINK_AUTONEG_DUPLEX) ||
 				(dev->data->dev_conf.link_duplex == ETH_LINK_FULL_DUPLEX))
 			hw->phy.autoneg_advertised = ADVERTISE_1000_FULL;
 		else
 			goto error_invalid_config;
 		break;
-	case ETH_LINK_SPEED_10000:
+	case ETH_SPEED_NUM_10G:
 	default:
 		goto error_invalid_config;
 	}
diff --git a/drivers/net/i40e/i40e_ethdev.c b/drivers/net/i40e/i40e_ethdev.c
index 10e0d38..5d8bdd9 100644
--- a/drivers/net/i40e/i40e_ethdev.c
+++ b/drivers/net/i40e/i40e_ethdev.c
@@ -1372,19 +1372,19 @@ i40e_parse_link_speed(uint16_t eth_link_speed)
 	uint8_t link_speed = I40E_LINK_SPEED_UNKNOWN;
 
 	switch (eth_link_speed) {
-	case ETH_LINK_SPEED_40G:
+	case ETH_SPEED_NUM_40G:
 		link_speed = I40E_LINK_SPEED_40GB;
 		break;
-	case ETH_LINK_SPEED_20G:
+	case ETH_SPEED_NUM_20G:
 		link_speed = I40E_LINK_SPEED_20GB;
 		break;
-	case ETH_LINK_SPEED_10G:
+	case ETH_SPEED_NUM_10G:
 		link_speed = I40E_LINK_SPEED_10GB;
 		break;
-	case ETH_LINK_SPEED_1000:
+	case ETH_SPEED_NUM_1G:
 		link_speed = I40E_LINK_SPEED_1GB;
 		break;
-	case ETH_LINK_SPEED_100:
+	case ETH_SPEED_NUM_100M:
 		link_speed = I40E_LINK_SPEED_100MB;
 		break;
 	}
@@ -1754,7 +1754,7 @@ i40e_dev_link_update(struct rte_eth_dev *dev,
 		/* Get link status information from hardware */
 		status = i40e_aq_get_link_info(hw, false, &link_status, NULL);
 		if (status != I40E_SUCCESS) {
-			link.link_speed = ETH_LINK_SPEED_100;
+			link.link_speed = ETH_SPEED_NUM_100M;
 			link.link_duplex = ETH_LINK_FULL_DUPLEX;
 			PMD_DRV_LOG(ERR, "Failed to get link info");
 			goto out;
@@ -1776,22 +1776,22 @@ i40e_dev_link_update(struct rte_eth_dev *dev,
 	/* Parse the link status */
 	switch (link_status.link_speed) {
 	case I40E_LINK_SPEED_100MB:
-		link.link_speed = ETH_LINK_SPEED_100;
+		link.link_speed = ETH_SPEED_NUM_100M;
 		break;
 	case I40E_LINK_SPEED_1GB:
-		link.link_speed = ETH_LINK_SPEED_1000;
+		link.link_speed = ETH_SPEED_NUM_1G;
 		break;
 	case I40E_LINK_SPEED_10GB:
-		link.link_speed = ETH_LINK_SPEED_10G;
+		link.link_speed = ETH_SPEED_NUM_10G;
 		break;
 	case I40E_LINK_SPEED_20GB:
-		link.link_speed = ETH_LINK_SPEED_20G;
+		link.link_speed = ETH_SPEED_NUM_20G;
 		break;
 	case I40E_LINK_SPEED_40GB:
-		link.link_speed = ETH_LINK_SPEED_40G;
+		link.link_speed = ETH_SPEED_NUM_40G;
 		break;
 	default:
-		link.link_speed = ETH_LINK_SPEED_100;
+		link.link_speed = ETH_SPEED_NUM_100M;
 		break;
 	}
 
@@ -8087,15 +8087,15 @@ i40e_start_timecounters(struct rte_eth_dev *dev)
 	rte_i40e_dev_atomic_read_link_status(dev, &link);
 
 	switch (link.link_speed) {
-	case ETH_LINK_SPEED_40G:
+	case ETH_SPEED_NUM_40G:
 		tsync_inc_l = I40E_PTP_40GB_INCVAL & 0xFFFFFFFF;
 		tsync_inc_h = I40E_PTP_40GB_INCVAL >> 32;
 		break;
-	case ETH_LINK_SPEED_10G:
+	case ETH_SPEED_NUM_10G:
 		tsync_inc_l = I40E_PTP_10GB_INCVAL & 0xFFFFFFFF;
 		tsync_inc_h = I40E_PTP_10GB_INCVAL >> 32;
 		break;
-	case ETH_LINK_SPEED_1000:
+	case ETH_SPEED_NUM_1G:
 		tsync_inc_l = I40E_PTP_1GB_INCVAL & 0xFFFFFFFF;
 		tsync_inc_h = I40E_PTP_1GB_INCVAL >> 32;
 		break;
diff --git a/drivers/net/i40e/i40e_ethdev_vf.c b/drivers/net/i40e/i40e_ethdev_vf.c
index de00aff..f2b37a2 100644
--- a/drivers/net/i40e/i40e_ethdev_vf.c
+++ b/drivers/net/i40e/i40e_ethdev_vf.c
@@ -1958,7 +1958,7 @@ i40evf_dev_link_update(struct rte_eth_dev *dev,
 	else {
 		/* Always assume it's up, for Linux driver PF host */
 		new_link.link_duplex = ETH_LINK_AUTONEG_DUPLEX;
-		new_link.link_speed  = ETH_LINK_SPEED_10000;
+		new_link.link_speed  = ETH_SPEED_NUM_10G;
 		new_link.link_status = ETH_LINK_UP;
 	}
 	i40evf_dev_atomic_write_link_status(dev, &new_link);
diff --git a/drivers/net/ixgbe/ixgbe_ethdev.c b/drivers/net/ixgbe/ixgbe_ethdev.c
index 35dac49..9246fdb 100644
--- a/drivers/net/ixgbe/ixgbe_ethdev.c
+++ b/drivers/net/ixgbe/ixgbe_ethdev.c
@@ -2179,17 +2179,17 @@ ixgbe_dev_start(struct rte_eth_dev *dev)
 				IXGBE_LINK_SPEED_82599_AUTONEG :
 				IXGBE_LINK_SPEED_82598_AUTONEG;
 		break;
-	case ETH_LINK_SPEED_100:
+	case ETH_SPEED_NUM_100M:
 		/*
 		 * Invalid for 82598 but error will be detected by
 		 * ixgbe_setup_link()
 		 */
 		speed = IXGBE_LINK_SPEED_100_FULL;
 		break;
-	case ETH_LINK_SPEED_1000:
+	case ETH_SPEED_NUM_1G:
 		speed = IXGBE_LINK_SPEED_1GB_FULL;
 		break;
-	case ETH_LINK_SPEED_10000:
+	case ETH_SPEED_NUM_10G:
 		speed = IXGBE_LINK_SPEED_10GB_FULL;
 		break;
 	default:
@@ -3010,7 +3010,7 @@ ixgbe_dev_link_update(struct rte_eth_dev *dev, int wait_to_complete)
 		diag = ixgbe_check_link(hw, &link_speed, &link_up, 1);
 
 	if (diag != 0) {
-		link.link_speed = ETH_LINK_SPEED_100;
+		link.link_speed = ETH_SPEED_NUM_100M;
 		link.link_duplex = ETH_LINK_HALF_DUPLEX;
 		rte_ixgbe_dev_atomic_write_link_status(dev, &link);
 		if (link.link_status == old.link_status)
@@ -3031,19 +3031,19 @@ ixgbe_dev_link_update(struct rte_eth_dev *dev, int wait_to_complete)
 	default:
 	case IXGBE_LINK_SPEED_UNKNOWN:
 		link.link_duplex = ETH_LINK_HALF_DUPLEX;
-		link.link_speed = ETH_LINK_SPEED_100;
+		link.link_speed = ETH_SPEED_NUM_100M;
 		break;
 
 	case IXGBE_LINK_SPEED_100_FULL:
-		link.link_speed = ETH_LINK_SPEED_100;
+		link.link_speed = ETH_SPEED_NUM_100M;
 		break;
 
 	case IXGBE_LINK_SPEED_1GB_FULL:
-		link.link_speed = ETH_LINK_SPEED_1000;
+		link.link_speed = ETH_SPEED_NUM_1G;
 		break;
 
 	case IXGBE_LINK_SPEED_10GB_FULL:
-		link.link_speed = ETH_LINK_SPEED_10000;
+		link.link_speed = ETH_SPEED_NUM_10G;
 		break;
 	}
 	rte_ixgbe_dev_atomic_write_link_status(dev, &link);
@@ -5838,15 +5838,15 @@ ixgbe_start_timecounters(struct rte_eth_dev *dev)
 	rte_ixgbe_dev_atomic_read_link_status(dev, &link);
 
 	switch (link.link_speed) {
-	case ETH_LINK_SPEED_100:
+	case ETH_SPEED_NUM_100M:
 		incval = IXGBE_INCVAL_100;
 		shift = IXGBE_INCVAL_SHIFT_100;
 		break;
-	case ETH_LINK_SPEED_1000:
+	case ETH_SPEED_NUM_1G:
 		incval = IXGBE_INCVAL_1GB;
 		shift = IXGBE_INCVAL_SHIFT_1GB;
 		break;
-	case ETH_LINK_SPEED_10000:
+	case ETH_SPEED_NUM_10G:
 	default:
 		incval = IXGBE_INCVAL_10GB;
 		shift = IXGBE_INCVAL_SHIFT_10GB;
diff --git a/drivers/net/mpipe/mpipe_tilegx.c b/drivers/net/mpipe/mpipe_tilegx.c
index 1e04b75..960d468 100644
--- a/drivers/net/mpipe/mpipe_tilegx.c
+++ b/drivers/net/mpipe/mpipe_tilegx.c
@@ -395,11 +395,11 @@ mpipe_link_update(struct rte_eth_dev *dev, int wait_to_complete)
 		speed = state & GXIO_MPIPE_LINK_SPEED_MASK;
 
 		if (speed == GXIO_MPIPE_LINK_1G) {
-			new.link_speed = ETH_LINK_SPEED_1000;
+			new.link_speed = ETH_SPEED_NUM_1G;
 			new.link_duplex = ETH_LINK_FULL_DUPLEX;
 			new.link_status = ETH_LINK_UP;
 		} else if (speed == GXIO_MPIPE_LINK_10G) {
-			new.link_speed = ETH_LINK_SPEED_10000;
+			new.link_speed = ETH_SPEED_NUM_10G;
 			new.link_duplex = ETH_LINK_FULL_DUPLEX;
 			new.link_status = ETH_LINK_UP;
 		}
diff --git a/drivers/net/nfp/nfp_net.c b/drivers/net/nfp/nfp_net.c
index 7cb7d76..9e314bd 100644
--- a/drivers/net/nfp/nfp_net.c
+++ b/drivers/net/nfp/nfp_net.c
@@ -821,7 +821,7 @@ nfp_net_link_update(struct rte_eth_dev *dev, __rte_unused int wait_to_complete)
 
 	link.link_duplex = ETH_LINK_FULL_DUPLEX;
 	/* Other cards can limit the tx and rx rate per VF */
-	link.link_speed = ETH_LINK_SPEED_40G;
+	link.link_speed = ETH_SPEED_NUM_40G;
 
 	if (old.link_status != link.link_status) {
 		nfp_net_dev_atomic_write_link_status(dev, &link);
diff --git a/drivers/net/null/rte_eth_null.c b/drivers/net/null/rte_eth_null.c
index 6adea91..5640585 100644
--- a/drivers/net/null/rte_eth_null.c
+++ b/drivers/net/null/rte_eth_null.c
@@ -89,7 +89,7 @@ struct pmd_internals {
 static struct ether_addr eth_addr = { .addr_bytes = {0} };
 static const char *drivername = "Null PMD";
 static struct rte_eth_link pmd_link = {
-	.link_speed = 10000,
+	.link_speed = ETH_SPEED_NUM_10G,
 	.link_duplex = ETH_LINK_FULL_DUPLEX,
 	.link_status = ETH_LINK_DOWN,
 };
diff --git a/drivers/net/pcap/rte_eth_pcap.c b/drivers/net/pcap/rte_eth_pcap.c
index b90c725..c657951 100644
--- a/drivers/net/pcap/rte_eth_pcap.c
+++ b/drivers/net/pcap/rte_eth_pcap.c
@@ -123,7 +123,7 @@ static int open_single_iface(const char *iface, pcap_t **pcap);
 static struct ether_addr eth_addr = { .addr_bytes = { 0, 0, 0, 0x1, 0x2, 0x3 } };
 static const char *drivername = "Pcap PMD";
 static struct rte_eth_link pmd_link = {
-		.link_speed = 10000,
+		.link_speed = ETH_SPEED_NUM_10G,
 		.link_duplex = ETH_LINK_FULL_DUPLEX,
 		.link_status = ETH_LINK_DOWN,
 };
diff --git a/drivers/net/ring/rte_eth_ring.c b/drivers/net/ring/rte_eth_ring.c
index 4335c6a..58685e9 100644
--- a/drivers/net/ring/rte_eth_ring.c
+++ b/drivers/net/ring/rte_eth_ring.c
@@ -77,7 +77,7 @@ struct pmd_internals {
 
 static const char *drivername = "Rings PMD";
 static struct rte_eth_link pmd_link = {
-		.link_speed = 10000,
+		.link_speed = ETH_SPEED_NUM_10G,
 		.link_duplex = ETH_LINK_FULL_DUPLEX,
 		.link_status = ETH_LINK_DOWN,
 };
diff --git a/drivers/net/szedata2/rte_eth_szedata2.c b/drivers/net/szedata2/rte_eth_szedata2.c
index c65067e..854cb5c 100644
--- a/drivers/net/szedata2/rte_eth_szedata2.c
+++ b/drivers/net/szedata2/rte_eth_szedata2.c
@@ -1149,10 +1149,10 @@ eth_link_update(struct rte_eth_dev *dev,
 
 	switch (cgmii_link_speed(ibuf)) {
 	case SZEDATA2_LINK_SPEED_10G:
-		link.link_speed = ETH_LINK_SPEED_10G;
+		link.link_speed = ETH_SPEED_NUM_10G;
 		break;
 	case SZEDATA2_LINK_SPEED_40G:
-		link.link_speed = ETH_LINK_SPEED_40G;
+		link.link_speed = ETH_SPEED_NUM_40G;
 		break;
 	case SZEDATA2_LINK_SPEED_100G:
 		/*
@@ -1161,10 +1161,10 @@ eth_link_update(struct rte_eth_dev *dev,
 		 * will be changed to support 100Gbps speed change
 		 * this value to 100G.
 		 */
-		link.link_speed = ETH_LINK_SPEED_10G;
+		link.link_speed = ETH_SPEED_NUM_10G;
 		break;
 	default:
-		link.link_speed = ETH_LINK_SPEED_10G;
+		link.link_speed = ETH_SPEED_NUM_10G;
 		break;
 	}
 
diff --git a/drivers/net/vmxnet3/vmxnet3_ethdev.c b/drivers/net/vmxnet3/vmxnet3_ethdev.c
index 7fe3a53..ad8029b 100644
--- a/drivers/net/vmxnet3/vmxnet3_ethdev.c
+++ b/drivers/net/vmxnet3/vmxnet3_ethdev.c
@@ -762,7 +762,7 @@ vmxnet3_dev_link_update(struct rte_eth_dev *dev, __attribute__((unused)) int wai
 	if (ret & 0x1) {
 		link.link_status = ETH_LINK_UP;
 		link.link_duplex = ETH_LINK_FULL_DUPLEX;
-		link.link_speed = ETH_LINK_SPEED_10000;
+		link.link_speed = ETH_SPEED_NUM_10G;
 	}
 
 	vmxnet3_dev_atomic_write_link_status(dev, &link);
diff --git a/drivers/net/xenvirt/rte_eth_xenvirt.c b/drivers/net/xenvirt/rte_eth_xenvirt.c
index 9453a06..77d3ba1 100644
--- a/drivers/net/xenvirt/rte_eth_xenvirt.c
+++ b/drivers/net/xenvirt/rte_eth_xenvirt.c
@@ -70,7 +70,7 @@ static int virtio_idx = 0;
 static const char *drivername = "xen virtio PMD";
 
 static struct rte_eth_link pmd_link = {
-		.link_speed = 10000,
+		.link_speed = ETH_SPEED_NUM_10G,
 		.link_duplex = ETH_LINK_FULL_DUPLEX,
 		.link_status = ETH_LINK_DOWN,
 };
diff --git a/lib/librte_ether/rte_ethdev.h b/lib/librte_ether/rte_ethdev.h
index 5379bee..d7c8a66 100644
--- a/lib/librte_ether/rte_ethdev.h
+++ b/lib/librte_ether/rte_ethdev.h
@@ -242,23 +242,30 @@ struct rte_eth_stats {
 };
 
 /**
+ * Ethernet numeric link speeds in Mbps
+ */
+#define ETH_LINK_SPEED_AUTONEG     0 /**< Auto-negotiate link speed. */
+#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 */
+
+/**
  * A structure used to retrieve link-level information of an Ethernet port.
  */
 struct rte_eth_link {
-	uint16_t link_speed;      /**< ETH_LINK_SPEED_[10, 100, 1000, 10000] */
+	uint16_t link_speed;      /**< ETH_SPEED_NUM_ */
 	uint16_t link_duplex;     /**< ETH_LINK_[HALF/FULL]_DUPLEX */
 	uint8_t  link_status : 1; /**< ETH_LINK_[DOWN/UP] */
 }__attribute__((aligned(8)));     /**< aligned for atomic64 read/write */
 
-#define ETH_LINK_SPEED_AUTONEG  0       /**< Auto-negotiate link speed. */
-#define ETH_LINK_SPEED_10       10      /**< 10 megabits/second. */
-#define ETH_LINK_SPEED_100      100     /**< 100 megabits/second. */
-#define ETH_LINK_SPEED_1000     1000    /**< 1 gigabits/second. */
-#define ETH_LINK_SPEED_10000    10000   /**< 10 gigabits/second. */
-#define ETH_LINK_SPEED_10G      10000   /**< alias of 10 gigabits/second. */
-#define ETH_LINK_SPEED_20G      20000   /**< 20 gigabits/second. */
-#define ETH_LINK_SPEED_40G      40000   /**< 40 gigabits/second. */
-
 /* Utility constants */
 #define ETH_LINK_AUTONEG_DUPLEX 0       /**< Auto-negotiate duplex. */
 #define ETH_LINK_HALF_DUPLEX    1       /**< Half-duplex connection. */
@@ -779,7 +786,7 @@ struct rte_intr_conf {
  */
 struct rte_eth_conf {
 	uint16_t link_speed;
-	/**< ETH_LINK_SPEED_10[0|00|000], or 0 for autonegotation */
+	/**< ETH_SPEED_NUM_ or 0 for autonegotiation */
 	uint16_t link_duplex;
 	/**< ETH_LINK_[HALF_DUPLEX|FULL_DUPLEX], or 0 for autonegotation */
 	struct rte_eth_rxmode rxmode; /**< Port RX configuration. */
-- 
2.7.0

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

* [PATCH v11 5/8] ethdev: add speed capabilities
  2016-03-17 18:08           ` [PATCH v11 0/8] ethdev: 100G and link speed API refactoring Thomas Monjalon
                               ` (3 preceding siblings ...)
  2016-03-17 18:09             ` [PATCH v11 4/8] ethdev: rename link speed constants Thomas Monjalon
@ 2016-03-17 18:09             ` Thomas Monjalon
  2016-03-18  5:18               ` Chen, Jing D
  2016-03-18  9:28               ` Adrien Mazarguil
  2016-03-17 18:09             ` [PATCH v11 6/8] ethdev: redesign link speed config Thomas Monjalon
                               ` (5 subsequent siblings)
  10 siblings, 2 replies; 167+ messages in thread
From: Thomas Monjalon @ 2016-03-17 18:09 UTC (permalink / raw)
  To: marcdevel, bruce.richardson, declan.doherty, konstantin.ananyev,
	wenzhuo.lu, helin.zhang, jing.d.chen, harish.patil,
	rahul.lakkireddy, johndale, vido, adrien.mazarguil,
	alejandro.lucero
  Cc: dev

From: Marc Sune <marcdevel@gmail.com>

The speed capabilities of a device can be retrieved with
rte_eth_dev_info_get().

The new field speed_capa is initialized in the drivers without
taking care of device characteristics in this patch.
When the capabilities of a driver are accurate, the table in
overview.rst must be filled.

Signed-off-by: Marc Sune <marcdevel@gmail.com>
---
 doc/guides/nics/overview.rst           |  1 +
 doc/guides/rel_notes/release_16_04.rst |  8 ++++++++
 drivers/net/bnx2x/bnx2x_ethdev.c       |  1 +
 drivers/net/cxgbe/cxgbe_ethdev.c       |  1 +
 drivers/net/e1000/em_ethdev.c          |  4 ++++
 drivers/net/e1000/igb_ethdev.c         |  4 ++++
 drivers/net/fm10k/fm10k_ethdev.c       |  4 ++++
 drivers/net/i40e/i40e_ethdev.c         |  8 ++++++++
 drivers/net/ixgbe/ixgbe_ethdev.c       |  8 ++++++++
 drivers/net/mlx4/mlx4.c                |  2 ++
 drivers/net/mlx5/mlx5_ethdev.c         |  3 +++
 drivers/net/nfp/nfp_net.c              |  2 ++
 lib/librte_ether/rte_ethdev.h          | 21 +++++++++++++++++++++
 13 files changed, 67 insertions(+)

diff --git a/doc/guides/nics/overview.rst b/doc/guides/nics/overview.rst
index 2d4f014..893da5f 100644
--- a/doc/guides/nics/overview.rst
+++ b/doc/guides/nics/overview.rst
@@ -88,6 +88,7 @@ Most of these differences are summarized below.
    ==================== = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
    link status                  X     X X                                   X
    link status event                  X X
+   speed capabilities
    Rx interrupt                       X X X X
    queue start/stop             X     X X X X                               X
    MTU update                   X
diff --git a/doc/guides/rel_notes/release_16_04.rst b/doc/guides/rel_notes/release_16_04.rst
index 2785b29..6ecd304 100644
--- a/doc/guides/rel_notes/release_16_04.rst
+++ b/doc/guides/rel_notes/release_16_04.rst
@@ -47,6 +47,11 @@ This section should contain new features added in this release. Sample format:
   A new function ``rte_pktmbuf_alloc_bulk()`` has been added to allow the user
   to allocate a bulk of mbufs.
 
+* **Added device link speed capabilities.**
+
+  The structure ``rte_eth_dev_info`` has now a ``speed_capa`` bitmap, which
+  allows the application to know the supported speeds of each device.
+
 * **Restored vmxnet3 Tx data ring.**
 
   Tx data ring has been shown to improve small pkt forwarding performance
@@ -394,6 +399,9 @@ This section should contain API changes. Sample format:
 * Add a short 1-2 sentence description of the API change. Use fixed width
   quotes for ``rte_function_names`` or ``rte_struct_names``. Use the past tense.
 
+* The ethdev structure ``rte_eth_dev_info`` was changed to support device
+  speed capabilities.
+
 * The functions ``rte_eth_dev_udp_tunnel_add`` and ``rte_eth_dev_udp_tunnel_delete``
   have been renamed into ``rte_eth_dev_udp_tunnel_port_add`` and
   ``rte_eth_dev_udp_tunnel_port_delete``.
diff --git a/drivers/net/bnx2x/bnx2x_ethdev.c b/drivers/net/bnx2x/bnx2x_ethdev.c
index dc9ce84..607d2f4 100644
--- a/drivers/net/bnx2x/bnx2x_ethdev.c
+++ b/drivers/net/bnx2x/bnx2x_ethdev.c
@@ -327,6 +327,7 @@ bnx2x_dev_infos_get(struct rte_eth_dev *dev, __rte_unused struct rte_eth_dev_inf
 	dev_info->min_rx_bufsize = BNX2X_MIN_RX_BUF_SIZE;
 	dev_info->max_rx_pktlen  = BNX2X_MAX_RX_PKT_LEN;
 	dev_info->max_mac_addrs  = BNX2X_MAX_MAC_ADDRS;
+	dev_info->speed_capa = ETH_LINK_SPEED_10G | ETH_LINK_SPEED_20G;
 }
 
 static void
diff --git a/drivers/net/cxgbe/cxgbe_ethdev.c b/drivers/net/cxgbe/cxgbe_ethdev.c
index 8c6dd59..bccdca0 100644
--- a/drivers/net/cxgbe/cxgbe_ethdev.c
+++ b/drivers/net/cxgbe/cxgbe_ethdev.c
@@ -171,6 +171,7 @@ static void cxgbe_dev_info_get(struct rte_eth_dev *eth_dev,
 
 	device_info->rx_desc_lim = cxgbe_desc_lim;
 	device_info->tx_desc_lim = cxgbe_desc_lim;
+	device_info->speed_capa = ETH_LINK_SPEED_10G | ETH_LINK_SPEED_40G;
 }
 
 static void cxgbe_dev_promiscuous_enable(struct rte_eth_dev *eth_dev)
diff --git a/drivers/net/e1000/em_ethdev.c b/drivers/net/e1000/em_ethdev.c
index b9dbc0f..2a50857 100644
--- a/drivers/net/e1000/em_ethdev.c
+++ b/drivers/net/e1000/em_ethdev.c
@@ -1055,6 +1055,10 @@ eth_em_infos_get(struct rte_eth_dev *dev, struct rte_eth_dev_info *dev_info)
 		.nb_min = E1000_MIN_RING_DESC,
 		.nb_align = EM_TXD_ALIGN,
 	};
+
+	dev_info->speed_capa = ETH_LINK_SPEED_10M_HD | ETH_LINK_SPEED_10M |
+			ETH_LINK_SPEED_100M_HD | ETH_LINK_SPEED_100M |
+			ETH_LINK_SPEED_1G;
 }
 
 /* return 0 means link status changed, -1 means not changed */
diff --git a/drivers/net/e1000/igb_ethdev.c b/drivers/net/e1000/igb_ethdev.c
index 11786ef..b7e706a 100644
--- a/drivers/net/e1000/igb_ethdev.c
+++ b/drivers/net/e1000/igb_ethdev.c
@@ -1919,6 +1919,10 @@ eth_igb_infos_get(struct rte_eth_dev *dev, struct rte_eth_dev_info *dev_info)
 
 	dev_info->rx_desc_lim = rx_desc_lim;
 	dev_info->tx_desc_lim = tx_desc_lim;
+
+	dev_info->speed_capa = ETH_LINK_SPEED_10M_HD | ETH_LINK_SPEED_10M |
+			ETH_LINK_SPEED_100M_HD | ETH_LINK_SPEED_100M |
+			ETH_LINK_SPEED_1G;
 }
 
 static void
diff --git a/drivers/net/fm10k/fm10k_ethdev.c b/drivers/net/fm10k/fm10k_ethdev.c
index edc8c11..2a1c222 100644
--- a/drivers/net/fm10k/fm10k_ethdev.c
+++ b/drivers/net/fm10k/fm10k_ethdev.c
@@ -1410,6 +1410,10 @@ fm10k_dev_infos_get(struct rte_eth_dev *dev,
 		.nb_min = FM10K_MIN_TX_DESC,
 		.nb_align = FM10K_MULT_TX_DESC,
 	};
+
+	dev_info->speed_capa = ETH_LINK_SPEED_1G | ETH_LINK_SPEED_2_5G |
+			ETH_LINK_SPEED_10G | ETH_LINK_SPEED_25G |
+			ETH_LINK_SPEED_40G;
 }
 
 static int
diff --git a/drivers/net/i40e/i40e_ethdev.c b/drivers/net/i40e/i40e_ethdev.c
index 5d8bdd9..dee7ef7 100644
--- a/drivers/net/i40e/i40e_ethdev.c
+++ b/drivers/net/i40e/i40e_ethdev.c
@@ -2274,6 +2274,7 @@ static void
 i40e_dev_info_get(struct rte_eth_dev *dev, struct rte_eth_dev_info *dev_info)
 {
 	struct i40e_pf *pf = I40E_DEV_PRIVATE_TO_PF(dev->data->dev_private);
+	struct i40e_hw *hw = I40E_DEV_PRIVATE_TO_HW(dev->data->dev_private);
 	struct i40e_vsi *vsi = pf->main_vsi;
 
 	dev_info->max_rx_queues = vsi->nb_qps;
@@ -2345,6 +2346,13 @@ i40e_dev_info_get(struct rte_eth_dev *dev, struct rte_eth_dev_info *dev_info)
 		dev_info->max_rx_queues += dev_info->vmdq_queue_num;
 		dev_info->max_tx_queues += dev_info->vmdq_queue_num;
 	}
+
+	if (i40e_is_40G_device(hw->device_id))
+		/* For XL710 */
+		dev_info->speed_capa = ETH_LINK_SPEED_1G | ETH_LINK_SPEED_10G;
+	else
+		/* For X710 */
+		dev_info->speed_capa = ETH_LINK_SPEED_10G | ETH_LINK_SPEED_40G;
 }
 
 static int
diff --git a/drivers/net/ixgbe/ixgbe_ethdev.c b/drivers/net/ixgbe/ixgbe_ethdev.c
index 9246fdb..3d2e801 100644
--- a/drivers/net/ixgbe/ixgbe_ethdev.c
+++ b/drivers/net/ixgbe/ixgbe_ethdev.c
@@ -2929,6 +2929,14 @@ ixgbe_dev_info_get(struct rte_eth_dev *dev, struct rte_eth_dev_info *dev_info)
 	dev_info->hash_key_size = IXGBE_HKEY_MAX_INDEX * sizeof(uint32_t);
 	dev_info->reta_size = ixgbe_reta_size_get(hw->mac.type);
 	dev_info->flow_type_rss_offloads = IXGBE_RSS_OFFLOAD_ALL;
+
+	dev_info->speed_capa = ETH_LINK_SPEED_1G | ETH_LINK_SPEED_10G;
+	if (hw->mac.type == ixgbe_mac_X540 ||
+	    hw->mac.type == ixgbe_mac_X540_vf ||
+	    hw->mac.type == ixgbe_mac_X550 ||
+	    hw->mac.type == ixgbe_mac_X550_vf) {
+		dev_info->speed_capa |= ETH_LINK_SPEED_100M;
+	}
 }
 
 static void
diff --git a/drivers/net/mlx4/mlx4.c b/drivers/net/mlx4/mlx4.c
index cc4e9aa..3a4a989 100644
--- a/drivers/net/mlx4/mlx4.c
+++ b/drivers/net/mlx4/mlx4.c
@@ -4301,6 +4301,8 @@ mlx4_dev_infos_get(struct rte_eth_dev *dev, struct rte_eth_dev_info *info)
 		 0);
 	if (priv_get_ifname(priv, &ifname) == 0)
 		info->if_index = if_nametoindex(ifname);
+	info->speed_capa = ETH_LINK_SPEED_10G | ETH_LINK_SPEED_40G |
+			ETH_LINK_SPEED_56G;
 	priv_unlock(priv);
 }
 
diff --git a/drivers/net/mlx5/mlx5_ethdev.c b/drivers/net/mlx5/mlx5_ethdev.c
index 6704382..3487538 100644
--- a/drivers/net/mlx5/mlx5_ethdev.c
+++ b/drivers/net/mlx5/mlx5_ethdev.c
@@ -522,6 +522,9 @@ mlx5_dev_infos_get(struct rte_eth_dev *dev, struct rte_eth_dev_info *info)
 	 * size if it is not fixed.
 	 * The API should be updated to solve this problem. */
 	info->reta_size = priv->ind_table_max_size;
+	info->speed_capa = ETH_LINK_SPEED_1G | ETH_LINK_SPEED_10G |
+			ETH_LINK_SPEED_25G | ETH_LINK_SPEED_40G |
+			ETH_LINK_SPEED_50G;
 	priv_unlock(priv);
 }
 
diff --git a/drivers/net/nfp/nfp_net.c b/drivers/net/nfp/nfp_net.c
index 9e314bd..c9e1dc5 100644
--- a/drivers/net/nfp/nfp_net.c
+++ b/drivers/net/nfp/nfp_net.c
@@ -1061,6 +1061,8 @@ nfp_net_infos_get(struct rte_eth_dev *dev, struct rte_eth_dev_info *dev_info)
 
 	dev_info->reta_size = NFP_NET_CFG_RSS_ITBL_SZ;
 	dev_info->hash_key_size = NFP_NET_CFG_RSS_KEY_SZ;
+
+	dev_info->speed_capa = ETH_LINK_SPEED_50G;
 }
 
 static uint32_t
diff --git a/lib/librte_ether/rte_ethdev.h b/lib/librte_ether/rte_ethdev.h
index d7c8a66..7aa39f9 100644
--- a/lib/librte_ether/rte_ethdev.h
+++ b/lib/librte_ether/rte_ethdev.h
@@ -242,6 +242,23 @@ struct rte_eth_stats {
 };
 
 /**
+ * Device supported speeds bitmap flags
+ */
+#define ETH_LINK_SPEED_10M_HD   (1 <<  1)  /**<  10 Mbps half-duplex */
+#define ETH_LINK_SPEED_10M      (1 <<  2)  /**<  10 Mbps full-duplex */
+#define ETH_LINK_SPEED_100M_HD  (1 <<  3)  /**< 100 Mbps half-duplex */
+#define ETH_LINK_SPEED_100M     (1 <<  4)  /**< 100 Mbps full-duplex */
+#define ETH_LINK_SPEED_1G       (1 <<  5)  /**<   1 Gbps */
+#define ETH_LINK_SPEED_2_5G     (1 <<  6)  /**< 2.5 Gbps */
+#define ETH_LINK_SPEED_5G       (1 <<  7)  /**<   5 Gbps */
+#define ETH_LINK_SPEED_10G      (1 <<  8)  /**<  10 Gbps */
+#define ETH_LINK_SPEED_20G      (1 <<  9)  /**<  20 Gbps */
+#define ETH_LINK_SPEED_25G      (1 << 10)  /**<  25 Gbps */
+#define ETH_LINK_SPEED_40G      (1 << 11)  /**<  40 Gbps */
+#define ETH_LINK_SPEED_50G      (1 << 12)  /**<  50 Gbps */
+#define ETH_LINK_SPEED_56G      (1 << 13)  /**<  56 Gbps */
+
+/**
  * Ethernet numeric link speeds in Mbps
  */
 #define ETH_LINK_SPEED_AUTONEG     0 /**< Auto-negotiate link speed. */
@@ -850,6 +867,9 @@ struct rte_eth_conf {
 #define DEV_TX_OFFLOAD_OUTER_IPV4_CKSUM 0x00000080 /**< Used for tunneling packet. */
 #define DEV_TX_OFFLOAD_QINQ_INSERT 0x00000100
 
+/**
+ * Ethernet device information
+ */
 struct rte_eth_dev_info {
 	struct rte_pci_device *pci_dev; /**< Device PCI information. */
 	const char *driver_name; /**< Device Driver name. */
@@ -878,6 +898,7 @@ struct rte_eth_dev_info {
 	uint16_t vmdq_pool_base;  /**< First ID of VMDQ pools. */
 	struct rte_eth_desc_lim rx_desc_lim;  /**< RX descriptors limits */
 	struct rte_eth_desc_lim tx_desc_lim;  /**< TX descriptors limits */
+	uint32_t speed_capa;  /**< Supported speeds bitmap (ETH_LINK_SPEED_). */
 };
 
 /**
-- 
2.7.0

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

* [PATCH v11 6/8] ethdev: redesign link speed config
  2016-03-17 18:08           ` [PATCH v11 0/8] ethdev: 100G and link speed API refactoring Thomas Monjalon
                               ` (4 preceding siblings ...)
  2016-03-17 18:09             ` [PATCH v11 5/8] ethdev: add speed capabilities Thomas Monjalon
@ 2016-03-17 18:09             ` Thomas Monjalon
  2016-03-17 18:09             ` [PATCH v11 7/8] ethdev: convert speed number to bitmap flag Thomas Monjalon
                               ` (4 subsequent siblings)
  10 siblings, 0 replies; 167+ messages in thread
From: Thomas Monjalon @ 2016-03-17 18:09 UTC (permalink / raw)
  To: marcdevel, bruce.richardson, declan.doherty, konstantin.ananyev,
	wenzhuo.lu, helin.zhang, jing.d.chen, harish.patil,
	rahul.lakkireddy, johndale, vido, adrien.mazarguil,
	alejandro.lucero
  Cc: dev

From: Marc Sune <marcdevel@gmail.com>

This patch redesigns the API to set the link speed/s configuration
of an ethernet port. Specifically:

- it allows to define a set of advertised speeds for
  auto-negociation.
- it allows to disable link auto-negociation (single fixed speed).
- default: auto-negociate all supported speeds.

A flag autoneg in struct rte_eth_link indicates if link speed was a
result of auto-negociation or was fixed by configuration.

Signed-off-by: Marc Sune <marcdevel@gmail.com>
Tested-by: Nelio Laranjeiro <nelio.laranjeiro@6wind.com>
Signed-off-by: Thomas Monjalon <thomas.monjalon@6wind.com>
---
 app/test-pmd/cmdline.c                    | 26 ++++----
 doc/guides/rel_notes/release_16_04.rst    |  9 +++
 drivers/net/af_packet/rte_eth_af_packet.c |  1 +
 drivers/net/bnx2x/bnx2x_ethdev.c          |  4 +-
 drivers/net/bonding/rte_eth_bond_8023ad.c |  2 +-
 drivers/net/e1000/em_ethdev.c             | 99 +++++++++++++++----------------
 drivers/net/e1000/igb_ethdev.c            | 94 +++++++++++++++--------------
 drivers/net/i40e/i40e_ethdev.c            | 48 +++++++--------
 drivers/net/i40e/i40e_ethdev_vf.c         |  7 ++-
 drivers/net/ixgbe/ixgbe_ethdev.c          | 46 ++++++--------
 drivers/net/mlx4/mlx4.c                   |  2 +
 drivers/net/mpipe/mpipe_tilegx.c          |  2 +
 drivers/net/null/rte_eth_null.c           |  1 +
 drivers/net/pcap/rte_eth_pcap.c           |  1 +
 drivers/net/ring/rte_eth_ring.c           |  1 +
 drivers/net/szedata2/rte_eth_szedata2.c   |  2 +
 drivers/net/vmxnet3/vmxnet3_ethdev.c      |  1 +
 drivers/net/xenvirt/rte_eth_xenvirt.c     |  1 +
 examples/ip_pipeline/config_parse.c       |  3 +-
 lib/librte_ether/rte_ethdev.h             | 29 +++++----
 20 files changed, 196 insertions(+), 183 deletions(-)

diff --git a/app/test-pmd/cmdline.c b/app/test-pmd/cmdline.c
index 874129a..3bc7bb4 100644
--- a/app/test-pmd/cmdline.c
+++ b/app/test-pmd/cmdline.c
@@ -984,7 +984,7 @@ struct cmd_config_speed_all {
 };
 
 static int
-parse_and_check_speed_duplex(char *speedstr, char *duplexstr, uint16_t *speed)
+parse_and_check_speed_duplex(char *speedstr, char *duplexstr, uint32_t *speed)
 {
 
 	int duplex;
@@ -1001,20 +1001,22 @@ parse_and_check_speed_duplex(char *speedstr, char *duplexstr, uint16_t *speed)
 	}
 
 	if (!strcmp(speedstr, "10")) {
-		*speed = ETH_SPEED_NUM_10M;
+		*speed = (duplex == ETH_LINK_HALF_DUPLEX) ?
+				ETH_LINK_SPEED_10M_HD : ETH_LINK_SPEED_10M;
 	} else if (!strcmp(speedstr, "100")) {
-		*speed = ETH_SPEED_NUM_100M;
+		*speed = (duplex == ETH_LINK_HALF_DUPLEX) ?
+				ETH_LINK_SPEED_100M_HD : ETH_LINK_SPEED_100M;
 	} else {
 		if (duplex != ETH_LINK_FULL_DUPLEX) {
 			printf("Invalid speed/duplex parameters\n");
 			return -1;
 		}
 		if (!strcmp(speedstr, "1000")) {
-			*speed = ETH_SPEED_NUM_1G;
+			*speed = ETH_LINK_SPEED_1G;
 		} else if (!strcmp(speedstr, "10000")) {
-			*speed = ETH_SPEED_NUM_10G;
+			*speed = ETH_LINK_SPEED_10G;
 		} else if (!strcmp(speedstr, "40000")) {
-			*speed = ETH_SPEED_NUM_40G;
+			*speed = ETH_LINK_SPEED_40G;
 		} else if (!strcmp(speedstr, "auto")) {
 			*speed = ETH_LINK_SPEED_AUTONEG;
 		} else {
@@ -1032,8 +1034,7 @@ cmd_config_speed_all_parsed(void *parsed_result,
 			__attribute__((unused)) void *data)
 {
 	struct cmd_config_speed_all *res = parsed_result;
-	uint16_t link_speed = ETH_LINK_SPEED_AUTONEG;
-	uint16_t link_duplex = 0;
+	uint32_t link_speed;
 	portid_t pid;
 
 	if (!all_ports_stopped()) {
@@ -1046,8 +1047,7 @@ cmd_config_speed_all_parsed(void *parsed_result,
 		return;
 
 	FOREACH_PORT(pid, ports) {
-		ports[pid].dev_conf.link_speed = link_speed;
-		ports[pid].dev_conf.link_duplex = link_duplex;
+		ports[pid].dev_conf.link_speeds = link_speed;
 	}
 
 	cmd_reconfig_device_queue(RTE_PORT_ALL, 1, 1);
@@ -1105,8 +1105,7 @@ cmd_config_speed_specific_parsed(void *parsed_result,
 				__attribute__((unused)) void *data)
 {
 	struct cmd_config_speed_specific *res = parsed_result;
-	uint16_t link_speed = ETH_LINK_SPEED_AUTONEG;
-	uint16_t link_duplex = 0;
+	uint32_t link_speed;
 
 	if (!all_ports_stopped()) {
 		printf("Please stop all ports first\n");
@@ -1120,8 +1119,7 @@ cmd_config_speed_specific_parsed(void *parsed_result,
 			&link_speed) < 0)
 		return;
 
-	ports[res->id].dev_conf.link_speed = link_speed;
-	ports[res->id].dev_conf.link_duplex = link_duplex;
+	ports[res->id].dev_conf.link_speeds = link_speed;
 
 	cmd_reconfig_device_queue(RTE_PORT_ALL, 1, 1);
 }
diff --git a/doc/guides/rel_notes/release_16_04.rst b/doc/guides/rel_notes/release_16_04.rst
index 6ecd304..6540941 100644
--- a/doc/guides/rel_notes/release_16_04.rst
+++ b/doc/guides/rel_notes/release_16_04.rst
@@ -52,6 +52,12 @@ This section should contain new features added in this release. Sample format:
   The structure ``rte_eth_dev_info`` has now a ``speed_capa`` bitmap, which
   allows the application to know the supported speeds of each device.
 
+* **Added bitmap of link speeds to advertise.**
+
+  Allow defining a set of advertised speeds for auto-negotiation,
+  explicitly disabling link auto-negotiation (single speed)
+  and full auto-negotiation.
+
 * **Restored vmxnet3 Tx data ring.**
 
   Tx data ring has been shown to improve small pkt forwarding performance
@@ -402,6 +408,9 @@ This section should contain API changes. Sample format:
 * The ethdev structure ``rte_eth_dev_info`` was changed to support device
   speed capabilities.
 
+* The ethdev structures ``rte_eth_link`` and ``rte_eth_conf`` were changed to
+  support the new link API.
+
 * The functions ``rte_eth_dev_udp_tunnel_add`` and ``rte_eth_dev_udp_tunnel_delete``
   have been renamed into ``rte_eth_dev_udp_tunnel_port_add`` and
   ``rte_eth_dev_udp_tunnel_port_delete``.
diff --git a/drivers/net/af_packet/rte_eth_af_packet.c b/drivers/net/af_packet/rte_eth_af_packet.c
index 641f849..f17bd7e 100644
--- a/drivers/net/af_packet/rte_eth_af_packet.c
+++ b/drivers/net/af_packet/rte_eth_af_packet.c
@@ -119,6 +119,7 @@ static struct rte_eth_link pmd_link = {
 	.link_speed = ETH_SPEED_NUM_10G,
 	.link_duplex = ETH_LINK_FULL_DUPLEX,
 	.link_status = ETH_LINK_DOWN,
+	.link_autoneg = ETH_LINK_SPEED_AUTONEG
 };
 
 static uint16_t
diff --git a/drivers/net/bnx2x/bnx2x_ethdev.c b/drivers/net/bnx2x/bnx2x_ethdev.c
index 607d2f4..71c2360 100644
--- a/drivers/net/bnx2x/bnx2x_ethdev.c
+++ b/drivers/net/bnx2x/bnx2x_ethdev.c
@@ -44,9 +44,9 @@ bnx2x_link_update(struct rte_eth_dev *dev)
 		case DUPLEX_HALF:
 			dev->data->dev_link.link_duplex = ETH_LINK_HALF_DUPLEX;
 			break;
-		default:
-			dev->data->dev_link.link_duplex = ETH_LINK_AUTONEG_DUPLEX;
 	}
+	dev->data->dev_link.link_autoneg = (dev->data->dev_conf.link_speeds &
+			ETH_LINK_SPEED_AUTONEG);
 	dev->data->dev_link.link_status = sc->link_vars.link_up;
 }
 
diff --git a/drivers/net/bonding/rte_eth_bond_8023ad.c b/drivers/net/bonding/rte_eth_bond_8023ad.c
index ac8306f..cca7cc3 100644
--- a/drivers/net/bonding/rte_eth_bond_8023ad.c
+++ b/drivers/net/bonding/rte_eth_bond_8023ad.c
@@ -708,7 +708,7 @@ link_speed_key(uint16_t speed) {
 	uint16_t key_speed;
 
 	switch (speed) {
-	case ETH_LINK_SPEED_AUTONEG:
+	case ETH_SPEED_NUM_NONE:
 		key_speed = 0x00;
 		break;
 	case ETH_SPEED_NUM_10M:
diff --git a/drivers/net/e1000/em_ethdev.c b/drivers/net/e1000/em_ethdev.c
index 2a50857..70326e1 100644
--- a/drivers/net/e1000/em_ethdev.c
+++ b/drivers/net/e1000/em_ethdev.c
@@ -538,6 +538,9 @@ eth_em_start(struct rte_eth_dev *dev)
 	struct rte_intr_handle *intr_handle = &dev->pci_dev->intr_handle;
 	int ret, mask;
 	uint32_t intr_vector = 0;
+	uint32_t *speeds;
+	int num_speeds;
+	bool autoneg;
 
 	PMD_INIT_FUNC_TRACE();
 
@@ -612,56 +615,46 @@ eth_em_start(struct rte_eth_dev *dev)
 	E1000_WRITE_REG(hw, E1000_ITR, UINT16_MAX);
 
 	/* Setup link speed and duplex */
-	switch (dev->data->dev_conf.link_speed) {
-	case ETH_LINK_SPEED_AUTONEG:
-		if (dev->data->dev_conf.link_duplex == ETH_LINK_AUTONEG_DUPLEX)
-			hw->phy.autoneg_advertised = E1000_ALL_SPEED_DUPLEX;
-		else if (dev->data->dev_conf.link_duplex ==
-					ETH_LINK_HALF_DUPLEX)
-			hw->phy.autoneg_advertised = E1000_ALL_HALF_DUPLEX;
-		else if (dev->data->dev_conf.link_duplex ==
-					ETH_LINK_FULL_DUPLEX)
-			hw->phy.autoneg_advertised = E1000_ALL_FULL_DUPLEX;
-		else
-			goto error_invalid_config;
-		break;
-	case ETH_SPEED_NUM_10M:
-		if (dev->data->dev_conf.link_duplex == ETH_LINK_AUTONEG_DUPLEX)
-			hw->phy.autoneg_advertised = E1000_ALL_10_SPEED;
-		else if (dev->data->dev_conf.link_duplex ==
-					ETH_LINK_HALF_DUPLEX)
-			hw->phy.autoneg_advertised = ADVERTISE_10_HALF;
-		else if (dev->data->dev_conf.link_duplex ==
-					ETH_LINK_FULL_DUPLEX)
-			hw->phy.autoneg_advertised = ADVERTISE_10_FULL;
-		else
-			goto error_invalid_config;
-		break;
-	case ETH_SPEED_NUM_100M:
-		if (dev->data->dev_conf.link_duplex == ETH_LINK_AUTONEG_DUPLEX)
-			hw->phy.autoneg_advertised = E1000_ALL_100_SPEED;
-		else if (dev->data->dev_conf.link_duplex ==
-					ETH_LINK_HALF_DUPLEX)
-			hw->phy.autoneg_advertised = ADVERTISE_100_HALF;
-		else if (dev->data->dev_conf.link_duplex ==
-					ETH_LINK_FULL_DUPLEX)
-			hw->phy.autoneg_advertised = ADVERTISE_100_FULL;
-		else
+	speeds = &dev->data->dev_conf.link_speeds;
+	if (*speeds == ETH_LINK_SPEED_AUTONEG) {
+		hw->phy.autoneg_advertised = E1000_ALL_SPEED_DUPLEX;
+	} else {
+		num_speeds = 0;
+		autoneg = (*speeds & ETH_LINK_SPEED_AUTONEG);
+
+		/* Reset */
+		hw->phy.autoneg_advertised = 0;
+
+		if (*speeds & ~(ETH_LINK_SPEED_10M_HD | ETH_LINK_SPEED_10M |
+				ETH_LINK_SPEED_100M_HD | ETH_LINK_SPEED_100M |
+				ETH_LINK_SPEED_1G)) {
+			num_speeds = -1;
 			goto error_invalid_config;
-		break;
-	case ETH_SPEED_NUM_1G:
-		if ((dev->data->dev_conf.link_duplex ==
-				ETH_LINK_AUTONEG_DUPLEX) ||
-			(dev->data->dev_conf.link_duplex ==
-					ETH_LINK_FULL_DUPLEX))
-			hw->phy.autoneg_advertised = ADVERTISE_1000_FULL;
-		else
+		}
+		if (*speeds & ETH_LINK_SPEED_10M_HD) {
+			hw->phy.autoneg_advertised |= ADVERTISE_10_HALF;
+			num_speeds++;
+		}
+		if (*speeds & ETH_LINK_SPEED_10M) {
+			hw->phy.autoneg_advertised |= ADVERTISE_10_FULL;
+			num_speeds++;
+		}
+		if (*speeds & ETH_LINK_SPEED_100M_HD) {
+			hw->phy.autoneg_advertised |= ADVERTISE_100_HALF;
+			num_speeds++;
+		}
+		if (*speeds & ETH_LINK_SPEED_100M) {
+			hw->phy.autoneg_advertised |= ADVERTISE_100_FULL;
+			num_speeds++;
+		}
+		if (*speeds & ETH_LINK_SPEED_1G) {
+			hw->phy.autoneg_advertised |= ADVERTISE_1000_FULL;
+			num_speeds++;
+		}
+		if (num_speeds == 0 || (!autoneg && (num_speeds > 2)))
 			goto error_invalid_config;
-		break;
-	case ETH_SPEED_NUM_10G:
-	default:
-		goto error_invalid_config;
 	}
+
 	e1000_setup_link(hw);
 
 	if (rte_intr_allow_others(intr_handle)) {
@@ -694,9 +687,8 @@ eth_em_start(struct rte_eth_dev *dev)
 	return 0;
 
 error_invalid_config:
-	PMD_INIT_LOG(ERR, "Invalid link_speed/link_duplex (%u/%u) for port %u",
-		     dev->data->dev_conf.link_speed,
-		     dev->data->dev_conf.link_duplex, dev->data->port_id);
+	PMD_INIT_LOG(ERR, "Invalid advertised speeds (%u) for port %u",
+		     dev->data->dev_conf.link_speeds, dev->data->port_id);
 	em_dev_clear_queues(dev);
 	return -EINVAL;
 }
@@ -1107,8 +1099,11 @@ eth_em_link_update(struct rte_eth_dev *dev, int wait_to_complete)
 
 	/* Now we check if a transition has happened */
 	if (link_check && (link.link_status == ETH_LINK_DOWN)) {
-		hw->mac.ops.get_link_up_info(hw, &link.link_speed,
-			&link.link_duplex);
+		uint16_t duplex, speed;
+		hw->mac.ops.get_link_up_info(hw, &speed, &duplex);
+		link.link_duplex = duplex ? ETH_LINK_FULL_DUPLEX :
+				ETH_LINK_HALF_DUPLEX;
+		link.link_speed = speed;
 		link.link_status = ETH_LINK_UP;
 	} else if (!link_check && (link.link_status == ETH_LINK_UP)) {
 		link.link_speed = 0;
diff --git a/drivers/net/e1000/igb_ethdev.c b/drivers/net/e1000/igb_ethdev.c
index b7e706a..2208d48 100644
--- a/drivers/net/e1000/igb_ethdev.c
+++ b/drivers/net/e1000/igb_ethdev.c
@@ -1130,6 +1130,9 @@ eth_igb_start(struct rte_eth_dev *dev)
 	int ret, mask;
 	uint32_t intr_vector = 0;
 	uint32_t ctrl_ext;
+	uint32_t *speeds;
+	int num_speeds;
+	bool autoneg;
 
 	PMD_INIT_FUNC_TRACE();
 
@@ -1230,48 +1233,46 @@ eth_igb_start(struct rte_eth_dev *dev)
 	}
 
 	/* Setup link speed and duplex */
-	switch (dev->data->dev_conf.link_speed) {
-	case ETH_LINK_SPEED_AUTONEG:
-		if (dev->data->dev_conf.link_duplex == ETH_LINK_AUTONEG_DUPLEX)
-			hw->phy.autoneg_advertised = E1000_ALL_SPEED_DUPLEX;
-		else if (dev->data->dev_conf.link_duplex == ETH_LINK_HALF_DUPLEX)
-			hw->phy.autoneg_advertised = E1000_ALL_HALF_DUPLEX;
-		else if (dev->data->dev_conf.link_duplex == ETH_LINK_FULL_DUPLEX)
-			hw->phy.autoneg_advertised = E1000_ALL_FULL_DUPLEX;
-		else
-			goto error_invalid_config;
-		break;
-	case ETH_SPEED_NUM_10M:
-		if (dev->data->dev_conf.link_duplex == ETH_LINK_AUTONEG_DUPLEX)
-			hw->phy.autoneg_advertised = E1000_ALL_10_SPEED;
-		else if (dev->data->dev_conf.link_duplex == ETH_LINK_HALF_DUPLEX)
-			hw->phy.autoneg_advertised = ADVERTISE_10_HALF;
-		else if (dev->data->dev_conf.link_duplex == ETH_LINK_FULL_DUPLEX)
-			hw->phy.autoneg_advertised = ADVERTISE_10_FULL;
-		else
-			goto error_invalid_config;
-		break;
-	case ETH_SPEED_NUM_100M:
-		if (dev->data->dev_conf.link_duplex == ETH_LINK_AUTONEG_DUPLEX)
-			hw->phy.autoneg_advertised = E1000_ALL_100_SPEED;
-		else if (dev->data->dev_conf.link_duplex == ETH_LINK_HALF_DUPLEX)
-			hw->phy.autoneg_advertised = ADVERTISE_100_HALF;
-		else if (dev->data->dev_conf.link_duplex == ETH_LINK_FULL_DUPLEX)
-			hw->phy.autoneg_advertised = ADVERTISE_100_FULL;
-		else
+	speeds = &dev->data->dev_conf.link_speeds;
+	if (*speeds == ETH_LINK_SPEED_AUTONEG) {
+		hw->phy.autoneg_advertised = E1000_ALL_SPEED_DUPLEX;
+	} else {
+		num_speeds = 0;
+		autoneg = (*speeds & ETH_LINK_SPEED_AUTONEG);
+
+		/* Reset */
+		hw->phy.autoneg_advertised = 0;
+
+		if (*speeds & ~(ETH_LINK_SPEED_10M_HD | ETH_LINK_SPEED_10M |
+				ETH_LINK_SPEED_100M_HD | ETH_LINK_SPEED_100M |
+				ETH_LINK_SPEED_1G)) {
+			num_speeds = -1;
 			goto error_invalid_config;
-		break;
-	case ETH_SPEED_NUM_1G:
-		if ((dev->data->dev_conf.link_duplex == ETH_LINK_AUTONEG_DUPLEX) ||
-				(dev->data->dev_conf.link_duplex == ETH_LINK_FULL_DUPLEX))
-			hw->phy.autoneg_advertised = ADVERTISE_1000_FULL;
-		else
+		}
+		if (*speeds & ETH_LINK_SPEED_10M_HD) {
+			hw->phy.autoneg_advertised |= ADVERTISE_10_HALF;
+			num_speeds++;
+		}
+		if (*speeds & ETH_LINK_SPEED_10M) {
+			hw->phy.autoneg_advertised |= ADVERTISE_10_FULL;
+			num_speeds++;
+		}
+		if (*speeds & ETH_LINK_SPEED_100M_HD) {
+			hw->phy.autoneg_advertised |= ADVERTISE_100_HALF;
+			num_speeds++;
+		}
+		if (*speeds & ETH_LINK_SPEED_100M) {
+			hw->phy.autoneg_advertised |= ADVERTISE_100_FULL;
+			num_speeds++;
+		}
+		if (*speeds & ETH_LINK_SPEED_1G) {
+			hw->phy.autoneg_advertised |= ADVERTISE_1000_FULL;
+			num_speeds++;
+		}
+		if (num_speeds == 0 || (!autoneg && (num_speeds > 2)))
 			goto error_invalid_config;
-		break;
-	case ETH_SPEED_NUM_10G:
-	default:
-		goto error_invalid_config;
 	}
+
 	e1000_setup_link(hw);
 
 	if (rte_intr_allow_others(intr_handle)) {
@@ -1303,9 +1304,8 @@ eth_igb_start(struct rte_eth_dev *dev)
 	return 0;
 
 error_invalid_config:
-	PMD_INIT_LOG(ERR, "Invalid link_speed/link_duplex (%u/%u) for port %u",
-		     dev->data->dev_conf.link_speed,
-		     dev->data->dev_conf.link_duplex, dev->data->port_id);
+	PMD_INIT_LOG(ERR, "Invalid advertised speeds (%u) for port %u",
+		     dev->data->dev_conf.link_speeds, dev->data->port_id);
 	igb_dev_clear_queues(dev);
 	return -EINVAL;
 }
@@ -2032,13 +2032,19 @@ eth_igb_link_update(struct rte_eth_dev *dev, int wait_to_complete)
 
 	/* Now we check if a transition has happened */
 	if (link_check) {
-		hw->mac.ops.get_link_up_info(hw, &link.link_speed,
-					  &link.link_duplex);
+		uint16_t duplex, speed;
+		hw->mac.ops.get_link_up_info(hw, &speed, &duplex);
+		link.link_duplex = duplex ? ETH_LINK_FULL_DUPLEX :
+				ETH_LINK_HALF_DUPLEX;
+		link.link_speed = speed;
 		link.link_status = ETH_LINK_UP;
+		link.link_autoneg = (dev->data->dev_conf.link_speeds &
+				ETH_LINK_SPEED_AUTONEG);
 	} else if (!link_check) {
 		link.link_speed = 0;
 		link.link_duplex = ETH_LINK_HALF_DUPLEX;
 		link.link_status = ETH_LINK_DOWN;
+		link.link_autoneg = ETH_LINK_SPEED_FIXED;
 	}
 	rte_igb_dev_atomic_write_link_status(dev, &link);
 
diff --git a/drivers/net/i40e/i40e_ethdev.c b/drivers/net/i40e/i40e_ethdev.c
index dee7ef7..d71d840 100644
--- a/drivers/net/i40e/i40e_ethdev.c
+++ b/drivers/net/i40e/i40e_ethdev.c
@@ -1367,27 +1367,20 @@ i40e_vsi_disable_queues_intr(struct i40e_vsi *vsi)
 }
 
 static inline uint8_t
-i40e_parse_link_speed(uint16_t eth_link_speed)
+i40e_parse_link_speeds(uint16_t link_speeds)
 {
 	uint8_t link_speed = I40E_LINK_SPEED_UNKNOWN;
 
-	switch (eth_link_speed) {
-	case ETH_SPEED_NUM_40G:
-		link_speed = I40E_LINK_SPEED_40GB;
-		break;
-	case ETH_SPEED_NUM_20G:
-		link_speed = I40E_LINK_SPEED_20GB;
-		break;
-	case ETH_SPEED_NUM_10G:
-		link_speed = I40E_LINK_SPEED_10GB;
-		break;
-	case ETH_SPEED_NUM_1G:
-		link_speed = I40E_LINK_SPEED_1GB;
-		break;
-	case ETH_SPEED_NUM_100M:
-		link_speed = I40E_LINK_SPEED_100MB;
-		break;
-	}
+	if (link_speeds & ETH_LINK_SPEED_40G)
+		link_speed |= I40E_LINK_SPEED_40GB;
+	if (link_speeds & ETH_LINK_SPEED_20G)
+		link_speed |= I40E_LINK_SPEED_20GB;
+	if (link_speeds & ETH_LINK_SPEED_10G)
+		link_speed |= I40E_LINK_SPEED_10GB;
+	if (link_speeds & ETH_LINK_SPEED_1G)
+		link_speed |= I40E_LINK_SPEED_1GB;
+	if (link_speeds & ETH_LINK_SPEED_100M)
+		link_speed |= I40E_LINK_SPEED_100MB;
 
 	return link_speed;
 }
@@ -1413,9 +1406,9 @@ i40e_apply_link_speed(struct rte_eth_dev *dev)
 	struct i40e_hw *hw = I40E_DEV_PRIVATE_TO_HW(dev->data->dev_private);
 	struct rte_eth_conf *conf = &dev->data->dev_conf;
 
-	speed = i40e_parse_link_speed(conf->link_speed);
+	speed = i40e_parse_link_speeds(conf->link_speeds);
 	abilities |= I40E_AQ_PHY_ENABLE_ATOMIC_LINK;
-	if (conf->link_speed == ETH_LINK_SPEED_AUTONEG)
+	if (conf->link_speeds & ETH_LINK_SPEED_AUTONEG)
 		abilities |= I40E_AQ_PHY_AN_ENABLED;
 	else
 		abilities |= I40E_AQ_PHY_LINK_ENABLED;
@@ -1435,10 +1428,8 @@ i40e_dev_start(struct rte_eth_dev *dev)
 
 	hw->adapter_stopped = 0;
 
-	if ((dev->data->dev_conf.link_duplex != ETH_LINK_AUTONEG_DUPLEX) &&
-		(dev->data->dev_conf.link_duplex != ETH_LINK_FULL_DUPLEX)) {
-		PMD_INIT_LOG(ERR, "Invalid link_duplex (%hu) for port %hhu",
-			     dev->data->dev_conf.link_duplex,
+	if (!(dev->data->dev_conf.link_speeds & ETH_LINK_SPEED_AUTONEG)) {
+		PMD_INIT_LOG(ERR, "Invalid link_speeds for port %hhu; autonegotiation disabled",
 			     dev->data->port_id);
 		return -EINVAL;
 	}
@@ -1511,6 +1502,12 @@ i40e_dev_start(struct rte_eth_dev *dev)
 	}
 
 	/* Apply link configure */
+	if (dev->data->dev_conf.link_speeds & ~(ETH_LINK_SPEED_100M |
+				ETH_LINK_SPEED_1G | ETH_LINK_SPEED_10G |
+				ETH_LINK_SPEED_20G | ETH_LINK_SPEED_40G)) {
+		PMD_DRV_LOG(ERR, "Invalid link setting");
+		goto err_up;
+	}
 	ret = i40e_apply_link_speed(dev);
 	if (I40E_SUCCESS != ret) {
 		PMD_DRV_LOG(ERR, "Fail to apply link setting");
@@ -1795,6 +1792,9 @@ i40e_dev_link_update(struct rte_eth_dev *dev,
 		break;
 	}
 
+	link.link_autoneg = (dev->data->dev_conf.link_speeds &
+			ETH_LINK_SPEED_AUTONEG);
+
 out:
 	rte_i40e_dev_atomic_write_link_status(dev, &link);
 	if (link.link_status == old.link_status)
diff --git a/drivers/net/i40e/i40e_ethdev_vf.c b/drivers/net/i40e/i40e_ethdev_vf.c
index f2b37a2..cb8b6cf 100644
--- a/drivers/net/i40e/i40e_ethdev_vf.c
+++ b/drivers/net/i40e/i40e_ethdev_vf.c
@@ -1953,12 +1953,13 @@ i40evf_dev_link_update(struct rte_eth_dev *dev,
 	 * DPDK pf host provide interfacet to acquire link status
 	 * while Linux driver does not
 	 */
-	if (vf->version_major == I40E_DPDK_VERSION_MAJOR)
+	if (vf->version_major == I40E_DPDK_VERSION_MAJOR) {
 		i40evf_get_link_status(dev, &new_link);
-	else {
+	} else {
 		/* Always assume it's up, for Linux driver PF host */
-		new_link.link_duplex = ETH_LINK_AUTONEG_DUPLEX;
 		new_link.link_speed  = ETH_SPEED_NUM_10G;
+		new_link.link_duplex = ETH_LINK_FULL_DUPLEX;
+		new_link.link_autoneg = ETH_LINK_SPEED_AUTONEG;
 		new_link.link_status = ETH_LINK_UP;
 	}
 	i40evf_dev_atomic_write_link_status(dev, &new_link);
diff --git a/drivers/net/ixgbe/ixgbe_ethdev.c b/drivers/net/ixgbe/ixgbe_ethdev.c
index 3d2e801..861b9b9 100644
--- a/drivers/net/ixgbe/ixgbe_ethdev.c
+++ b/drivers/net/ixgbe/ixgbe_ethdev.c
@@ -2074,14 +2074,13 @@ ixgbe_dev_start(struct rte_eth_dev *dev)
 	int mask = 0;
 	int status;
 	uint16_t vf, idx;
+	uint32_t *link_speeds;
 
 	PMD_INIT_FUNC_TRACE();
 
 	/* IXGBE devices don't support half duplex */
-	if ((dev->data->dev_conf.link_duplex != ETH_LINK_AUTONEG_DUPLEX) &&
-			(dev->data->dev_conf.link_duplex != ETH_LINK_FULL_DUPLEX)) {
-		PMD_INIT_LOG(ERR, "Invalid link_duplex (%hu) for port %hhu",
-			     dev->data->dev_conf.link_duplex,
+	if (!(dev->data->dev_conf.link_speeds & ETH_LINK_SPEED_AUTONEG)) {
+		PMD_INIT_LOG(ERR, "Invalid link_speeds for port %hhu; autonegotiation disabled",
 			     dev->data->port_id);
 		return -EINVAL;
 	}
@@ -2173,32 +2172,21 @@ ixgbe_dev_start(struct rte_eth_dev *dev)
 	if (err)
 		goto error;
 
-	switch(dev->data->dev_conf.link_speed) {
-	case ETH_LINK_SPEED_AUTONEG:
-		speed = (hw->mac.type != ixgbe_mac_82598EB) ?
-				IXGBE_LINK_SPEED_82599_AUTONEG :
-				IXGBE_LINK_SPEED_82598_AUTONEG;
-		break;
-	case ETH_SPEED_NUM_100M:
-		/*
-		 * Invalid for 82598 but error will be detected by
-		 * ixgbe_setup_link()
-		 */
-		speed = IXGBE_LINK_SPEED_100_FULL;
-		break;
-	case ETH_SPEED_NUM_1G:
-		speed = IXGBE_LINK_SPEED_1GB_FULL;
-		break;
-	case ETH_SPEED_NUM_10G:
-		speed = IXGBE_LINK_SPEED_10GB_FULL;
-		break;
-	default:
-		PMD_INIT_LOG(ERR, "Invalid link_speed (%hu) for port %hhu",
-			     dev->data->dev_conf.link_speed,
-			     dev->data->port_id);
+	link_speeds = &dev->data->dev_conf.link_speeds;
+	if (*link_speeds & ~(ETH_LINK_SPEED_100M | ETH_LINK_SPEED_1G |
+			ETH_LINK_SPEED_10G)) {
+		PMD_INIT_LOG(ERR, "Invalid link setting");
 		goto error;
 	}
 
+	speed = 0x0;
+	if (*link_speeds & ETH_LINK_SPEED_10G)
+		speed |= IXGBE_LINK_SPEED_10GB_FULL;
+	if (*link_speeds & ETH_LINK_SPEED_1G)
+		speed |= IXGBE_LINK_SPEED_1GB_FULL;
+	if (*link_speeds & ETH_LINK_SPEED_100M)
+		speed |= IXGBE_LINK_SPEED_100_FULL;
+
 	err = ixgbe_setup_link(hw, speed, link_up);
 	if (err)
 		goto error;
@@ -3019,7 +3007,7 @@ ixgbe_dev_link_update(struct rte_eth_dev *dev, int wait_to_complete)
 
 	if (diag != 0) {
 		link.link_speed = ETH_SPEED_NUM_100M;
-		link.link_duplex = ETH_LINK_HALF_DUPLEX;
+		link.link_duplex = ETH_LINK_FULL_DUPLEX;
 		rte_ixgbe_dev_atomic_write_link_status(dev, &link);
 		if (link.link_status == old.link_status)
 			return -1;
@@ -3038,7 +3026,7 @@ ixgbe_dev_link_update(struct rte_eth_dev *dev, int wait_to_complete)
 	switch (link_speed) {
 	default:
 	case IXGBE_LINK_SPEED_UNKNOWN:
-		link.link_duplex = ETH_LINK_HALF_DUPLEX;
+		link.link_duplex = ETH_LINK_FULL_DUPLEX;
 		link.link_speed = ETH_SPEED_NUM_100M;
 		break;
 
diff --git a/drivers/net/mlx4/mlx4.c b/drivers/net/mlx4/mlx4.c
index 3a4a989..10e29e2 100644
--- a/drivers/net/mlx4/mlx4.c
+++ b/drivers/net/mlx4/mlx4.c
@@ -4687,6 +4687,8 @@ mlx4_link_update_unlocked(struct rte_eth_dev *dev, int wait_to_complete)
 		dev_link.link_speed = link_speed;
 	dev_link.link_duplex = ((edata.duplex == DUPLEX_HALF) ?
 				ETH_LINK_HALF_DUPLEX : ETH_LINK_FULL_DUPLEX);
+	dev_link.link_autoneg = (dev->data->dev_conf.link_speeds &
+			ETH_LINK_SPEED_AUTONEG);
 	if (memcmp(&dev_link, &dev->data->dev_link, sizeof(dev_link))) {
 		/* Link status changed. */
 		dev->data->dev_link = dev_link;
diff --git a/drivers/net/mpipe/mpipe_tilegx.c b/drivers/net/mpipe/mpipe_tilegx.c
index 960d468..d5ab7dc 100644
--- a/drivers/net/mpipe/mpipe_tilegx.c
+++ b/drivers/net/mpipe/mpipe_tilegx.c
@@ -394,6 +394,8 @@ mpipe_link_update(struct rte_eth_dev *dev, int wait_to_complete)
 
 		speed = state & GXIO_MPIPE_LINK_SPEED_MASK;
 
+		new.link_autoneg = (dev->data->dev_conf.link_speeds &
+				ETH_LINK_SPEED_AUTONEG);
 		if (speed == GXIO_MPIPE_LINK_1G) {
 			new.link_speed = ETH_SPEED_NUM_1G;
 			new.link_duplex = ETH_LINK_FULL_DUPLEX;
diff --git a/drivers/net/null/rte_eth_null.c b/drivers/net/null/rte_eth_null.c
index 5640585..5e8e203 100644
--- a/drivers/net/null/rte_eth_null.c
+++ b/drivers/net/null/rte_eth_null.c
@@ -92,6 +92,7 @@ static struct rte_eth_link pmd_link = {
 	.link_speed = ETH_SPEED_NUM_10G,
 	.link_duplex = ETH_LINK_FULL_DUPLEX,
 	.link_status = ETH_LINK_DOWN,
+	.link_autoneg = ETH_LINK_SPEED_AUTONEG,
 };
 
 static uint16_t
diff --git a/drivers/net/pcap/rte_eth_pcap.c b/drivers/net/pcap/rte_eth_pcap.c
index c657951..c98e234 100644
--- a/drivers/net/pcap/rte_eth_pcap.c
+++ b/drivers/net/pcap/rte_eth_pcap.c
@@ -126,6 +126,7 @@ static struct rte_eth_link pmd_link = {
 		.link_speed = ETH_SPEED_NUM_10G,
 		.link_duplex = ETH_LINK_FULL_DUPLEX,
 		.link_status = ETH_LINK_DOWN,
+		.link_autoneg = ETH_LINK_SPEED_FIXED,
 };
 
 static int
diff --git a/drivers/net/ring/rte_eth_ring.c b/drivers/net/ring/rte_eth_ring.c
index 58685e9..b1783c3 100644
--- a/drivers/net/ring/rte_eth_ring.c
+++ b/drivers/net/ring/rte_eth_ring.c
@@ -80,6 +80,7 @@ static struct rte_eth_link pmd_link = {
 		.link_speed = ETH_SPEED_NUM_10G,
 		.link_duplex = ETH_LINK_FULL_DUPLEX,
 		.link_status = ETH_LINK_DOWN,
+		.link_autoneg = ETH_LINK_SPEED_AUTONEG
 };
 
 static uint16_t
diff --git a/drivers/net/szedata2/rte_eth_szedata2.c b/drivers/net/szedata2/rte_eth_szedata2.c
index 854cb5c..0708e4a 100644
--- a/drivers/net/szedata2/rte_eth_szedata2.c
+++ b/drivers/net/szedata2/rte_eth_szedata2.c
@@ -1174,6 +1174,8 @@ eth_link_update(struct rte_eth_dev *dev,
 	link.link_status = (cgmii_ibuf_is_enabled(ibuf) &&
 			cgmii_ibuf_is_link_up(ibuf)) ? ETH_LINK_UP : ETH_LINK_DOWN;
 
+	link.link_autoneg = ETH_LINK_SPEED_FIXED;
+
 	rte_atomic64_cmpset((uint64_t *)dev_link, *(uint64_t *)dev_link,
 			*(uint64_t *)link_ptr);
 
diff --git a/drivers/net/vmxnet3/vmxnet3_ethdev.c b/drivers/net/vmxnet3/vmxnet3_ethdev.c
index ad8029b..076de7a 100644
--- a/drivers/net/vmxnet3/vmxnet3_ethdev.c
+++ b/drivers/net/vmxnet3/vmxnet3_ethdev.c
@@ -763,6 +763,7 @@ vmxnet3_dev_link_update(struct rte_eth_dev *dev, __attribute__((unused)) int wai
 		link.link_status = ETH_LINK_UP;
 		link.link_duplex = ETH_LINK_FULL_DUPLEX;
 		link.link_speed = ETH_SPEED_NUM_10G;
+		link.link_autoneg = ETH_LINK_SPEED_FIXED;
 	}
 
 	vmxnet3_dev_atomic_write_link_status(dev, &link);
diff --git a/drivers/net/xenvirt/rte_eth_xenvirt.c b/drivers/net/xenvirt/rte_eth_xenvirt.c
index 77d3ba1..b9638d9 100644
--- a/drivers/net/xenvirt/rte_eth_xenvirt.c
+++ b/drivers/net/xenvirt/rte_eth_xenvirt.c
@@ -73,6 +73,7 @@ static struct rte_eth_link pmd_link = {
 		.link_speed = ETH_SPEED_NUM_10G,
 		.link_duplex = ETH_LINK_FULL_DUPLEX,
 		.link_status = ETH_LINK_DOWN,
+		.link_autoneg = ETH_LINK_SPEED_FIXED
 };
 
 static void
diff --git a/examples/ip_pipeline/config_parse.c b/examples/ip_pipeline/config_parse.c
index e39c23e..28112f7 100644
--- a/examples/ip_pipeline/config_parse.c
+++ b/examples/ip_pipeline/config_parse.c
@@ -87,8 +87,7 @@ static const struct app_link_params link_params_default = {
 	.pci_bdf = {0},
 
 	.conf = {
-		.link_speed = 0,
-		.link_duplex = 0,
+		.link_speeds = 0,
 		.rxmode = {
 			.mq_mode = ETH_MQ_RX_NONE,
 
diff --git a/lib/librte_ether/rte_ethdev.h b/lib/librte_ether/rte_ethdev.h
index 7aa39f9..470e434 100644
--- a/lib/librte_ether/rte_ethdev.h
+++ b/lib/librte_ether/rte_ethdev.h
@@ -244,6 +244,8 @@ struct rte_eth_stats {
 /**
  * Device supported speeds bitmap flags
  */
+#define ETH_LINK_SPEED_FIXED    (0 <<  0)  /**< Disable autoneg (fixed speed) */
+#define ETH_LINK_SPEED_AUTONEG  (1 <<  0)  /**< Autonegotiate (all speeds) */
 #define ETH_LINK_SPEED_10M_HD   (1 <<  1)  /**<  10 Mbps half-duplex */
 #define ETH_LINK_SPEED_10M      (1 <<  2)  /**<  10 Mbps full-duplex */
 #define ETH_LINK_SPEED_100M_HD  (1 <<  3)  /**< 100 Mbps half-duplex */
@@ -261,7 +263,7 @@ struct rte_eth_stats {
 /**
  * Ethernet numeric link speeds in Mbps
  */
-#define ETH_LINK_SPEED_AUTONEG     0 /**< Auto-negotiate link speed. */
+#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 */
@@ -278,15 +280,15 @@ struct rte_eth_stats {
  * A structure used to retrieve link-level information of an Ethernet port.
  */
 struct rte_eth_link {
-	uint16_t link_speed;      /**< ETH_SPEED_NUM_ */
-	uint16_t link_duplex;     /**< ETH_LINK_[HALF/FULL]_DUPLEX */
-	uint8_t  link_status : 1; /**< ETH_LINK_[DOWN/UP] */
-}__attribute__((aligned(8)));     /**< aligned for atomic64 read/write */
+	uint16_t link_speed;        /**< ETH_SPEED_NUM_ */
+	uint16_t link_duplex  : 1;  /**< ETH_LINK_[HALF/FULL]_DUPLEX */
+	uint16_t link_autoneg : 1;  /**< ETH_LINK_SPEED_[AUTONEG/FIXED] */
+	uint16_t link_status  : 1;  /**< ETH_LINK_[DOWN/UP] */
+} __attribute__((aligned(8)));      /**< aligned for atomic64 read/write */
 
 /* Utility constants */
-#define ETH_LINK_AUTONEG_DUPLEX 0       /**< Auto-negotiate duplex. */
-#define ETH_LINK_HALF_DUPLEX    1       /**< Half-duplex connection. */
-#define ETH_LINK_FULL_DUPLEX    2       /**< Full-duplex connection. */
+#define ETH_LINK_HALF_DUPLEX    0 /**< Half-duplex connection. */
+#define ETH_LINK_FULL_DUPLEX    1 /**< Full-duplex connection. */
 #define ETH_LINK_DOWN           0 /**< Link is down. */
 #define ETH_LINK_UP             1 /**< Link is up. */
 
@@ -802,10 +804,13 @@ struct rte_intr_conf {
  * configuration settings may be needed.
  */
 struct rte_eth_conf {
-	uint16_t link_speed;
-	/**< ETH_SPEED_NUM_ or 0 for autonegotiation */
-	uint16_t link_duplex;
-	/**< ETH_LINK_[HALF_DUPLEX|FULL_DUPLEX], or 0 for autonegotation */
+	uint32_t link_speeds; /**< bitmap of ETH_LINK_SPEED_XXX of speeds to be
+				used. ETH_LINK_SPEED_FIXED disables link
+				autonegotiation, and a unique speed shall be
+				set. Otherwise, the bitmap defines the set of
+				speeds to be advertised. If the special value
+				ETH_LINK_SPEED_AUTONEG (0) is used, all speeds
+				supported are advertised. */
 	struct rte_eth_rxmode rxmode; /**< Port RX configuration. */
 	struct rte_eth_txmode txmode; /**< Port TX configuration. */
 	uint32_t lpbk_mode; /**< Loopback operation mode. By default the value
-- 
2.7.0

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

* [PATCH v11 7/8] ethdev: convert speed number to bitmap flag
  2016-03-17 18:08           ` [PATCH v11 0/8] ethdev: 100G and link speed API refactoring Thomas Monjalon
                               ` (5 preceding siblings ...)
  2016-03-17 18:09             ` [PATCH v11 6/8] ethdev: redesign link speed config Thomas Monjalon
@ 2016-03-17 18:09             ` Thomas Monjalon
  2016-03-17 18:09             ` [PATCH v11 8/8] ethdev: add 100G link speed Thomas Monjalon
                               ` (3 subsequent siblings)
  10 siblings, 0 replies; 167+ messages in thread
From: Thomas Monjalon @ 2016-03-17 18:09 UTC (permalink / raw)
  To: marcdevel, bruce.richardson, declan.doherty, konstantin.ananyev,
	wenzhuo.lu, helin.zhang, jing.d.chen, harish.patil,
	rahul.lakkireddy, johndale, vido, adrien.mazarguil,
	alejandro.lucero
  Cc: dev

From: Marc Sune <marcdevel@gmail.com>

It is a helper for the bitmap configuration.

Signed-off-by: Marc Sune <marcdevel@gmail.com>
Signed-off-by: Thomas Monjalon <thomas.monjalon@6wind.com>
---
 lib/librte_ether/rte_ethdev.c          | 31 +++++++++++++++++++++++++++++++
 lib/librte_ether/rte_ethdev.h          | 13 +++++++++++++
 lib/librte_ether/rte_ether_version.map |  1 +
 3 files changed, 45 insertions(+)

diff --git a/lib/librte_ether/rte_ethdev.c b/lib/librte_ether/rte_ethdev.c
index db35102..4dbea4e 100644
--- a/lib/librte_ether/rte_ethdev.c
+++ b/lib/librte_ether/rte_ethdev.c
@@ -866,6 +866,37 @@ rte_eth_dev_tx_queue_config(struct rte_eth_dev *dev, uint16_t nb_queues)
 	return 0;
 }
 
+uint32_t
+rte_eth_speed_bitflag(uint32_t speed, int duplex)
+{
+	switch (speed) {
+	case ETH_SPEED_NUM_10M:
+		return duplex ? ETH_LINK_SPEED_10M : ETH_LINK_SPEED_10M_HD;
+	case ETH_SPEED_NUM_100M:
+		return duplex ? ETH_LINK_SPEED_100M : ETH_LINK_SPEED_100M_HD;
+	case ETH_SPEED_NUM_1G:
+		return ETH_LINK_SPEED_1G;
+	case ETH_SPEED_NUM_2_5G:
+		return ETH_LINK_SPEED_2_5G;
+	case ETH_SPEED_NUM_5G:
+		return ETH_LINK_SPEED_5G;
+	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;
+	default:
+		return 0;
+	}
+}
+
 int
 rte_eth_dev_configure(uint8_t port_id, uint16_t nb_rx_q, uint16_t nb_tx_q,
 		      const struct rte_eth_conf *dev_conf)
diff --git a/lib/librte_ether/rte_ethdev.h b/lib/librte_ether/rte_ethdev.h
index 470e434..4b37cd0 100644
--- a/lib/librte_ether/rte_ethdev.h
+++ b/lib/librte_ether/rte_ethdev.h
@@ -1871,6 +1871,19 @@ struct eth_driver {
 void rte_eth_driver_register(struct eth_driver *eth_drv);
 
 /**
+ * Convert a numerical speed in Mbps to a bitmap flag that can be used in
+ * the bitmap link_speeds of the struct rte_eth_conf
+ *
+ * @param speed
+ *   Numerical speed value in Mbps
+ * @param duplex
+ *   ETH_LINK_[HALF/FULL]_DUPLEX (only for 10/100M speeds)
+ * @return
+ *   0 if the speed cannot be mapped
+ */
+uint32_t rte_eth_speed_bitflag(uint32_t speed, int duplex);
+
+/**
  * Configure an Ethernet device.
  * This function must be invoked first before any other function in the
  * Ethernet API. This function can also be re-invoked when a device is in the
diff --git a/lib/librte_ether/rte_ether_version.map b/lib/librte_ether/rte_ether_version.map
index 5cb4d79..13d9f2e 100644
--- a/lib/librte_ether/rte_ether_version.map
+++ b/lib/librte_ether/rte_ether_version.map
@@ -124,6 +124,7 @@ DPDK_16.04 {
 	rte_eth_dev_set_vlan_ether_type;
 	rte_eth_dev_udp_tunnel_port_add;
 	rte_eth_dev_udp_tunnel_port_delete;
+	rte_eth_speed_bitflag;
 	rte_eth_tx_buffer_count_callback;
 	rte_eth_tx_buffer_drop_callback;
 	rte_eth_tx_buffer_init;
-- 
2.7.0

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

* [PATCH v11 8/8] ethdev: add 100G link speed
  2016-03-17 18:08           ` [PATCH v11 0/8] ethdev: 100G and link speed API refactoring Thomas Monjalon
                               ` (6 preceding siblings ...)
  2016-03-17 18:09             ` [PATCH v11 7/8] ethdev: convert speed number to bitmap flag Thomas Monjalon
@ 2016-03-17 18:09             ` Thomas Monjalon
  2016-03-22 19:58             ` [PATCH v11 0/8] ethdev: 100G and link speed API refactoring Thomas Monjalon
                               ` (2 subsequent siblings)
  10 siblings, 0 replies; 167+ messages in thread
From: Thomas Monjalon @ 2016-03-17 18:09 UTC (permalink / raw)
  To: marcdevel, bruce.richardson, declan.doherty, konstantin.ananyev,
	wenzhuo.lu, helin.zhang, jing.d.chen, harish.patil,
	rahul.lakkireddy, johndale, vido, adrien.mazarguil,
	alejandro.lucero
  Cc: dev

The link speed configuration is now done with bitmaps so 100G speed
requires only a new bit flag.
The actual link speed is a number so its size must be increased from
16-bit to 32-bit.

Signed-off-by: Marc Sune <marcdevel@gmail.com>
Tested-by: Nelio Laranjeiro <nelio.laranjeiro@6wind.com>
Signed-off-by: Thomas Monjalon <thomas.monjalon@6wind.com>
---
 app/test-pmd/cmdline.c                      | 12 +++++++-----
 doc/guides/nics/szedata2.rst                |  6 ------
 doc/guides/rel_notes/release_16_04.rst      |  5 +++++
 doc/guides/testpmd_app_ug/testpmd_funcs.rst |  2 +-
 drivers/net/fm10k/fm10k_ethdev.c            |  2 +-
 drivers/net/mlx5/mlx5_ethdev.c              |  2 +-
 drivers/net/nfp/nfp_net.c                   |  2 +-
 drivers/net/szedata2/rte_eth_szedata2.c     |  9 ++-------
 lib/librte_ether/rte_ethdev.c               |  2 ++
 lib/librte_ether/rte_ethdev.h               |  4 +++-
 10 files changed, 23 insertions(+), 23 deletions(-)

diff --git a/app/test-pmd/cmdline.c b/app/test-pmd/cmdline.c
index 3bc7bb4..3337b7b 100644
--- a/app/test-pmd/cmdline.c
+++ b/app/test-pmd/cmdline.c
@@ -549,7 +549,7 @@ static void cmd_help_long_parsed(void *parsed_result,
 			"    Detach physical or virtual dev by port_id\n\n"
 
 			"port config (port_id|all)"
-			" speed (10|100|1000|10000|40000|auto)"
+			" speed (10|100|1000|10000|40000|100000|auto)"
 			" duplex (half|full|auto)\n"
 			"    Set speed and duplex for all ports or port_id\n\n"
 
@@ -1017,6 +1017,8 @@ parse_and_check_speed_duplex(char *speedstr, char *duplexstr, uint32_t *speed)
 			*speed = ETH_LINK_SPEED_10G;
 		} else if (!strcmp(speedstr, "40000")) {
 			*speed = ETH_LINK_SPEED_40G;
+		} else if (!strcmp(speedstr, "100000")) {
+			*speed = ETH_LINK_SPEED_100G;
 		} else if (!strcmp(speedstr, "auto")) {
 			*speed = ETH_LINK_SPEED_AUTONEG;
 		} else {
@@ -1064,7 +1066,7 @@ cmdline_parse_token_string_t cmd_config_speed_all_item1 =
 	TOKEN_STRING_INITIALIZER(struct cmd_config_speed_all, item1, "speed");
 cmdline_parse_token_string_t cmd_config_speed_all_value1 =
 	TOKEN_STRING_INITIALIZER(struct cmd_config_speed_all, value1,
-						"10#100#1000#10000#40000#auto");
+						"10#100#1000#10000#40000#100000#auto");
 cmdline_parse_token_string_t cmd_config_speed_all_item2 =
 	TOKEN_STRING_INITIALIZER(struct cmd_config_speed_all, item2, "duplex");
 cmdline_parse_token_string_t cmd_config_speed_all_value2 =
@@ -1074,7 +1076,7 @@ cmdline_parse_token_string_t cmd_config_speed_all_value2 =
 cmdline_parse_inst_t cmd_config_speed_all = {
 	.f = cmd_config_speed_all_parsed,
 	.data = NULL,
-	.help_str = "port config all speed 10|100|1000|10000|40000|auto duplex "
+	.help_str = "port config all speed 10|100|1000|10000|40000|100000|auto duplex "
 							"half|full|auto",
 	.tokens = {
 		(void *)&cmd_config_speed_all_port,
@@ -1138,7 +1140,7 @@ cmdline_parse_token_string_t cmd_config_speed_specific_item1 =
 								"speed");
 cmdline_parse_token_string_t cmd_config_speed_specific_value1 =
 	TOKEN_STRING_INITIALIZER(struct cmd_config_speed_specific, value1,
-						"10#100#1000#10000#40000#auto");
+						"10#100#1000#10000#40000#100000#auto");
 cmdline_parse_token_string_t cmd_config_speed_specific_item2 =
 	TOKEN_STRING_INITIALIZER(struct cmd_config_speed_specific, item2,
 								"duplex");
@@ -1149,7 +1151,7 @@ cmdline_parse_token_string_t cmd_config_speed_specific_value2 =
 cmdline_parse_inst_t cmd_config_speed_specific = {
 	.f = cmd_config_speed_specific_parsed,
 	.data = NULL,
-	.help_str = "port config X speed 10|100|1000|10000|40000|auto duplex "
+	.help_str = "port config X speed 10|100|1000|10000|40000|100000|auto duplex "
 							"half|full|auto",
 	.tokens = {
 		(void *)&cmd_config_speed_specific_port,
diff --git a/doc/guides/nics/szedata2.rst b/doc/guides/nics/szedata2.rst
index 77c15b3..741b400 100644
--- a/doc/guides/nics/szedata2.rst
+++ b/doc/guides/nics/szedata2.rst
@@ -148,9 +148,3 @@ Example output:
      TX threshold registers: pthresh=0 hthresh=0 wthresh=0
      TX RS bit threshold=0 - TXQ flags=0x0
    testpmd>
-
-.. note::
-
-   Link speed API currently supports speeds up to 40 Gbps.
-   Therefore there is used 10G constant for 100 Gbps cards until the link speed
-   API is not changed.
diff --git a/doc/guides/rel_notes/release_16_04.rst b/doc/guides/rel_notes/release_16_04.rst
index 6540941..e6a9144 100644
--- a/doc/guides/rel_notes/release_16_04.rst
+++ b/doc/guides/rel_notes/release_16_04.rst
@@ -279,6 +279,11 @@ EAL
 Drivers
 ~~~~~~~
 
+* **ethdev: Fixed overflow for 100Gbps.**
+
+  100Gbps in Mbps (100000) was exceeding 16-bit max value of ``link_speed``
+  in ``rte_eth_link``.
+
 * **ethdev: Fixed byte order consistency between fdir flow and mask.**
 
   Fixed issue in ethdev library that the structure for setting
diff --git a/doc/guides/testpmd_app_ug/testpmd_funcs.rst b/doc/guides/testpmd_app_ug/testpmd_funcs.rst
index efaf2b5..cb49495 100644
--- a/doc/guides/testpmd_app_ug/testpmd_funcs.rst
+++ b/doc/guides/testpmd_app_ug/testpmd_funcs.rst
@@ -1155,7 +1155,7 @@ port config - speed
 
 Set the speed and duplex mode for all ports or a specific port::
 
-   testpmd> port config (port_id|all) speed (10|100|1000|10000|auto) \
+   testpmd> port config (port_id|all) speed (10|100|1000|10000|40000|100000|auto) \
             duplex (half|full|auto)
 
 port config - queues/descriptors
diff --git a/drivers/net/fm10k/fm10k_ethdev.c b/drivers/net/fm10k/fm10k_ethdev.c
index 2a1c222..056f3aa 100644
--- a/drivers/net/fm10k/fm10k_ethdev.c
+++ b/drivers/net/fm10k/fm10k_ethdev.c
@@ -1413,7 +1413,7 @@ fm10k_dev_infos_get(struct rte_eth_dev *dev,
 
 	dev_info->speed_capa = ETH_LINK_SPEED_1G | ETH_LINK_SPEED_2_5G |
 			ETH_LINK_SPEED_10G | ETH_LINK_SPEED_25G |
-			ETH_LINK_SPEED_40G;
+			ETH_LINK_SPEED_40G | ETH_LINK_SPEED_100G;
 }
 
 static int
diff --git a/drivers/net/mlx5/mlx5_ethdev.c b/drivers/net/mlx5/mlx5_ethdev.c
index 3487538..1f9ba98 100644
--- a/drivers/net/mlx5/mlx5_ethdev.c
+++ b/drivers/net/mlx5/mlx5_ethdev.c
@@ -524,7 +524,7 @@ mlx5_dev_infos_get(struct rte_eth_dev *dev, struct rte_eth_dev_info *info)
 	info->reta_size = priv->ind_table_max_size;
 	info->speed_capa = ETH_LINK_SPEED_1G | ETH_LINK_SPEED_10G |
 			ETH_LINK_SPEED_25G | ETH_LINK_SPEED_40G |
-			ETH_LINK_SPEED_50G;
+			ETH_LINK_SPEED_50G | ETH_LINK_SPEED_100G;
 	priv_unlock(priv);
 }
 
diff --git a/drivers/net/nfp/nfp_net.c b/drivers/net/nfp/nfp_net.c
index c9e1dc5..fbf6737 100644
--- a/drivers/net/nfp/nfp_net.c
+++ b/drivers/net/nfp/nfp_net.c
@@ -1062,7 +1062,7 @@ nfp_net_infos_get(struct rte_eth_dev *dev, struct rte_eth_dev_info *dev_info)
 	dev_info->reta_size = NFP_NET_CFG_RSS_ITBL_SZ;
 	dev_info->hash_key_size = NFP_NET_CFG_RSS_KEY_SZ;
 
-	dev_info->speed_capa = ETH_LINK_SPEED_50G;
+	dev_info->speed_capa = ETH_LINK_SPEED_50G | ETH_LINK_SPEED_100G;
 }
 
 static uint32_t
diff --git a/drivers/net/szedata2/rte_eth_szedata2.c b/drivers/net/szedata2/rte_eth_szedata2.c
index 0708e4a..916333f 100644
--- a/drivers/net/szedata2/rte_eth_szedata2.c
+++ b/drivers/net/szedata2/rte_eth_szedata2.c
@@ -1036,6 +1036,7 @@ eth_dev_info(struct rte_eth_dev *dev,
 	dev_info->max_rx_queues = internals->max_rx_queues;
 	dev_info->max_tx_queues = internals->max_tx_queues;
 	dev_info->min_rx_bufsize = 0;
+	dev_info->speed_capa = ETH_LINK_SPEED_100G;
 }
 
 static void
@@ -1155,13 +1156,7 @@ eth_link_update(struct rte_eth_dev *dev,
 		link.link_speed = ETH_SPEED_NUM_40G;
 		break;
 	case SZEDATA2_LINK_SPEED_100G:
-		/*
-		 * TODO
-		 * If link_speed value from rte_eth_link structure
-		 * will be changed to support 100Gbps speed change
-		 * this value to 100G.
-		 */
-		link.link_speed = ETH_SPEED_NUM_10G;
+		link.link_speed = ETH_SPEED_NUM_100G;
 		break;
 	default:
 		link.link_speed = ETH_SPEED_NUM_10G;
diff --git a/lib/librte_ether/rte_ethdev.c b/lib/librte_ether/rte_ethdev.c
index 4dbea4e..62937cb 100644
--- a/lib/librte_ether/rte_ethdev.c
+++ b/lib/librte_ether/rte_ethdev.c
@@ -892,6 +892,8 @@ rte_eth_speed_bitflag(uint32_t speed, int duplex)
 		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;
 	}
diff --git a/lib/librte_ether/rte_ethdev.h b/lib/librte_ether/rte_ethdev.h
index 4b37cd0..73ded7c 100644
--- a/lib/librte_ether/rte_ethdev.h
+++ b/lib/librte_ether/rte_ethdev.h
@@ -259,6 +259,7 @@ struct rte_eth_stats {
 #define ETH_LINK_SPEED_40G      (1 << 11)  /**<  40 Gbps */
 #define ETH_LINK_SPEED_50G      (1 << 12)  /**<  50 Gbps */
 #define ETH_LINK_SPEED_56G      (1 << 13)  /**<  56 Gbps */
+#define ETH_LINK_SPEED_100G     (1 << 14)  /**< 100 Gbps */
 
 /**
  * Ethernet numeric link speeds in Mbps
@@ -275,12 +276,13 @@ struct rte_eth_stats {
 #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 */
 
 /**
  * A structure used to retrieve link-level information of an Ethernet port.
  */
 struct rte_eth_link {
-	uint16_t link_speed;        /**< ETH_SPEED_NUM_ */
+	uint32_t link_speed;        /**< ETH_SPEED_NUM_ */
 	uint16_t link_duplex  : 1;  /**< ETH_LINK_[HALF/FULL]_DUPLEX */
 	uint16_t link_autoneg : 1;  /**< ETH_LINK_SPEED_[AUTONEG/FIXED] */
 	uint16_t link_status  : 1;  /**< ETH_LINK_[DOWN/UP] */
-- 
2.7.0

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

* Re: [PATCH v11 5/8] ethdev: add speed capabilities
  2016-03-17 18:09             ` [PATCH v11 5/8] ethdev: add speed capabilities Thomas Monjalon
@ 2016-03-18  5:18               ` Chen, Jing D
  2016-03-18  8:06                 ` Thomas Monjalon
  2016-03-18  9:28               ` Adrien Mazarguil
  1 sibling, 1 reply; 167+ messages in thread
From: Chen, Jing D @ 2016-03-18  5:18 UTC (permalink / raw)
  To: Thomas Monjalon, marcdevel, Richardson, Bruce, Doherty, Declan,
	Ananyev, Konstantin, Lu, Wenzhuo, Zhang, Helin, harish.patil,
	rahul.lakkireddy, johndale, vido, adrien.mazarguil,
	alejandro.lucero
  Cc: dev

Hi,

Best Regards,
Mark


> -----Original Message-----
> From: Thomas Monjalon [mailto:thomas.monjalon@6wind.com]
> Sent: Friday, March 18, 2016 2:09 AM
> To: marcdevel@gmail.com; Richardson, Bruce; Doherty, Declan; Ananyev,
> Konstantin; Lu, Wenzhuo; Zhang, Helin; Chen, Jing D; harish.patil@qlogic.com;
> rahul.lakkireddy@chelsio.com; johndale@cisco.com; vido@cesnet.cz;
> adrien.mazarguil@6wind.com; alejandro.lucero@netronome.com
> Cc: dev@dpdk.org
> Subject: [PATCH v11 5/8] ethdev: add speed capabilities
> 
> From: Marc Sune <marcdevel@gmail.com>
> 
> The speed capabilities of a device can be retrieved with
> rte_eth_dev_info_get().
> 
> The new field speed_capa is initialized in the drivers without
> taking care of device characteristics in this patch.
> When the capabilities of a driver are accurate, the table in
> overview.rst must be filled.
> 
> Signed-off-by: Marc Sune <marcdevel@gmail.com>
> ---
>  doc/guides/nics/overview.rst           |  1 +
>  doc/guides/rel_notes/release_16_04.rst |  8 ++++++++
>  drivers/net/bnx2x/bnx2x_ethdev.c       |  1 +
>  drivers/net/cxgbe/cxgbe_ethdev.c       |  1 +
>  drivers/net/e1000/em_ethdev.c          |  4 ++++
>  drivers/net/e1000/igb_ethdev.c         |  4 ++++
>  drivers/net/fm10k/fm10k_ethdev.c       |  4 ++++
>  drivers/net/i40e/i40e_ethdev.c         |  8 ++++++++
>  drivers/net/ixgbe/ixgbe_ethdev.c       |  8 ++++++++
>  drivers/net/mlx4/mlx4.c                |  2 ++
>  drivers/net/mlx5/mlx5_ethdev.c         |  3 +++
>  drivers/net/nfp/nfp_net.c              |  2 ++
>  lib/librte_ether/rte_ethdev.h          | 21 +++++++++++++++++++++
>  13 files changed, 67 insertions(+)
> 
> 
>  static void
> diff --git a/drivers/net/fm10k/fm10k_ethdev.c
> b/drivers/net/fm10k/fm10k_ethdev.c
> index edc8c11..2a1c222 100644
> --- a/drivers/net/fm10k/fm10k_ethdev.c
> +++ b/drivers/net/fm10k/fm10k_ethdev.c
> @@ -1410,6 +1410,10 @@ fm10k_dev_infos_get(struct rte_eth_dev *dev,
>  		.nb_min = FM10K_MIN_TX_DESC,
>  		.nb_align = FM10K_MULT_TX_DESC,
>  	};
> +
> +	dev_info->speed_capa = ETH_LINK_SPEED_1G |
> ETH_LINK_SPEED_2_5G |
> +			ETH_LINK_SPEED_10G | ETH_LINK_SPEED_25G |
> +			ETH_LINK_SPEED_40G;
>  }
> 

Fm10k has 100G capability, we'd better to add ETH_LINK_SPEED_100G here.

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

* Re: [PATCH v11 5/8] ethdev: add speed capabilities
  2016-03-18  5:18               ` Chen, Jing D
@ 2016-03-18  8:06                 ` Thomas Monjalon
  0 siblings, 0 replies; 167+ messages in thread
From: Thomas Monjalon @ 2016-03-18  8:06 UTC (permalink / raw)
  To: Chen, Jing D; +Cc: marcdevel, bruce.richardson, dev

2016-03-18 05:18, Chen, Jing D:
> > --- a/drivers/net/fm10k/fm10k_ethdev.c
> > +++ b/drivers/net/fm10k/fm10k_ethdev.c
> > @@ -1410,6 +1410,10 @@ fm10k_dev_infos_get(struct rte_eth_dev *dev,
> >  		.nb_min = FM10K_MIN_TX_DESC,
> >  		.nb_align = FM10K_MULT_TX_DESC,
> >  	};
> > +
> > +	dev_info->speed_capa = ETH_LINK_SPEED_1G |
> > ETH_LINK_SPEED_2_5G |
> > +			ETH_LINK_SPEED_10G | ETH_LINK_SPEED_25G |
> > +			ETH_LINK_SPEED_40G;
> >  }
> > 
> 
> Fm10k has 100G capability, we'd better to add ETH_LINK_SPEED_100G here.

The 100G capability is added in patch #8.

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

* Re: [PATCH v11 5/8] ethdev: add speed capabilities
  2016-03-17 18:09             ` [PATCH v11 5/8] ethdev: add speed capabilities Thomas Monjalon
  2016-03-18  5:18               ` Chen, Jing D
@ 2016-03-18  9:28               ` Adrien Mazarguil
  2016-03-18 10:12                 ` Thomas Monjalon
  1 sibling, 1 reply; 167+ messages in thread
From: Adrien Mazarguil @ 2016-03-18  9:28 UTC (permalink / raw)
  To: Thomas Monjalon
  Cc: marcdevel, bruce.richardson, declan.doherty, konstantin.ananyev,
	wenzhuo.lu, helin.zhang, jing.d.chen, harish.patil,
	rahul.lakkireddy, johndale, vido, alejandro.lucero, dev

On Thu, Mar 17, 2016 at 07:09:02PM +0100, Thomas Monjalon wrote:
> From: Marc Sune <marcdevel@gmail.com>
> 
> The speed capabilities of a device can be retrieved with
> rte_eth_dev_info_get().
> 
> The new field speed_capa is initialized in the drivers without
> taking care of device characteristics in this patch.
> When the capabilities of a driver are accurate, the table in
> overview.rst must be filled.
> 
> Signed-off-by: Marc Sune <marcdevel@gmail.com>
> ---
>  doc/guides/nics/overview.rst           |  1 +
>  doc/guides/rel_notes/release_16_04.rst |  8 ++++++++
>  drivers/net/bnx2x/bnx2x_ethdev.c       |  1 +
>  drivers/net/cxgbe/cxgbe_ethdev.c       |  1 +
>  drivers/net/e1000/em_ethdev.c          |  4 ++++
>  drivers/net/e1000/igb_ethdev.c         |  4 ++++
>  drivers/net/fm10k/fm10k_ethdev.c       |  4 ++++
>  drivers/net/i40e/i40e_ethdev.c         |  8 ++++++++
>  drivers/net/ixgbe/ixgbe_ethdev.c       |  8 ++++++++
>  drivers/net/mlx4/mlx4.c                |  2 ++
>  drivers/net/mlx5/mlx5_ethdev.c         |  3 +++
>  drivers/net/nfp/nfp_net.c              |  2 ++
>  lib/librte_ether/rte_ethdev.h          | 21 +++++++++++++++++++++
>  13 files changed, 67 insertions(+)
[...]
> diff --git a/drivers/net/mlx4/mlx4.c b/drivers/net/mlx4/mlx4.c
> index cc4e9aa..3a4a989 100644
> --- a/drivers/net/mlx4/mlx4.c
> +++ b/drivers/net/mlx4/mlx4.c
> @@ -4301,6 +4301,8 @@ mlx4_dev_infos_get(struct rte_eth_dev *dev, struct rte_eth_dev_info *info)
>  		 0);
>  	if (priv_get_ifname(priv, &ifname) == 0)
>  		info->if_index = if_nametoindex(ifname);
> +	info->speed_capa = ETH_LINK_SPEED_10G | ETH_LINK_SPEED_40G |
> +			ETH_LINK_SPEED_56G;
>  	priv_unlock(priv);
>  }

Missing: ETH_LINK_SPEED_100M (not sure if we care), ETH_LINK_SPEED_1G and
the nonstandard ETH_LINK_SPEED_20G with some adapters.

In the future we should provide a more accurate speed_capa depending on
actual port capabilities, several mlx4 adapters cannot handle them all.

> diff --git a/drivers/net/mlx5/mlx5_ethdev.c b/drivers/net/mlx5/mlx5_ethdev.c
> index 6704382..3487538 100644
> --- a/drivers/net/mlx5/mlx5_ethdev.c
> +++ b/drivers/net/mlx5/mlx5_ethdev.c
> @@ -522,6 +522,9 @@ mlx5_dev_infos_get(struct rte_eth_dev *dev, struct rte_eth_dev_info *info)
>  	 * size if it is not fixed.
>  	 * The API should be updated to solve this problem. */
>  	info->reta_size = priv->ind_table_max_size;
> +	info->speed_capa = ETH_LINK_SPEED_1G | ETH_LINK_SPEED_10G |
> +			ETH_LINK_SPEED_25G | ETH_LINK_SPEED_40G |
> +			ETH_LINK_SPEED_50G;
>  	priv_unlock(priv);
>  }

Missing: ETH_LINK_SPEED_100G, ETH_LINK_SPEED_20G and ETH_LINK_SPEED_56G.

Same as above, these capabilities actually depend on the adapter type and
should be probed.

I think ETH_LINK_SPEED_100M should work as well but I can't find it
mentioned anywhere, let's leave it out for now.

-- 
Adrien Mazarguil
6WIND

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

* Re: [PATCH v11 5/8] ethdev: add speed capabilities
  2016-03-18  9:28               ` Adrien Mazarguil
@ 2016-03-18 10:12                 ` Thomas Monjalon
  0 siblings, 0 replies; 167+ messages in thread
From: Thomas Monjalon @ 2016-03-18 10:12 UTC (permalink / raw)
  To: Adrien Mazarguil
  Cc: marcdevel, bruce.richardson, declan.doherty, konstantin.ananyev,
	wenzhuo.lu, helin.zhang, jing.d.chen, harish.patil,
	rahul.lakkireddy, johndale, vido, alejandro.lucero, dev

2016-03-18 10:28, Adrien Mazarguil:
> On Thu, Mar 17, 2016 at 07:09:02PM +0100, Thomas Monjalon wrote:
> > --- a/drivers/net/mlx4/mlx4.c
> > +++ b/drivers/net/mlx4/mlx4.c
> > @@ -4301,6 +4301,8 @@ mlx4_dev_infos_get(struct rte_eth_dev *dev, struct rte_eth_dev_info *info)
> >  		 0);
> >  	if (priv_get_ifname(priv, &ifname) == 0)
> >  		info->if_index = if_nametoindex(ifname);
> > +	info->speed_capa = ETH_LINK_SPEED_10G | ETH_LINK_SPEED_40G |
> > +			ETH_LINK_SPEED_56G;
> >  	priv_unlock(priv);
> >  }
> 
> Missing: ETH_LINK_SPEED_100M (not sure if we care), ETH_LINK_SPEED_1G and
> the nonstandard ETH_LINK_SPEED_20G with some adapters.

For v12:
-       info->speed_capa = ETH_LINK_SPEED_10G | ETH_LINK_SPEED_40G |
+       info->speed_capa =
+                       ETH_LINK_SPEED_1G |
+                       ETH_LINK_SPEED_10G |
+                       ETH_LINK_SPEED_20G |
+                       ETH_LINK_SPEED_40G |
                        ETH_LINK_SPEED_56G;

> In the future we should provide a more accurate speed_capa depending on
> actual port capabilities, several mlx4 adapters cannot handle them all.

When doing so, you'll be able to fill the row "speed capability" in overview.rst.

> > --- a/drivers/net/mlx5/mlx5_ethdev.c
> > +++ b/drivers/net/mlx5/mlx5_ethdev.c
> > @@ -522,6 +522,9 @@ mlx5_dev_infos_get(struct rte_eth_dev *dev, struct rte_eth_dev_info *info)
> >  	 * size if it is not fixed.
> >  	 * The API should be updated to solve this problem. */
> >  	info->reta_size = priv->ind_table_max_size;
> > +	info->speed_capa = ETH_LINK_SPEED_1G | ETH_LINK_SPEED_10G |
> > +			ETH_LINK_SPEED_25G | ETH_LINK_SPEED_40G |
> > +			ETH_LINK_SPEED_50G;
> >  	priv_unlock(priv);
> >  }
> 
> Missing: ETH_LINK_SPEED_100G, ETH_LINK_SPEED_20G and ETH_LINK_SPEED_56G.

For v12:
-       info->speed_capa = ETH_LINK_SPEED_1G | ETH_LINK_SPEED_10G |
-                       ETH_LINK_SPEED_25G | ETH_LINK_SPEED_40G |
-                       ETH_LINK_SPEED_50G | ETH_LINK_SPEED_100G;
+       info->speed_capa =
+                       ETH_LINK_SPEED_1G |
+                       ETH_LINK_SPEED_10G |
+                       ETH_LINK_SPEED_20G |
+                       ETH_LINK_SPEED_25G |
+                       ETH_LINK_SPEED_40G |
+                       ETH_LINK_SPEED_50G |
+                       ETH_LINK_SPEED_56G |
+                       ETH_LINK_SPEED_100G;

ETH_LINK_SPEED_100G is added in patch #8.

> Same as above, these capabilities actually depend on the adapter type and
> should be probed.
> 
> I think ETH_LINK_SPEED_100M should work as well but I can't find it
> mentioned anywhere, let's leave it out for now.

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

* Re: [PATCH v11 0/8] ethdev: 100G and link speed API refactoring
  2016-03-17 18:08           ` [PATCH v11 0/8] ethdev: 100G and link speed API refactoring Thomas Monjalon
                               ` (7 preceding siblings ...)
  2016-03-17 18:09             ` [PATCH v11 8/8] ethdev: add 100G link speed Thomas Monjalon
@ 2016-03-22 19:58             ` Thomas Monjalon
  2016-03-23  1:18               ` Xu, Qian Q
  2016-03-24 17:32             ` Matej Vido
  2016-03-25 19:42             ` [PATCH v12 " Thomas Monjalon
  10 siblings, 1 reply; 167+ messages in thread
From: Thomas Monjalon @ 2016-03-22 19:58 UTC (permalink / raw)
  To: konstantin.ananyev, wenzhuo.lu, helin.zhang
  Cc: marcdevel, bruce.richardson, dev

2016-03-17 19:08, Thomas Monjalon:
> There are still too few tests and reviews, especially for
> autonegotiation with Intel devices (patch #6).
> I would not be surprised to see some bugs in this rework.

Any feedback about autoneg in e1000/ixgbe/i40e?
Has it been tested before its integration in RC2?

> The capabilities must be adapted per device. It can be
> improved in a separate patch.
> 
> It will be integrated in 16.04-rc2.
> Please test and review shortly, thanks!

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

* Re: [PATCH v11 0/8] ethdev: 100G and link speed API refactoring
  2016-03-22 19:58             ` [PATCH v11 0/8] ethdev: 100G and link speed API refactoring Thomas Monjalon
@ 2016-03-23  1:18               ` Xu, Qian Q
  2016-03-23  8:39                 ` Thomas Monjalon
  2016-03-23 20:54                 ` Marc
  0 siblings, 2 replies; 167+ messages in thread
From: Xu, Qian Q @ 2016-03-23  1:18 UTC (permalink / raw)
  To: Thomas Monjalon, Ananyev, Konstantin, Lu, Wenzhuo, Zhang, Helin
  Cc: marcdevel, Richardson, Bruce, dev

We have tested with intel nic and found port can't be started for all nics:ixgbe/i40e/igb/bonding, see attached mail for more details. Please check and fix it. 


Thanks
Qian

-----Original Message-----
From: dev [mailto:dev-bounces@dpdk.org] On Behalf Of Thomas Monjalon
Sent: Wednesday, March 23, 2016 3:59 AM
To: Ananyev, Konstantin; Lu, Wenzhuo; Zhang, Helin
Cc: marcdevel@gmail.com; Richardson, Bruce; dev@dpdk.org
Subject: Re: [dpdk-dev] [PATCH v11 0/8] ethdev: 100G and link speed API refactoring

2016-03-17 19:08, Thomas Monjalon:
> There are still too few tests and reviews, especially for 
> autonegotiation with Intel devices (patch #6).
> I would not be surprised to see some bugs in this rework.

Any feedback about autoneg in e1000/ixgbe/i40e?
Has it been tested before its integration in RC2?

> The capabilities must be adapted per device. It can be improved in a 
> separate patch.
> 
> It will be integrated in 16.04-rc2.
> Please test and review shortly, thanks!

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

* Re: [PATCH v11 2/8] ethdev: use constants for link duplex
  2016-03-17 18:08             ` [PATCH v11 2/8] ethdev: use constants for link duplex Thomas Monjalon
@ 2016-03-23  2:44               ` Zhang, Helin
  2016-03-23  8:34                 ` Thomas Monjalon
  0 siblings, 1 reply; 167+ messages in thread
From: Zhang, Helin @ 2016-03-23  2:44 UTC (permalink / raw)
  To: Thomas Monjalon, marcdevel, Richardson, Bruce, Doherty, Declan,
	Ananyev, Konstantin, Lu, Wenzhuo, Chen, Jing D, harish.patil,
	rahul.lakkireddy, johndale, vido, adrien.mazarguil,
	alejandro.lucero
  Cc: dev



> -----Original Message-----
> From: Thomas Monjalon [mailto:thomas.monjalon@6wind.com]
> Sent: Friday, March 18, 2016 2:09 AM
> To: marcdevel@gmail.com; Richardson, Bruce; Doherty, Declan; Ananyev,
> Konstantin; Lu, Wenzhuo; Zhang, Helin; Chen, Jing D;
> harish.patil@qlogic.com; rahul.lakkireddy@chelsio.com;
> johndale@cisco.com; vido@cesnet.cz; adrien.mazarguil@6wind.com;
> alejandro.lucero@netronome.com
> Cc: dev@dpdk.org
> Subject: [PATCH v11 2/8] ethdev: use constants for link duplex
> 
> From: Marc Sune <marcdevel@gmail.com>
> 
> Some duplex values are replaced from 0 to half-duplex when link is down.
> 
> Some drivers are still using their own constants for duplex modes.
> 
> Signed-off-by: Marc Sune <marcdevel@gmail.com>
> ---
>  drivers/net/e1000/em_ethdev.c      | 2 +-
>  drivers/net/e1000/igb_ethdev.c     | 2 +-
>  drivers/net/ixgbe/ixgbe_ethdev.c   | 2 +-
>  drivers/net/virtio/virtio_ethdev.c | 2 +-  drivers/net/virtio/virtio_ethdev.h |
> 2 --
>  lib/librte_ether/rte_ethdev.h      | 2 +-
>  6 files changed, 5 insertions(+), 7 deletions(-)
> 
> diff --git a/drivers/net/e1000/em_ethdev.c
> b/drivers/net/e1000/em_ethdev.c index 58093c6..943a270 100644
> --- a/drivers/net/e1000/em_ethdev.c
> +++ b/drivers/net/e1000/em_ethdev.c
> @@ -1108,7 +1108,7 @@ eth_em_link_update(struct rte_eth_dev *dev, int
> wait_to_complete)
>  		link.link_status = ETH_LINK_UP;
>  	} else if (!link_check && (link.link_status == ETH_LINK_UP)) {
>  		link.link_speed = 0;
> -		link.link_duplex = 0;
> +		link.link_duplex = ETH_LINK_HALF_DUPLEX;
>  		link.link_status = ETH_LINK_DOWN;
>  	}
>  	rte_em_dev_atomic_write_link_status(dev, &link); diff --git
> a/drivers/net/e1000/igb_ethdev.c b/drivers/net/e1000/igb_ethdev.c index
> 311f866..ea156ce 100644
> --- a/drivers/net/e1000/igb_ethdev.c
> +++ b/drivers/net/e1000/igb_ethdev.c
> @@ -2033,7 +2033,7 @@ eth_igb_link_update(struct rte_eth_dev *dev, int
> wait_to_complete)
>  		link.link_status = ETH_LINK_UP;
>  	} else if (!link_check) {
>  		link.link_speed = 0;
> -		link.link_duplex = 0;
> +		link.link_duplex = ETH_LINK_HALF_DUPLEX;
>  		link.link_status = ETH_LINK_DOWN;
>  	}
>  	rte_igb_dev_atomic_write_link_status(dev, &link); diff --git
> a/drivers/net/ixgbe/ixgbe_ethdev.c b/drivers/net/ixgbe/ixgbe_ethdev.c
> index be28f7e..35dac49 100644
> --- a/drivers/net/ixgbe/ixgbe_ethdev.c
> +++ b/drivers/net/ixgbe/ixgbe_ethdev.c
> @@ -2997,7 +2997,7 @@ ixgbe_dev_link_update(struct rte_eth_dev *dev,
> int wait_to_complete)
> 
>  	link.link_status = ETH_LINK_DOWN;
>  	link.link_speed = 0;
> -	link.link_duplex = 0;
> +	link.link_duplex = ETH_LINK_HALF_DUPLEX;
>  	memset(&old, 0, sizeof(old));
>  	rte_ixgbe_dev_atomic_read_link_status(dev, &old);
> 
> diff --git a/drivers/net/virtio/virtio_ethdev.c
> b/drivers/net/virtio/virtio_ethdev.c
> index 3ebc221..63a368a 100644
> --- a/drivers/net/virtio/virtio_ethdev.c
> +++ b/drivers/net/virtio/virtio_ethdev.c
> @@ -1401,7 +1401,7 @@ virtio_dev_link_update(struct rte_eth_dev *dev,
> __rte_unused int wait_to_complet
>  	memset(&link, 0, sizeof(link));
>  	virtio_dev_atomic_read_link_status(dev, &link);
>  	old = link;
> -	link.link_duplex = FULL_DUPLEX;
> +	link.link_duplex = ETH_LINK_FULL_DUPLEX;
>  	link.link_speed  = SPEED_10G;
> 
>  	if (vtpci_with_feature(hw, VIRTIO_NET_F_STATUS)) { diff --git
> a/drivers/net/virtio/virtio_ethdev.h b/drivers/net/virtio/virtio_ethdev.h
> index fed9571..66423a0 100644
> --- a/drivers/net/virtio/virtio_ethdev.h
> +++ b/drivers/net/virtio/virtio_ethdev.h
> @@ -42,8 +42,6 @@
>  #define SPEED_100	100
>  #define SPEED_1000	1000
>  #define SPEED_10G	10000
> -#define HALF_DUPLEX	1
> -#define FULL_DUPLEX	2
> 
>  #ifndef PAGE_SIZE
>  #define PAGE_SIZE 4096
> diff --git a/lib/librte_ether/rte_ethdev.h b/lib/librte_ether/rte_ethdev.h
> index ec8d6b1..5379bee 100644
> --- a/lib/librte_ether/rte_ethdev.h
> +++ b/lib/librte_ether/rte_ethdev.h
> @@ -246,7 +246,7 @@ struct rte_eth_stats {
>   */
>  struct rte_eth_link {
>  	uint16_t link_speed;      /**< ETH_LINK_SPEED_[10, 100, 1000, 10000]
> */
> -	uint16_t link_duplex;     /**< ETH_LINK_[HALF_DUPLEX,
> FULL_DUPLEX] */
> +	uint16_t link_duplex;     /**< ETH_LINK_[HALF/FULL]_DUPLEX */
>  	uint8_t  link_status : 1; /**< ETH_LINK_[DOWN/UP] */
>  }__attribute__((aligned(8)));     /**< aligned for atomic64 read/write */
For link speed and link duplex, I'd suggest to add one more status of 'UNKNOWN'.
Because, sometimes it cannot get all the information from hardware.
For link stauts, assume it in DOWN state is acceptable, while for other two, I don't think so.

Currently it can be seen that a default link speed and duplex will be set if it cannot
get the accurate info from hardware. That's not good, and I think UNKNOWN could be better.

What do you think?

Thanks,
Helin

> 
> --
> 2.7.0

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

* Re: [PATCH v11 4/8] ethdev: rename link speed constants
  2016-03-17 18:09             ` [PATCH v11 4/8] ethdev: rename link speed constants Thomas Monjalon
@ 2016-03-23  2:52               ` Zhang, Helin
  2016-03-23  8:31                 ` Thomas Monjalon
  0 siblings, 1 reply; 167+ messages in thread
From: Zhang, Helin @ 2016-03-23  2:52 UTC (permalink / raw)
  To: Thomas Monjalon, marcdevel, Richardson, Bruce, Doherty, Declan,
	Ananyev, Konstantin, Lu, Wenzhuo, Chen, Jing D, harish.patil,
	rahul.lakkireddy, johndale, vido, adrien.mazarguil,
	alejandro.lucero
  Cc: dev



> -----Original Message-----
> From: Thomas Monjalon [mailto:thomas.monjalon@6wind.com]
> Sent: Friday, March 18, 2016 2:09 AM
> To: marcdevel@gmail.com; Richardson, Bruce; Doherty, Declan; Ananyev,
> Konstantin; Lu, Wenzhuo; Zhang, Helin; Chen, Jing D;
> harish.patil@qlogic.com; rahul.lakkireddy@chelsio.com;
> johndale@cisco.com; vido@cesnet.cz; adrien.mazarguil@6wind.com;
> alejandro.lucero@netronome.com
> Cc: dev@dpdk.org
> Subject: [PATCH v11 4/8] ethdev: rename link speed constants
> 
> From: Marc Sune <marcdevel@gmail.com>
> 
> The speed numbers ETH_LINK_SPEED_ are renamed ETH_SPEED_NUM_.
> The prefix ETH_LINK_SPEED_ is kept for AUTONEG and will be used for bit
> flags in next patch.
> 
> Signed-off-by: Marc Sune <marcdevel@gmail.com>
> ---
>  app/test-pmd/cmdline.c                    | 10 +++++-----
>  app/test/virtual_pmd.c                    |  2 +-
>  drivers/net/af_packet/rte_eth_af_packet.c |  2 +-
> drivers/net/bonding/rte_eth_bond_8023ad.c | 12 ++++++------
>  drivers/net/cxgbe/base/t4_hw.c            |  8 ++++----
>  drivers/net/e1000/em_ethdev.c             |  8 ++++----
>  drivers/net/e1000/igb_ethdev.c            |  8 ++++----
>  drivers/net/i40e/i40e_ethdev.c            | 30 +++++++++++++++---------------
>  drivers/net/i40e/i40e_ethdev_vf.c         |  2 +-
>  drivers/net/ixgbe/ixgbe_ethdev.c          | 22 +++++++++++-----------
>  drivers/net/mpipe/mpipe_tilegx.c          |  4 ++--
>  drivers/net/nfp/nfp_net.c                 |  2 +-
>  drivers/net/null/rte_eth_null.c           |  2 +-
>  drivers/net/pcap/rte_eth_pcap.c           |  2 +-
>  drivers/net/ring/rte_eth_ring.c           |  2 +-
>  drivers/net/szedata2/rte_eth_szedata2.c   |  8 ++++----
>  drivers/net/vmxnet3/vmxnet3_ethdev.c      |  2 +-
>  drivers/net/xenvirt/rte_eth_xenvirt.c     |  2 +-
>  lib/librte_ether/rte_ethdev.h             | 29 ++++++++++++++++++-----------
>  19 files changed, 82 insertions(+), 75 deletions(-)
> 
> diff --git a/app/test-pmd/cmdline.c b/app/test-pmd/cmdline.c index
> 37be5cd..874129a 100644
> --- a/app/test-pmd/cmdline.c
> +++ b/app/test-pmd/cmdline.c
> @@ -1001,20 +1001,20 @@ parse_and_check_speed_duplex(char *speedstr,
> char *duplexstr, uint16_t *speed)
>  	}
> 
>  	if (!strcmp(speedstr, "10")) {
> -		*speed = ETH_LINK_SPEED_10;
> +		*speed = ETH_SPEED_NUM_10M;
>  	} else if (!strcmp(speedstr, "100")) {
> -		*speed = ETH_LINK_SPEED_100;
> +		*speed = ETH_SPEED_NUM_100M;
>  	} else {
>  		if (duplex != ETH_LINK_FULL_DUPLEX) {
>  			printf("Invalid speed/duplex parameters\n");
>  			return -1;
>  		}
>  		if (!strcmp(speedstr, "1000")) {
> -			*speed = ETH_LINK_SPEED_1000;
> +			*speed = ETH_SPEED_NUM_1G;
>  		} else if (!strcmp(speedstr, "10000")) {
> -			*speed = ETH_LINK_SPEED_10G;
> +			*speed = ETH_SPEED_NUM_10G;
>  		} else if (!strcmp(speedstr, "40000")) {
> -			*speed = ETH_LINK_SPEED_40G;
> +			*speed = ETH_SPEED_NUM_40G;
>  		} else if (!strcmp(speedstr, "auto")) {
>  			*speed = ETH_LINK_SPEED_AUTONEG;
>  		} else {
> diff --git a/app/test/virtual_pmd.c b/app/test/virtual_pmd.c index
> b1d40d7..b4bd2f2 100644
> --- a/app/test/virtual_pmd.c
> +++ b/app/test/virtual_pmd.c
> @@ -604,7 +604,7 @@ virtual_ethdev_create(const char *name, struct
> ether_addr *mac_addr,
>  	TAILQ_INIT(&(eth_dev->link_intr_cbs));
> 
>  	eth_dev->data->dev_link.link_status = ETH_LINK_DOWN;
> -	eth_dev->data->dev_link.link_speed = ETH_LINK_SPEED_10000;
> +	eth_dev->data->dev_link.link_speed = ETH_SPEED_NUM_10G;
>  	eth_dev->data->dev_link.link_duplex = ETH_LINK_FULL_DUPLEX;
> 
>  	eth_dev->data->mac_addrs = rte_zmalloc(name, ETHER_ADDR_LEN,
> 0); diff --git a/drivers/net/af_packet/rte_eth_af_packet.c
> b/drivers/net/af_packet/rte_eth_af_packet.c
> index dee7b59..641f849 100644
> --- a/drivers/net/af_packet/rte_eth_af_packet.c
> +++ b/drivers/net/af_packet/rte_eth_af_packet.c
> @@ -116,7 +116,7 @@ static const char *valid_arguments[] = {  static const
> char *drivername = "AF_PACKET PMD";
> 
>  static struct rte_eth_link pmd_link = {
> -	.link_speed = 10000,
> +	.link_speed = ETH_SPEED_NUM_10G,
>  	.link_duplex = ETH_LINK_FULL_DUPLEX,
>  	.link_status = ETH_LINK_DOWN,
>  };
> diff --git a/drivers/net/bonding/rte_eth_bond_8023ad.c
> b/drivers/net/bonding/rte_eth_bond_8023ad.c
> index 1b7e93a..ac8306f 100644
> --- a/drivers/net/bonding/rte_eth_bond_8023ad.c
> +++ b/drivers/net/bonding/rte_eth_bond_8023ad.c
> @@ -711,22 +711,22 @@ link_speed_key(uint16_t speed) {
>  	case ETH_LINK_SPEED_AUTONEG:
>  		key_speed = 0x00;
>  		break;
> -	case ETH_LINK_SPEED_10:
> +	case ETH_SPEED_NUM_10M:
>  		key_speed = BOND_LINK_SPEED_KEY_10M;
>  		break;
> -	case ETH_LINK_SPEED_100:
> +	case ETH_SPEED_NUM_100M:
>  		key_speed = BOND_LINK_SPEED_KEY_100M;
>  		break;
> -	case ETH_LINK_SPEED_1000:
> +	case ETH_SPEED_NUM_1G:
>  		key_speed = BOND_LINK_SPEED_KEY_1000M;
>  		break;
> -	case ETH_LINK_SPEED_10G:
> +	case ETH_SPEED_NUM_10G:
>  		key_speed = BOND_LINK_SPEED_KEY_10G;
>  		break;
> -	case ETH_LINK_SPEED_20G:
> +	case ETH_SPEED_NUM_20G:
>  		key_speed = BOND_LINK_SPEED_KEY_20G;
>  		break;
> -	case ETH_LINK_SPEED_40G:
> +	case ETH_SPEED_NUM_40G:
>  		key_speed = BOND_LINK_SPEED_KEY_40G;
>  		break;
>  	default:
> diff --git a/drivers/net/cxgbe/base/t4_hw.c
> b/drivers/net/cxgbe/base/t4_hw.c index 884d2cf..79af806 100644
> --- a/drivers/net/cxgbe/base/t4_hw.c
> +++ b/drivers/net/cxgbe/base/t4_hw.c
> @@ -2159,13 +2159,13 @@ int t4_handle_fw_rpl(struct adapter *adap,
> const __be64 *rpl)
>  		if (stat & F_FW_PORT_CMD_TXPAUSE)
>  			fc |= PAUSE_TX;
>  		if (stat &
> V_FW_PORT_CMD_LSPEED(FW_PORT_CAP_SPEED_100M))
> -			speed = ETH_LINK_SPEED_100;
> +			speed = ETH_SPEED_NUM_100M;
>  		else if (stat &
> V_FW_PORT_CMD_LSPEED(FW_PORT_CAP_SPEED_1G))
> -			speed = ETH_LINK_SPEED_1000;
> +			speed = ETH_SPEED_NUM_1G;
>  		else if (stat &
> V_FW_PORT_CMD_LSPEED(FW_PORT_CAP_SPEED_10G))
> -			speed = ETH_LINK_SPEED_10000;
> +			speed = ETH_SPEED_NUM_10G;
>  		else if (stat &
> V_FW_PORT_CMD_LSPEED(FW_PORT_CAP_SPEED_40G))
> -			speed = ETH_LINK_SPEED_40G;
> +			speed = ETH_SPEED_NUM_40G;
> 
>  		for_each_port(adap, i) {
>  			pi = adap2pinfo(adap, i);
> diff --git a/drivers/net/e1000/em_ethdev.c
> b/drivers/net/e1000/em_ethdev.c index 943a270..b9dbc0f 100644
> --- a/drivers/net/e1000/em_ethdev.c
> +++ b/drivers/net/e1000/em_ethdev.c
> @@ -625,7 +625,7 @@ eth_em_start(struct rte_eth_dev *dev)
>  		else
>  			goto error_invalid_config;
>  		break;
> -	case ETH_LINK_SPEED_10:
> +	case ETH_SPEED_NUM_10M:
>  		if (dev->data->dev_conf.link_duplex ==
> ETH_LINK_AUTONEG_DUPLEX)
>  			hw->phy.autoneg_advertised =
> E1000_ALL_10_SPEED;
>  		else if (dev->data->dev_conf.link_duplex == @@ -637,7
> +637,7 @@ eth_em_start(struct rte_eth_dev *dev)
>  		else
>  			goto error_invalid_config;
>  		break;
> -	case ETH_LINK_SPEED_100:
> +	case ETH_SPEED_NUM_100M:
>  		if (dev->data->dev_conf.link_duplex ==
> ETH_LINK_AUTONEG_DUPLEX)
>  			hw->phy.autoneg_advertised =
> E1000_ALL_100_SPEED;
>  		else if (dev->data->dev_conf.link_duplex == @@ -649,7
> +649,7 @@ eth_em_start(struct rte_eth_dev *dev)
>  		else
>  			goto error_invalid_config;
>  		break;
> -	case ETH_LINK_SPEED_1000:
> +	case ETH_SPEED_NUM_1G:
>  		if ((dev->data->dev_conf.link_duplex ==
>  				ETH_LINK_AUTONEG_DUPLEX) ||
>  			(dev->data->dev_conf.link_duplex ==
> @@ -658,7 +658,7 @@ eth_em_start(struct rte_eth_dev *dev)
>  		else
>  			goto error_invalid_config;
>  		break;
> -	case ETH_LINK_SPEED_10000:
> +	case ETH_SPEED_NUM_10G:
>  	default:
>  		goto error_invalid_config;
>  	}
> diff --git a/drivers/net/e1000/igb_ethdev.c
> b/drivers/net/e1000/igb_ethdev.c index ea156ce..11786ef 100644
> --- a/drivers/net/e1000/igb_ethdev.c
> +++ b/drivers/net/e1000/igb_ethdev.c
> @@ -1241,7 +1241,7 @@ eth_igb_start(struct rte_eth_dev *dev)
>  		else
>  			goto error_invalid_config;
>  		break;
> -	case ETH_LINK_SPEED_10:
> +	case ETH_SPEED_NUM_10M:
>  		if (dev->data->dev_conf.link_duplex ==
> ETH_LINK_AUTONEG_DUPLEX)
>  			hw->phy.autoneg_advertised =
> E1000_ALL_10_SPEED;
>  		else if (dev->data->dev_conf.link_duplex ==
> ETH_LINK_HALF_DUPLEX) @@ -1251,7 +1251,7 @@ eth_igb_start(struct
> rte_eth_dev *dev)
>  		else
>  			goto error_invalid_config;
>  		break;
> -	case ETH_LINK_SPEED_100:
> +	case ETH_SPEED_NUM_100M:
>  		if (dev->data->dev_conf.link_duplex ==
> ETH_LINK_AUTONEG_DUPLEX)
>  			hw->phy.autoneg_advertised =
> E1000_ALL_100_SPEED;
>  		else if (dev->data->dev_conf.link_duplex ==
> ETH_LINK_HALF_DUPLEX) @@ -1261,14 +1261,14 @@ eth_igb_start(struct
> rte_eth_dev *dev)
>  		else
>  			goto error_invalid_config;
>  		break;
> -	case ETH_LINK_SPEED_1000:
> +	case ETH_SPEED_NUM_1G:
>  		if ((dev->data->dev_conf.link_duplex ==
> ETH_LINK_AUTONEG_DUPLEX) ||
>  				(dev->data->dev_conf.link_duplex ==
> ETH_LINK_FULL_DUPLEX))
>  			hw->phy.autoneg_advertised =
> ADVERTISE_1000_FULL;
>  		else
>  			goto error_invalid_config;
>  		break;
> -	case ETH_LINK_SPEED_10000:
> +	case ETH_SPEED_NUM_10G:
>  	default:
>  		goto error_invalid_config;
>  	}
> diff --git a/drivers/net/i40e/i40e_ethdev.c b/drivers/net/i40e/i40e_ethdev.c
> index 10e0d38..5d8bdd9 100644
> --- a/drivers/net/i40e/i40e_ethdev.c
> +++ b/drivers/net/i40e/i40e_ethdev.c
> @@ -1372,19 +1372,19 @@ i40e_parse_link_speed(uint16_t eth_link_speed)
>  	uint8_t link_speed = I40E_LINK_SPEED_UNKNOWN;
> 
>  	switch (eth_link_speed) {
> -	case ETH_LINK_SPEED_40G:
> +	case ETH_SPEED_NUM_40G:
>  		link_speed = I40E_LINK_SPEED_40GB;
>  		break;
> -	case ETH_LINK_SPEED_20G:
> +	case ETH_SPEED_NUM_20G:
>  		link_speed = I40E_LINK_SPEED_20GB;
>  		break;
> -	case ETH_LINK_SPEED_10G:
> +	case ETH_SPEED_NUM_10G:
>  		link_speed = I40E_LINK_SPEED_10GB;
>  		break;
> -	case ETH_LINK_SPEED_1000:
> +	case ETH_SPEED_NUM_1G:
>  		link_speed = I40E_LINK_SPEED_1GB;
>  		break;
> -	case ETH_LINK_SPEED_100:
> +	case ETH_SPEED_NUM_100M:
>  		link_speed = I40E_LINK_SPEED_100MB;
>  		break;
>  	}
> @@ -1754,7 +1754,7 @@ i40e_dev_link_update(struct rte_eth_dev *dev,
>  		/* Get link status information from hardware */
>  		status = i40e_aq_get_link_info(hw, false, &link_status,
> NULL);
>  		if (status != I40E_SUCCESS) {
> -			link.link_speed = ETH_LINK_SPEED_100;
> +			link.link_speed = ETH_SPEED_NUM_100M;
>  			link.link_duplex = ETH_LINK_FULL_DUPLEX;
>  			PMD_DRV_LOG(ERR, "Failed to get link info");
>  			goto out;
> @@ -1776,22 +1776,22 @@ i40e_dev_link_update(struct rte_eth_dev *dev,
>  	/* Parse the link status */
>  	switch (link_status.link_speed) {
>  	case I40E_LINK_SPEED_100MB:
> -		link.link_speed = ETH_LINK_SPEED_100;
> +		link.link_speed = ETH_SPEED_NUM_100M;
>  		break;
>  	case I40E_LINK_SPEED_1GB:
> -		link.link_speed = ETH_LINK_SPEED_1000;
> +		link.link_speed = ETH_SPEED_NUM_1G;
>  		break;
>  	case I40E_LINK_SPEED_10GB:
> -		link.link_speed = ETH_LINK_SPEED_10G;
> +		link.link_speed = ETH_SPEED_NUM_10G;
>  		break;
>  	case I40E_LINK_SPEED_20GB:
> -		link.link_speed = ETH_LINK_SPEED_20G;
> +		link.link_speed = ETH_SPEED_NUM_20G;
>  		break;
>  	case I40E_LINK_SPEED_40GB:
> -		link.link_speed = ETH_LINK_SPEED_40G;
> +		link.link_speed = ETH_SPEED_NUM_40G;
>  		break;
>  	default:
> -		link.link_speed = ETH_LINK_SPEED_100;
> +		link.link_speed = ETH_SPEED_NUM_100M;
>  		break;
>  	}
> 
> @@ -8087,15 +8087,15 @@ i40e_start_timecounters(struct rte_eth_dev
> *dev)
>  	rte_i40e_dev_atomic_read_link_status(dev, &link);
> 
>  	switch (link.link_speed) {
> -	case ETH_LINK_SPEED_40G:
> +	case ETH_SPEED_NUM_40G:
>  		tsync_inc_l = I40E_PTP_40GB_INCVAL & 0xFFFFFFFF;
>  		tsync_inc_h = I40E_PTP_40GB_INCVAL >> 32;
>  		break;
> -	case ETH_LINK_SPEED_10G:
> +	case ETH_SPEED_NUM_10G:
>  		tsync_inc_l = I40E_PTP_10GB_INCVAL & 0xFFFFFFFF;
>  		tsync_inc_h = I40E_PTP_10GB_INCVAL >> 32;
>  		break;
> -	case ETH_LINK_SPEED_1000:
> +	case ETH_SPEED_NUM_1G:
>  		tsync_inc_l = I40E_PTP_1GB_INCVAL & 0xFFFFFFFF;
>  		tsync_inc_h = I40E_PTP_1GB_INCVAL >> 32;
>  		break;
> diff --git a/drivers/net/i40e/i40e_ethdev_vf.c
> b/drivers/net/i40e/i40e_ethdev_vf.c
> index de00aff..f2b37a2 100644
> --- a/drivers/net/i40e/i40e_ethdev_vf.c
> +++ b/drivers/net/i40e/i40e_ethdev_vf.c
> @@ -1958,7 +1958,7 @@ i40evf_dev_link_update(struct rte_eth_dev *dev,
>  	else {
>  		/* Always assume it's up, for Linux driver PF host */
>  		new_link.link_duplex = ETH_LINK_AUTONEG_DUPLEX;
> -		new_link.link_speed  = ETH_LINK_SPEED_10000;
> +		new_link.link_speed  = ETH_SPEED_NUM_10G;
>  		new_link.link_status = ETH_LINK_UP;
>  	}
>  	i40evf_dev_atomic_write_link_status(dev, &new_link); diff --git
> a/drivers/net/ixgbe/ixgbe_ethdev.c b/drivers/net/ixgbe/ixgbe_ethdev.c
> index 35dac49..9246fdb 100644
> --- a/drivers/net/ixgbe/ixgbe_ethdev.c
> +++ b/drivers/net/ixgbe/ixgbe_ethdev.c
> @@ -2179,17 +2179,17 @@ ixgbe_dev_start(struct rte_eth_dev *dev)
>  				IXGBE_LINK_SPEED_82599_AUTONEG :
>  				IXGBE_LINK_SPEED_82598_AUTONEG;
>  		break;
> -	case ETH_LINK_SPEED_100:
> +	case ETH_SPEED_NUM_100M:
>  		/*
>  		 * Invalid for 82598 but error will be detected by
>  		 * ixgbe_setup_link()
>  		 */
>  		speed = IXGBE_LINK_SPEED_100_FULL;
>  		break;
> -	case ETH_LINK_SPEED_1000:
> +	case ETH_SPEED_NUM_1G:
>  		speed = IXGBE_LINK_SPEED_1GB_FULL;
>  		break;
> -	case ETH_LINK_SPEED_10000:
> +	case ETH_SPEED_NUM_10G:
>  		speed = IXGBE_LINK_SPEED_10GB_FULL;
>  		break;
>  	default:
> @@ -3010,7 +3010,7 @@ ixgbe_dev_link_update(struct rte_eth_dev *dev,
> int wait_to_complete)
>  		diag = ixgbe_check_link(hw, &link_speed, &link_up, 1);
> 
>  	if (diag != 0) {
> -		link.link_speed = ETH_LINK_SPEED_100;
> +		link.link_speed = ETH_SPEED_NUM_100M;
>  		link.link_duplex = ETH_LINK_HALF_DUPLEX;
>  		rte_ixgbe_dev_atomic_write_link_status(dev, &link);
>  		if (link.link_status == old.link_status) @@ -3031,19 +3031,19
> @@ ixgbe_dev_link_update(struct rte_eth_dev *dev, int wait_to_complete)
>  	default:
>  	case IXGBE_LINK_SPEED_UNKNOWN:
>  		link.link_duplex = ETH_LINK_HALF_DUPLEX;
> -		link.link_speed = ETH_LINK_SPEED_100;
> +		link.link_speed = ETH_SPEED_NUM_100M;
>  		break;
> 
>  	case IXGBE_LINK_SPEED_100_FULL:
> -		link.link_speed = ETH_LINK_SPEED_100;
> +		link.link_speed = ETH_SPEED_NUM_100M;
>  		break;
> 
>  	case IXGBE_LINK_SPEED_1GB_FULL:
> -		link.link_speed = ETH_LINK_SPEED_1000;
> +		link.link_speed = ETH_SPEED_NUM_1G;
>  		break;
> 
>  	case IXGBE_LINK_SPEED_10GB_FULL:
> -		link.link_speed = ETH_LINK_SPEED_10000;
> +		link.link_speed = ETH_SPEED_NUM_10G;
>  		break;
>  	}
>  	rte_ixgbe_dev_atomic_write_link_status(dev, &link); @@ -5838,15
> +5838,15 @@ ixgbe_start_timecounters(struct rte_eth_dev *dev)
>  	rte_ixgbe_dev_atomic_read_link_status(dev, &link);
> 
>  	switch (link.link_speed) {
> -	case ETH_LINK_SPEED_100:
> +	case ETH_SPEED_NUM_100M:
>  		incval = IXGBE_INCVAL_100;
>  		shift = IXGBE_INCVAL_SHIFT_100;
>  		break;
> -	case ETH_LINK_SPEED_1000:
> +	case ETH_SPEED_NUM_1G:
>  		incval = IXGBE_INCVAL_1GB;
>  		shift = IXGBE_INCVAL_SHIFT_1GB;
>  		break;
> -	case ETH_LINK_SPEED_10000:
> +	case ETH_SPEED_NUM_10G:
>  	default:
>  		incval = IXGBE_INCVAL_10GB;
>  		shift = IXGBE_INCVAL_SHIFT_10GB;
> diff --git a/drivers/net/mpipe/mpipe_tilegx.c
> b/drivers/net/mpipe/mpipe_tilegx.c
> index 1e04b75..960d468 100644
> --- a/drivers/net/mpipe/mpipe_tilegx.c
> +++ b/drivers/net/mpipe/mpipe_tilegx.c
> @@ -395,11 +395,11 @@ mpipe_link_update(struct rte_eth_dev *dev, int
> wait_to_complete)
>  		speed = state & GXIO_MPIPE_LINK_SPEED_MASK;
> 
>  		if (speed == GXIO_MPIPE_LINK_1G) {
> -			new.link_speed = ETH_LINK_SPEED_1000;
> +			new.link_speed = ETH_SPEED_NUM_1G;
>  			new.link_duplex = ETH_LINK_FULL_DUPLEX;
>  			new.link_status = ETH_LINK_UP;
>  		} else if (speed == GXIO_MPIPE_LINK_10G) {
> -			new.link_speed = ETH_LINK_SPEED_10000;
> +			new.link_speed = ETH_SPEED_NUM_10G;
>  			new.link_duplex = ETH_LINK_FULL_DUPLEX;
>  			new.link_status = ETH_LINK_UP;
>  		}
> diff --git a/drivers/net/nfp/nfp_net.c b/drivers/net/nfp/nfp_net.c index
> 7cb7d76..9e314bd 100644
> --- a/drivers/net/nfp/nfp_net.c
> +++ b/drivers/net/nfp/nfp_net.c
> @@ -821,7 +821,7 @@ nfp_net_link_update(struct rte_eth_dev *dev,
> __rte_unused int wait_to_complete)
> 
>  	link.link_duplex = ETH_LINK_FULL_DUPLEX;
>  	/* Other cards can limit the tx and rx rate per VF */
> -	link.link_speed = ETH_LINK_SPEED_40G;
> +	link.link_speed = ETH_SPEED_NUM_40G;
> 
>  	if (old.link_status != link.link_status) {
>  		nfp_net_dev_atomic_write_link_status(dev, &link); diff --git
> a/drivers/net/null/rte_eth_null.c b/drivers/net/null/rte_eth_null.c index
> 6adea91..5640585 100644
> --- a/drivers/net/null/rte_eth_null.c
> +++ b/drivers/net/null/rte_eth_null.c
> @@ -89,7 +89,7 @@ struct pmd_internals {  static struct ether_addr
> eth_addr = { .addr_bytes = {0} };  static const char *drivername = "Null PMD";
> static struct rte_eth_link pmd_link = {
> -	.link_speed = 10000,
> +	.link_speed = ETH_SPEED_NUM_10G,
>  	.link_duplex = ETH_LINK_FULL_DUPLEX,
>  	.link_status = ETH_LINK_DOWN,
>  };
> diff --git a/drivers/net/pcap/rte_eth_pcap.c
> b/drivers/net/pcap/rte_eth_pcap.c index b90c725..c657951 100644
> --- a/drivers/net/pcap/rte_eth_pcap.c
> +++ b/drivers/net/pcap/rte_eth_pcap.c
> @@ -123,7 +123,7 @@ static int open_single_iface(const char *iface,
> pcap_t **pcap);  static struct ether_addr eth_addr = { .addr_bytes = { 0, 0, 0,
> 0x1, 0x2, 0x3 } };  static const char *drivername = "Pcap PMD";  static struct
> rte_eth_link pmd_link = {
> -		.link_speed = 10000,
> +		.link_speed = ETH_SPEED_NUM_10G,
>  		.link_duplex = ETH_LINK_FULL_DUPLEX,
>  		.link_status = ETH_LINK_DOWN,
>  };
> diff --git a/drivers/net/ring/rte_eth_ring.c b/drivers/net/ring/rte_eth_ring.c
> index 4335c6a..58685e9 100644
> --- a/drivers/net/ring/rte_eth_ring.c
> +++ b/drivers/net/ring/rte_eth_ring.c
> @@ -77,7 +77,7 @@ struct pmd_internals {
> 
>  static const char *drivername = "Rings PMD";  static struct rte_eth_link
> pmd_link = {
> -		.link_speed = 10000,
> +		.link_speed = ETH_SPEED_NUM_10G,
>  		.link_duplex = ETH_LINK_FULL_DUPLEX,
>  		.link_status = ETH_LINK_DOWN,
>  };
> diff --git a/drivers/net/szedata2/rte_eth_szedata2.c
> b/drivers/net/szedata2/rte_eth_szedata2.c
> index c65067e..854cb5c 100644
> --- a/drivers/net/szedata2/rte_eth_szedata2.c
> +++ b/drivers/net/szedata2/rte_eth_szedata2.c
> @@ -1149,10 +1149,10 @@ eth_link_update(struct rte_eth_dev *dev,
> 
>  	switch (cgmii_link_speed(ibuf)) {
>  	case SZEDATA2_LINK_SPEED_10G:
> -		link.link_speed = ETH_LINK_SPEED_10G;
> +		link.link_speed = ETH_SPEED_NUM_10G;
>  		break;
>  	case SZEDATA2_LINK_SPEED_40G:
> -		link.link_speed = ETH_LINK_SPEED_40G;
> +		link.link_speed = ETH_SPEED_NUM_40G;
>  		break;
>  	case SZEDATA2_LINK_SPEED_100G:
>  		/*
> @@ -1161,10 +1161,10 @@ eth_link_update(struct rte_eth_dev *dev,
>  		 * will be changed to support 100Gbps speed change
>  		 * this value to 100G.
>  		 */
> -		link.link_speed = ETH_LINK_SPEED_10G;
> +		link.link_speed = ETH_SPEED_NUM_10G;
>  		break;
>  	default:
> -		link.link_speed = ETH_LINK_SPEED_10G;
> +		link.link_speed = ETH_SPEED_NUM_10G;
>  		break;
>  	}
> 
> diff --git a/drivers/net/vmxnet3/vmxnet3_ethdev.c
> b/drivers/net/vmxnet3/vmxnet3_ethdev.c
> index 7fe3a53..ad8029b 100644
> --- a/drivers/net/vmxnet3/vmxnet3_ethdev.c
> +++ b/drivers/net/vmxnet3/vmxnet3_ethdev.c
> @@ -762,7 +762,7 @@ vmxnet3_dev_link_update(struct rte_eth_dev *dev,
> __attribute__((unused)) int wai
>  	if (ret & 0x1) {
>  		link.link_status = ETH_LINK_UP;
>  		link.link_duplex = ETH_LINK_FULL_DUPLEX;
> -		link.link_speed = ETH_LINK_SPEED_10000;
> +		link.link_speed = ETH_SPEED_NUM_10G;
>  	}
> 
>  	vmxnet3_dev_atomic_write_link_status(dev, &link); diff --git
> a/drivers/net/xenvirt/rte_eth_xenvirt.c
> b/drivers/net/xenvirt/rte_eth_xenvirt.c
> index 9453a06..77d3ba1 100644
> --- a/drivers/net/xenvirt/rte_eth_xenvirt.c
> +++ b/drivers/net/xenvirt/rte_eth_xenvirt.c
> @@ -70,7 +70,7 @@ static int virtio_idx = 0;  static const char *drivername =
> "xen virtio PMD";
> 
>  static struct rte_eth_link pmd_link = {
> -		.link_speed = 10000,
> +		.link_speed = ETH_SPEED_NUM_10G,
>  		.link_duplex = ETH_LINK_FULL_DUPLEX,
>  		.link_status = ETH_LINK_DOWN,
>  };
> diff --git a/lib/librte_ether/rte_ethdev.h b/lib/librte_ether/rte_ethdev.h
> index 5379bee..d7c8a66 100644
> --- a/lib/librte_ether/rte_ethdev.h
> +++ b/lib/librte_ether/rte_ethdev.h
> @@ -242,23 +242,30 @@ struct rte_eth_stats {  };
> 
>  /**
> + * Ethernet numeric link speeds in Mbps  */
> +#define ETH_LINK_SPEED_AUTONEG     0 /**< Auto-negotiate link speed. */
> +#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 */
100G is coming, should we define it here?

> +
> +/**
>   * A structure used to retrieve link-level information of an Ethernet port.
>   */
>  struct rte_eth_link {
> -	uint16_t link_speed;      /**< ETH_LINK_SPEED_[10, 100, 1000, 10000]
> */
> +	uint16_t link_speed;      /**< ETH_SPEED_NUM_ */
>  	uint16_t link_duplex;     /**< ETH_LINK_[HALF/FULL]_DUPLEX */
>  	uint8_t  link_status : 1; /**< ETH_LINK_[DOWN/UP] */
>  }__attribute__((aligned(8)));     /**< aligned for atomic64 read/write */
> 
> -#define ETH_LINK_SPEED_AUTONEG  0       /**< Auto-negotiate link speed.
> */
> -#define ETH_LINK_SPEED_10       10      /**< 10 megabits/second. */
> -#define ETH_LINK_SPEED_100      100     /**< 100 megabits/second. */
> -#define ETH_LINK_SPEED_1000     1000    /**< 1 gigabits/second. */
> -#define ETH_LINK_SPEED_10000    10000   /**< 10 gigabits/second. */
> -#define ETH_LINK_SPEED_10G      10000   /**< alias of 10 gigabits/second.
> */
> -#define ETH_LINK_SPEED_20G      20000   /**< 20 gigabits/second. */
> -#define ETH_LINK_SPEED_40G      40000   /**< 40 gigabits/second. */
> -
>  /* Utility constants */
>  #define ETH_LINK_AUTONEG_DUPLEX 0       /**< Auto-negotiate duplex. */
>  #define ETH_LINK_HALF_DUPLEX    1       /**< Half-duplex connection. */
> @@ -779,7 +786,7 @@ struct rte_intr_conf {
>   */
>  struct rte_eth_conf {
>  	uint16_t link_speed;
100G support?
Uint16_t -> uint32_t to support 100G?

Thanks,
/Helin

> -	/**< ETH_LINK_SPEED_10[0|00|000], or 0 for autonegotation */
> +	/**< ETH_SPEED_NUM_ or 0 for autonegotiation */
>  	uint16_t link_duplex;
>  	/**< ETH_LINK_[HALF_DUPLEX|FULL_DUPLEX], or 0 for
> autonegotation */
>  	struct rte_eth_rxmode rxmode; /**< Port RX configuration. */
> --
> 2.7.0

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

* Re: [PATCH v11 4/8] ethdev: rename link speed constants
  2016-03-23  2:52               ` Zhang, Helin
@ 2016-03-23  8:31                 ` Thomas Monjalon
  0 siblings, 0 replies; 167+ messages in thread
From: Thomas Monjalon @ 2016-03-23  8:31 UTC (permalink / raw)
  To: Zhang, Helin; +Cc: dev, marcdevel

2016-03-23 02:52, Zhang, Helin:
> >  struct rte_eth_conf {
> >       uint16_t link_speed;
> 100G support?
> Uint16_t -> uint32_t to support 100G?

Yes, see next patches.

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

* Re: [PATCH v11 2/8] ethdev: use constants for link duplex
  2016-03-23  2:44               ` Zhang, Helin
@ 2016-03-23  8:34                 ` Thomas Monjalon
  0 siblings, 0 replies; 167+ messages in thread
From: Thomas Monjalon @ 2016-03-23  8:34 UTC (permalink / raw)
  To: Zhang, Helin
  Cc: marcdevel, Richardson, Bruce, Doherty, Declan, Ananyev,
	Konstantin, Lu, Wenzhuo, dev

2016-03-23 02:44, Zhang, Helin:
> >  struct rte_eth_link {
> >       uint16_t link_speed;      /**< ETH_LINK_SPEED_[10, 100, 1000, 10000]
> > */
> > -     uint16_t link_duplex;     /**< ETH_LINK_[HALF_DUPLEX,
> > FULL_DUPLEX] */
> > +     uint16_t link_duplex;     /**< ETH_LINK_[HALF/FULL]_DUPLEX */
> >       uint8_t  link_status : 1; /**< ETH_LINK_[DOWN/UP] */
> >  }__attribute__((aligned(8)));     /**< aligned for atomic64 read/write */
> For link speed and link duplex, I'd suggest to add one more status of 'UNKNOWN'.
> Because, sometimes it cannot get all the information from hardware.
> For link stauts, assume it in DOWN state is acceptable, while for other two, I don't think so.
> 
> Currently it can be seen that a default link speed and duplex will be set if it cannot
> get the accurate info from hardware. That's not good, and I think UNKNOWN could be better.
> 
> What do you think?

OK, please provide a patch on top of this one to set ETH_LINK_UNKNOWN_DUPLEX
in the drivers where appropriate.

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

* Re: [PATCH v11 0/8] ethdev: 100G and link speed API refactoring
  2016-03-23  1:18               ` Xu, Qian Q
@ 2016-03-23  8:39                 ` Thomas Monjalon
  2016-03-23 20:54                 ` Marc
  1 sibling, 0 replies; 167+ messages in thread
From: Thomas Monjalon @ 2016-03-23  8:39 UTC (permalink / raw)
  To: Xu, Qian Q, Ananyev, Konstantin, Lu, Wenzhuo, Zhang, Helin
  Cc: marcdevel, Richardson, Bruce, dev

2016-03-23 01:18, Xu, Qian Q:
> We have tested with intel nic and found port can't be started for all
> nics:ixgbe/i40e/igb/bonding, see attached mail for more details.
> Please check and fix it. 

Thanks for testing.

This patchset was in the air for several months but unfortunately there was
no test of Intel devices until now.
Please Intel drivers maintainers, help to fix it quickly.
Thanks

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

* Re: [PATCH v11 0/8] ethdev: 100G and link speed API refactoring
  2016-03-23  1:18               ` Xu, Qian Q
  2016-03-23  8:39                 ` Thomas Monjalon
@ 2016-03-23 20:54                 ` Marc
  2016-03-24  6:21                   ` Xu, Qian Q
  1 sibling, 1 reply; 167+ messages in thread
From: Marc @ 2016-03-23 20:54 UTC (permalink / raw)
  To: Xu, Qian Q
  Cc: Thomas Monjalon, Ananyev, Konstantin, Lu, Wenzhuo, Zhang, Helin,
	Richardson, Bruce, dev

Qian,

On 23 March 2016 at 02:18, Xu, Qian Q <qian.q.xu@intel.com> wrote:

> We have tested with intel nic and found port can't be started for all
> nics:ixgbe/i40e/igb/bonding, see attached mail for more details. Please
> check and fix it.
>
>
> Thanks
> Qian
>
> -----Original Message-----
> From: dev [mailto:dev-bounces@dpdk.org] On Behalf Of Thomas Monjalon
> Sent: Wednesday, March 23, 2016 3:59 AM
> To: Ananyev, Konstantin; Lu, Wenzhuo; Zhang, Helin
> Cc: marcdevel@gmail.com; Richardson, Bruce; dev@dpdk.org
> Subject: Re: [dpdk-dev] [PATCH v11 0/8] ethdev: 100G and link speed API
> refactoring
>
> 2016-03-17 19:08, Thomas Monjalon:
> > There are still too few tests and reviews, especially for
> > autonegotiation with Intel devices (patch #6).
> > I would not be surprised to see some bugs in this rework.
>
> Any feedback about autoneg in e1000/ixgbe/i40e?
> Has it been tested before its integration in RC2?
>
> > The capabilities must be adapted per device. It can be improved in a
> > separate patch.
> >
> > It will be integrated in 16.04-rc2.
> > Please test and review shortly, thanks!
>
>
>
> ---------- Forwarded message ----------
> From: "Xu, Qian Q" <qian.q.xu@intel.com>
> To: "Cao, Waterman" <waterman.cao@intel.com>, "Glynn, Michael J" <
> michael.j.glynn@intel.com>
> Cc: "Richardson, Bruce" <bruce.richardson@intel.com>, "Zhu, Heqing" <
> heqing.zhu@intel.com>, "O'Driscoll, Tim" <tim.odriscoll@intel.com>,
> "Mcnamara, John" <john.mcnamara@intel.com>, "Xu, HuilongX" <
> huilongx.xu@intel.com>, "Fu, JingguoX" <jingguox.fu@intel.com>, "Xu, Qian
> Q" <qian.q.xu@intel.com>, "Zhang, Helin" <helin.zhang@intel.com>
> Date: Tue, 22 Mar 2016 06:41:37 +0000
> Subject: RE: DPDK link speed with Intel devices
> Hi, all
> We have worked out the basic test cases for the patchset.
> 1. Test the link speed on major Intel NICs to see if the speed is right.
> 2. Test the auto-negoation on major Intel NICs to ensure it's working.
> Nic covered: ixgbe, igb, i40e, fm10k, bonding(SW), virtio(SW)
>
> When we run the Test#1 for all major NICs. We found that all these NIC
> port(igb, ixgbe, i40e, fm10k) can't be started. Pls check, if the patch is
> applied, all INTEL port can't be start, terrible things!
>
> Interactive-mode selected
> Configuring Port 0 (socket 0)
> PMD: ixgbe_dev_tx_queue_setup(): sw_ring=0x7f13e99e3440
> hw_ring=0x7f13e99e5480 dma_addr=0x8299e5480
> PMD: ixgbe_set_tx_function(): Using simple tx code path
> PMD: ixgbe_set_tx_function(): Vector tx enabled.
> PMD: ixgbe_dev_rx_queue_setup(): sw_ring=0x7f13ffcb8080
> sw_sc_ring=0x7f13ffcbaac0 hw_ring=0x7f13e99d3380 dma_addr=0x8299d3380
> PMD: ixgbe_dev_start(): Invalid link_speeds for port 0; autonegotiation
> disabled
> Fail to start port 0
> Configuring Port 1 (socket 0)
> PMD: i40e_set_tx_function_flag(): Vector tx can be enabled on this txq.
> PMD: i40e_dev_rx_queue_setup(): Rx Burst Bulk Alloc Preconditions are
> satisfied. Rx Burst Bulk Alloc function will be used on port=1, queue=0.
> PMD: i40e_dev_start(): Invalid link_speeds for port 1; autonegotiation
> disabled
>


Just to double-check; is the test#1 adapted to the _new_ API that ethdev
has to set link speeds? For the output it seems autoneg is disabled =>
fixed speed, hence the new bitmaps have to be used.

(I am not claiming patchset is bug free; there might be issues still)

Regards
marc

Fail to start port 1
> Please stop the ports first
> Done
>
> Thanks
> Qian
>
>
> -----Original Message-----
> From: Cao, Waterman
> Sent: Tuesday, March 22, 2016 11:06 AM
> To: Glynn, Michael J
> Cc: Richardson, Bruce; Zhu, Heqing; O'Driscoll, Tim; Mcnamara, John; Xu,
> Qian Q; Cao, Waterman
> Subject: RE: DPDK link speed with Intel devices
>
> Hi Mike,
>
>         We just knew this patch set last week.
>         Since this patch set is required to test with a lot of NIC,  we
> need more document from Dev about this patch.
>         Currently, Qian is working on with Wenzhuo on it now.
>
> Waterman
>
>
> -----Original Message-----
> From: Glynn, Michael J
> Sent: Tuesday, March 22, 2016 1:31 AM
> To: Cao, Waterman <waterman.cao@intel.com>
> Cc: Richardson, Bruce <bruce.richardson@intel.com>; Zhu, Heqing <
> heqing.zhu@intel.com>; O'Driscoll, Tim <tim.odriscoll@intel.com>;
> Mcnamara, John <john.mcnamara@intel.com>
> Subject: FW: DPDK link speed with Intel devices
> Importance: High
>
> Hi Waterman, all
>
> See below - are you aware? And if so where are we with testing/resolution?
>
> Regards
> Mike
>
>
>
> -----Original Message-----
> From: Thomas Monjalon [mailto:thomas.monjalon@6wind.com]
> Sent: Monday, March 21, 2016 2:19 PM
> To: O'Driscoll, Tim <tim.odriscoll@intel.com>; Glynn, Michael J <
> michael.j.glynn@intel.com>; Zhu, Heqing <heqing.zhu@intel.com>
> Cc: vincent.jardin@6wind.com
> Subject: DPDK link speed with Intel devices
>
> Hi,
>
> We are still waiting for test feedbacks for this important patchset:
>         ethdev: 100G and link speed API refactoring It is possible that it
> breaks the autonegotiation in e1000/ixgbe/i40e.
>
> Thanks for taking care.
>
>

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

* Re: [PATCH v11 0/8] ethdev: 100G and link speed API refactoring
  2016-03-23 20:54                 ` Marc
@ 2016-03-24  6:21                   ` Xu, Qian Q
  2016-03-24  7:47                     ` Marc
  0 siblings, 1 reply; 167+ messages in thread
From: Xu, Qian Q @ 2016-03-24  6:21 UTC (permalink / raw)
  To: Marc
  Cc: Thomas Monjalon, Ananyev, Konstantin, Lu, Wenzhuo, Zhang, Helin,
	Richardson, Bruce, dev

Marc
I didn’t quite get your points, I observed that after applying this patchset, all intel nic can’t be started, maybe something wrong happened when you check the duplex/autoneg value for different NICs. If we want to merge the patchset in RC2, we need fix them. Maybe not an easy job in several days.


Thanks
Qian

From: marc.sune@gmail.com [mailto:marc.sune@gmail.com] On Behalf Of Marc
Sent: Thursday, March 24, 2016 4:54 AM
To: Xu, Qian Q
Cc: Thomas Monjalon; Ananyev, Konstantin; Lu, Wenzhuo; Zhang, Helin; Richardson, Bruce; dev@dpdk.org
Subject: Re: [dpdk-dev] [PATCH v11 0/8] ethdev: 100G and link speed API refactoring

Qian,

On 23 March 2016 at 02:18, Xu, Qian Q <qian.q.xu@intel.com<mailto:qian.q.xu@intel.com>> wrote:
We have tested with intel nic and found port can't be started for all nics:ixgbe/i40e/igb/bonding, see attached mail for more details. Please check and fix it.


Thanks
Qian

-----Original Message-----
From: dev [mailto:dev-bounces@dpdk.org<mailto:dev-bounces@dpdk.org>] On Behalf Of Thomas Monjalon
Sent: Wednesday, March 23, 2016 3:59 AM
To: Ananyev, Konstantin; Lu, Wenzhuo; Zhang, Helin
Cc: marcdevel@gmail.com<mailto:marcdevel@gmail.com>; Richardson, Bruce; dev@dpdk.org<mailto:dev@dpdk.org>
Subject: Re: [dpdk-dev] [PATCH v11 0/8] ethdev: 100G and link speed API refactoring

2016-03-17 19:08, Thomas Monjalon:
> There are still too few tests and reviews, especially for
> autonegotiation with Intel devices (patch #6).
> I would not be surprised to see some bugs in this rework.

Any feedback about autoneg in e1000/ixgbe/i40e?
Has it been tested before its integration in RC2?

> The capabilities must be adapted per device. It can be improved in a
> separate patch.
>
> It will be integrated in 16.04-rc2.
> Please test and review shortly, thanks!


---------- Forwarded message ----------
From: "Xu, Qian Q" <qian.q.xu@intel.com<mailto:qian.q.xu@intel.com>>
To: "Cao, Waterman" <waterman.cao@intel.com<mailto:waterman.cao@intel.com>>, "Glynn, Michael J" <michael.j.glynn@intel.com<mailto:michael.j.glynn@intel.com>>
Cc: "Richardson, Bruce" <bruce.richardson@intel.com<mailto:bruce.richardson@intel.com>>, "Zhu, Heqing" <heqing.zhu@intel.com<mailto:heqing.zhu@intel.com>>, "O'Driscoll, Tim" <tim.odriscoll@intel.com<mailto:tim.odriscoll@intel.com>>, "Mcnamara, John" <john.mcnamara@intel.com<mailto:john.mcnamara@intel.com>>, "Xu, HuilongX" <huilongx.xu@intel.com<mailto:huilongx.xu@intel.com>>, "Fu, JingguoX" <jingguox.fu@intel.com<mailto:jingguox.fu@intel.com>>, "Xu, Qian Q" <qian.q.xu@intel.com<mailto:qian.q.xu@intel.com>>, "Zhang, Helin" <helin.zhang@intel.com<mailto:helin.zhang@intel.com>>
Date: Tue, 22 Mar 2016 06:41:37 +0000
Subject: RE: DPDK link speed with Intel devices
Hi, all
We have worked out the basic test cases for the patchset.
1. Test the link speed on major Intel NICs to see if the speed is right.
2. Test the auto-negoation on major Intel NICs to ensure it's working.
Nic covered: ixgbe, igb, i40e, fm10k, bonding(SW), virtio(SW)

When we run the Test#1 for all major NICs. We found that all these NIC port(igb, ixgbe, i40e, fm10k) can't be started. Pls check, if the patch is applied, all INTEL port can't be start, terrible things!

Interactive-mode selected
Configuring Port 0 (socket 0)
PMD: ixgbe_dev_tx_queue_setup(): sw_ring=0x7f13e99e3440 hw_ring=0x7f13e99e5480 dma_addr=0x8299e5480
PMD: ixgbe_set_tx_function(): Using simple tx code path
PMD: ixgbe_set_tx_function(): Vector tx enabled.
PMD: ixgbe_dev_rx_queue_setup(): sw_ring=0x7f13ffcb8080 sw_sc_ring=0x7f13ffcbaac0 hw_ring=0x7f13e99d3380 dma_addr=0x8299d3380
PMD: ixgbe_dev_start(): Invalid link_speeds for port 0; autonegotiation disabled
Fail to start port 0
Configuring Port 1 (socket 0)
PMD: i40e_set_tx_function_flag(): Vector tx can be enabled on this txq.
PMD: i40e_dev_rx_queue_setup(): Rx Burst Bulk Alloc Preconditions are satisfied. Rx Burst Bulk Alloc function will be used on port=1, queue=0.
PMD: i40e_dev_start(): Invalid link_speeds for port 1; autonegotiation disabled


Just to double-check; is the test#1 adapted to the _new_ API that ethdev has to set link speeds? For the output it seems autoneg is disabled => fixed speed, hence the new bitmaps have to be used.

(I am not claiming patchset is bug free; there might be issues still)

Regards
marc

Fail to start port 1
Please stop the ports first
Done

Thanks
Qian


-----Original Message-----
From: Cao, Waterman
Sent: Tuesday, March 22, 2016 11:06 AM
To: Glynn, Michael J
Cc: Richardson, Bruce; Zhu, Heqing; O'Driscoll, Tim; Mcnamara, John; Xu, Qian Q; Cao, Waterman
Subject: RE: DPDK link speed with Intel devices

Hi Mike,

        We just knew this patch set last week.
        Since this patch set is required to test with a lot of NIC,  we need more document from Dev about this patch.
        Currently, Qian is working on with Wenzhuo on it now.

Waterman


-----Original Message-----
From: Glynn, Michael J
Sent: Tuesday, March 22, 2016 1:31 AM
To: Cao, Waterman <waterman.cao@intel.com<mailto:waterman.cao@intel.com>>
Cc: Richardson, Bruce <bruce.richardson@intel.com<mailto:bruce.richardson@intel.com>>; Zhu, Heqing <heqing.zhu@intel.com<mailto:heqing.zhu@intel.com>>; O'Driscoll, Tim <tim.odriscoll@intel.com<mailto:tim.odriscoll@intel.com>>; Mcnamara, John <john.mcnamara@intel.com<mailto:john.mcnamara@intel.com>>
Subject: FW: DPDK link speed with Intel devices
Importance: High

Hi Waterman, all

See below - are you aware? And if so where are we with testing/resolution?

Regards
Mike



-----Original Message-----
From: Thomas Monjalon [mailto:thomas.monjalon@6wind.com<mailto:thomas.monjalon@6wind.com>]
Sent: Monday, March 21, 2016 2:19 PM
To: O'Driscoll, Tim <tim.odriscoll@intel.com<mailto:tim.odriscoll@intel.com>>; Glynn, Michael J <michael.j.glynn@intel.com<mailto:michael.j.glynn@intel.com>>; Zhu, Heqing <heqing.zhu@intel.com<mailto:heqing.zhu@intel.com>>
Cc: vincent.jardin@6wind.com<mailto:vincent.jardin@6wind.com>
Subject: DPDK link speed with Intel devices

Hi,

We are still waiting for test feedbacks for this important patchset:
        ethdev: 100G and link speed API refactoring It is possible that it breaks the autonegotiation in e1000/ixgbe/i40e.

Thanks for taking care.


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

* Re: [PATCH v11 0/8] ethdev: 100G and link speed API refactoring
  2016-03-24  6:21                   ` Xu, Qian Q
@ 2016-03-24  7:47                     ` Marc
  2016-03-25  1:02                       ` Xu, Qian Q
  0 siblings, 1 reply; 167+ messages in thread
From: Marc @ 2016-03-24  7:47 UTC (permalink / raw)
  To: Xu, Qian Q
  Cc: Thomas Monjalon, Ananyev, Konstantin, Lu, Wenzhuo, Zhang, Helin,
	Richardson, Bruce, dev

On 24 March 2016 at 07:21, Xu, Qian Q <qian.q.xu@intel.com> wrote:

> Marc
>
> I didn’t quite get your points, I observed that after applying this
> patchset, all intel nic can’t be started, maybe something wrong happened
> when you check the duplex/autoneg value for different NICs. If we want to
> merge the patchset in RC2, we need fix them. Maybe not an easy job in
> several days.
>

Is this test#1 one of the tests contained in the DPDK repository or is it
an internal test?

Marc


>
>
>
>
> Thanks
>
> Qian
>
>
>
> *From:* marc.sune@gmail.com [mailto:marc.sune@gmail.com] *On Behalf Of *
> Marc
> *Sent:* Thursday, March 24, 2016 4:54 AM
> *To:* Xu, Qian Q
> *Cc:* Thomas Monjalon; Ananyev, Konstantin; Lu, Wenzhuo; Zhang, Helin;
> Richardson, Bruce; dev@dpdk.org
>
> *Subject:* Re: [dpdk-dev] [PATCH v11 0/8] ethdev: 100G and link speed API
> refactoring
>
>
>
> Qian,
>
>
>
> On 23 March 2016 at 02:18, Xu, Qian Q <qian.q.xu@intel.com> wrote:
>
> We have tested with intel nic and found port can't be started for all
> nics:ixgbe/i40e/igb/bonding, see attached mail for more details. Please
> check and fix it.
>
>
> Thanks
> Qian
>
>
> -----Original Message-----
> From: dev [mailto:dev-bounces@dpdk.org] On Behalf Of Thomas Monjalon
> Sent: Wednesday, March 23, 2016 3:59 AM
> To: Ananyev, Konstantin; Lu, Wenzhuo; Zhang, Helin
> Cc: marcdevel@gmail.com; Richardson, Bruce; dev@dpdk.org
> Subject: Re: [dpdk-dev] [PATCH v11 0/8] ethdev: 100G and link speed API
> refactoring
>
> 2016-03-17 19:08, Thomas Monjalon:
> > There are still too few tests and reviews, especially for
> > autonegotiation with Intel devices (patch #6).
> > I would not be surprised to see some bugs in this rework.
>
> Any feedback about autoneg in e1000/ixgbe/i40e?
> Has it been tested before its integration in RC2?
>
> > The capabilities must be adapted per device. It can be improved in a
> > separate patch.
> >
> > It will be integrated in 16.04-rc2.
> > Please test and review shortly, thanks!
>
>
>
> ---------- Forwarded message ----------
> From: "Xu, Qian Q" <qian.q.xu@intel.com>
> To: "Cao, Waterman" <waterman.cao@intel.com>, "Glynn, Michael J" <
> michael.j.glynn@intel.com>
> Cc: "Richardson, Bruce" <bruce.richardson@intel.com>, "Zhu, Heqing" <
> heqing.zhu@intel.com>, "O'Driscoll, Tim" <tim.odriscoll@intel.com>,
> "Mcnamara, John" <john.mcnamara@intel.com>, "Xu, HuilongX" <
> huilongx.xu@intel.com>, "Fu, JingguoX" <jingguox.fu@intel.com>, "Xu, Qian
> Q" <qian.q.xu@intel.com>, "Zhang, Helin" <helin.zhang@intel.com>
> Date: Tue, 22 Mar 2016 06:41:37 +0000
> Subject: RE: DPDK link speed with Intel devices
> Hi, all
> We have worked out the basic test cases for the patchset.
> 1. Test the link speed on major Intel NICs to see if the speed is right.
> 2. Test the auto-negoation on major Intel NICs to ensure it's working.
> Nic covered: ixgbe, igb, i40e, fm10k, bonding(SW), virtio(SW)
>
> When we run the Test#1 for all major NICs. We found that all these NIC
> port(igb, ixgbe, i40e, fm10k) can't be started. Pls check, if the patch is
> applied, all INTEL port can't be start, terrible things!
>
> Interactive-mode selected
> Configuring Port 0 (socket 0)
> PMD: ixgbe_dev_tx_queue_setup(): sw_ring=0x7f13e99e3440
> hw_ring=0x7f13e99e5480 dma_addr=0x8299e5480
> PMD: ixgbe_set_tx_function(): Using simple tx code path
> PMD: ixgbe_set_tx_function(): Vector tx enabled.
> PMD: ixgbe_dev_rx_queue_setup(): sw_ring=0x7f13ffcb8080
> sw_sc_ring=0x7f13ffcbaac0 hw_ring=0x7f13e99d3380 dma_addr=0x8299d3380
> PMD: ixgbe_dev_start(): Invalid link_speeds for port 0; autonegotiation
> disabled
> Fail to start port 0
> Configuring Port 1 (socket 0)
> PMD: i40e_set_tx_function_flag(): Vector tx can be enabled on this txq.
> PMD: i40e_dev_rx_queue_setup(): Rx Burst Bulk Alloc Preconditions are
> satisfied. Rx Burst Bulk Alloc function will be used on port=1, queue=0.
> PMD: i40e_dev_start(): Invalid link_speeds for port 1; autonegotiation
> disabled
>
>
>
>
>
> Just to double-check; is the test#1 adapted to the _new_ API that ethdev
> has to set link speeds? For the output it seems autoneg is disabled =>
> fixed speed, hence the new bitmaps have to be used.
>
>
>
> (I am not claiming patchset is bug free; there might be issues still)
>
>
>
> Regards
>
> marc
>
>
>
> Fail to start port 1
> Please stop the ports first
> Done
>
> Thanks
> Qian
>
>
> -----Original Message-----
> From: Cao, Waterman
> Sent: Tuesday, March 22, 2016 11:06 AM
> To: Glynn, Michael J
> Cc: Richardson, Bruce; Zhu, Heqing; O'Driscoll, Tim; Mcnamara, John; Xu,
> Qian Q; Cao, Waterman
> Subject: RE: DPDK link speed with Intel devices
>
> Hi Mike,
>
>         We just knew this patch set last week.
>         Since this patch set is required to test with a lot of NIC,  we
> need more document from Dev about this patch.
>         Currently, Qian is working on with Wenzhuo on it now.
>
> Waterman
>
>
> -----Original Message-----
> From: Glynn, Michael J
> Sent: Tuesday, March 22, 2016 1:31 AM
> To: Cao, Waterman <waterman.cao@intel.com>
> Cc: Richardson, Bruce <bruce.richardson@intel.com>; Zhu, Heqing <
> heqing.zhu@intel.com>; O'Driscoll, Tim <tim.odriscoll@intel.com>;
> Mcnamara, John <john.mcnamara@intel.com>
> Subject: FW: DPDK link speed with Intel devices
> Importance: High
>
> Hi Waterman, all
>
> See below - are you aware? And if so where are we with testing/resolution?
>
> Regards
> Mike
>
>
>
> -----Original Message-----
> From: Thomas Monjalon [mailto:thomas.monjalon@6wind.com]
> Sent: Monday, March 21, 2016 2:19 PM
> To: O'Driscoll, Tim <tim.odriscoll@intel.com>; Glynn, Michael J <
> michael.j.glynn@intel.com>; Zhu, Heqing <heqing.zhu@intel.com>
> Cc: vincent.jardin@6wind.com
> Subject: DPDK link speed with Intel devices
>
> Hi,
>
> We are still waiting for test feedbacks for this important patchset:
>         ethdev: 100G and link speed API refactoring It is possible that it
> breaks the autonegotiation in e1000/ixgbe/i40e.
>
> Thanks for taking care.
>
>
>

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

* Re: [PATCH v11 0/8] ethdev: 100G and link speed API refactoring
  2016-03-17 18:08           ` [PATCH v11 0/8] ethdev: 100G and link speed API refactoring Thomas Monjalon
                               ` (8 preceding siblings ...)
  2016-03-22 19:58             ` [PATCH v11 0/8] ethdev: 100G and link speed API refactoring Thomas Monjalon
@ 2016-03-24 17:32             ` Matej Vido
  2016-03-25 19:42             ` [PATCH v12 " Thomas Monjalon
  10 siblings, 0 replies; 167+ messages in thread
From: Matej Vido @ 2016-03-24 17:32 UTC (permalink / raw)
  To: Thomas Monjalon, marcdevel, bruce.richardson, declan.doherty,
	konstantin.ananyev, wenzhuo.lu, helin.zhang, jing.d.chen,
	harish.patil, rahul.lakkireddy, johndale, adrien.mazarguil,
	alejandro.lucero
  Cc: dev

Dňa 17.03.2016 o 19:08 Thomas Monjalon napísal(a):
> There are still too few tests and reviews, especially for
> autonegotiation with Intel devices (patch #6).
> I would not be surprised to see some bugs in this rework.
>
> The capabilities must be adapted per device. It can be
> improved in a separate patch.
>
> It will be integrated in 16.04-rc2.
> Please test and review shortly, thanks!
>
> [...]
Tested-by: Matej Vido <vido@cesnet.cz>

Correct speed is displayed for COMBO-100G card.

Regards,
Matej

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

* Re: [PATCH v11 0/8] ethdev: 100G and link speed API refactoring
  2016-03-24  7:47                     ` Marc
@ 2016-03-25  1:02                       ` Xu, Qian Q
  2016-03-25  9:35                         ` Thomas Monjalon
  0 siblings, 1 reply; 167+ messages in thread
From: Xu, Qian Q @ 2016-03-25  1:02 UTC (permalink / raw)
  To: Marc
  Cc: Thomas Monjalon, Ananyev, Konstantin, Lu, Wenzhuo, Zhang, Helin,
	Richardson, Bruce, dev

Marc
#Test1 is just a simple test. Just launch testpmd with these nic port.
./testpmd –c 0x3 –n 4 -- -i

Thanks
Qian

From: marc.sune@gmail.com [mailto:marc.sune@gmail.com] On Behalf Of Marc
Sent: Thursday, March 24, 2016 3:48 PM
To: Xu, Qian Q
Cc: Thomas Monjalon; Ananyev, Konstantin; Lu, Wenzhuo; Zhang, Helin; Richardson, Bruce; dev@dpdk.org
Subject: Re: [dpdk-dev] [PATCH v11 0/8] ethdev: 100G and link speed API refactoring



On 24 March 2016 at 07:21, Xu, Qian Q <qian.q.xu@intel.com<mailto:qian.q.xu@intel.com>> wrote:
Marc
I didn’t quite get your points, I observed that after applying this patchset, all intel nic can’t be started, maybe something wrong happened when you check the duplex/autoneg value for different NICs. If we want to merge the patchset in RC2, we need fix them. Maybe not an easy job in several days.

Is this test#1 one of the tests contained in the DPDK repository or is it an internal test?

Marc



Thanks
Qian

From: marc.sune@gmail.com<mailto:marc.sune@gmail.com> [mailto:marc.sune@gmail.com<mailto:marc.sune@gmail.com>] On Behalf Of Marc
Sent: Thursday, March 24, 2016 4:54 AM
To: Xu, Qian Q
Cc: Thomas Monjalon; Ananyev, Konstantin; Lu, Wenzhuo; Zhang, Helin; Richardson, Bruce; dev@dpdk.org<mailto:dev@dpdk.org>

Subject: Re: [dpdk-dev] [PATCH v11 0/8] ethdev: 100G and link speed API refactoring

Qian,

On 23 March 2016 at 02:18, Xu, Qian Q <qian.q.xu@intel.com<mailto:qian.q.xu@intel.com>> wrote:
We have tested with intel nic and found port can't be started for all nics:ixgbe/i40e/igb/bonding, see attached mail for more details. Please check and fix it.


Thanks
Qian

-----Original Message-----
From: dev [mailto:dev-bounces@dpdk.org<mailto:dev-bounces@dpdk.org>] On Behalf Of Thomas Monjalon
Sent: Wednesday, March 23, 2016 3:59 AM
To: Ananyev, Konstantin; Lu, Wenzhuo; Zhang, Helin
Cc: marcdevel@gmail.com<mailto:marcdevel@gmail.com>; Richardson, Bruce; dev@dpdk.org<mailto:dev@dpdk.org>
Subject: Re: [dpdk-dev] [PATCH v11 0/8] ethdev: 100G and link speed API refactoring

2016-03-17 19:08, Thomas Monjalon:
> There are still too few tests and reviews, especially for
> autonegotiation with Intel devices (patch #6).
> I would not be surprised to see some bugs in this rework.

Any feedback about autoneg in e1000/ixgbe/i40e?
Has it been tested before its integration in RC2?

> The capabilities must be adapted per device. It can be improved in a
> separate patch.
>
> It will be integrated in 16.04-rc2.
> Please test and review shortly, thanks!


---------- Forwarded message ----------
From: "Xu, Qian Q" <qian.q.xu@intel.com<mailto:qian.q.xu@intel.com>>
To: "Cao, Waterman" <waterman.cao@intel.com<mailto:waterman.cao@intel.com>>, "Glynn, Michael J" <michael.j.glynn@intel.com<mailto:michael.j.glynn@intel.com>>
Cc: "Richardson, Bruce" <bruce.richardson@intel.com<mailto:bruce.richardson@intel.com>>, "Zhu, Heqing" <heqing.zhu@intel.com<mailto:heqing.zhu@intel.com>>, "O'Driscoll, Tim" <tim.odriscoll@intel.com<mailto:tim.odriscoll@intel.com>>, "Mcnamara, John" <john.mcnamara@intel.com<mailto:john.mcnamara@intel.com>>, "Xu, HuilongX" <huilongx.xu@intel.com<mailto:huilongx.xu@intel.com>>, "Fu, JingguoX" <jingguox.fu@intel.com<mailto:jingguox.fu@intel.com>>, "Xu, Qian Q" <qian.q.xu@intel.com<mailto:qian.q.xu@intel.com>>, "Zhang, Helin" <helin.zhang@intel.com<mailto:helin.zhang@intel.com>>
Date: Tue, 22 Mar 2016 06:41:37 +0000
Subject: RE: DPDK link speed with Intel devices
Hi, all
We have worked out the basic test cases for the patchset.
1. Test the link speed on major Intel NICs to see if the speed is right.
2. Test the auto-negoation on major Intel NICs to ensure it's working.
Nic covered: ixgbe, igb, i40e, fm10k, bonding(SW), virtio(SW)

When we run the Test#1 for all major NICs. We found that all these NIC port(igb, ixgbe, i40e, fm10k) can't be started. Pls check, if the patch is applied, all INTEL port can't be start, terrible things!

Interactive-mode selected
Configuring Port 0 (socket 0)
PMD: ixgbe_dev_tx_queue_setup(): sw_ring=0x7f13e99e3440 hw_ring=0x7f13e99e5480 dma_addr=0x8299e5480
PMD: ixgbe_set_tx_function(): Using simple tx code path
PMD: ixgbe_set_tx_function(): Vector tx enabled.
PMD: ixgbe_dev_rx_queue_setup(): sw_ring=0x7f13ffcb8080 sw_sc_ring=0x7f13ffcbaac0 hw_ring=0x7f13e99d3380 dma_addr=0x8299d3380
PMD: ixgbe_dev_start(): Invalid link_speeds for port 0; autonegotiation disabled
Fail to start port 0
Configuring Port 1 (socket 0)
PMD: i40e_set_tx_function_flag(): Vector tx can be enabled on this txq.
PMD: i40e_dev_rx_queue_setup(): Rx Burst Bulk Alloc Preconditions are satisfied. Rx Burst Bulk Alloc function will be used on port=1, queue=0.
PMD: i40e_dev_start(): Invalid link_speeds for port 1; autonegotiation disabled


Just to double-check; is the test#1 adapted to the _new_ API that ethdev has to set link speeds? For the output it seems autoneg is disabled => fixed speed, hence the new bitmaps have to be used.

(I am not claiming patchset is bug free; there might be issues still)

Regards
marc

Fail to start port 1
Please stop the ports first
Done

Thanks
Qian


-----Original Message-----
From: Cao, Waterman
Sent: Tuesday, March 22, 2016 11:06 AM
To: Glynn, Michael J
Cc: Richardson, Bruce; Zhu, Heqing; O'Driscoll, Tim; Mcnamara, John; Xu, Qian Q; Cao, Waterman
Subject: RE: DPDK link speed with Intel devices

Hi Mike,

        We just knew this patch set last week.
        Since this patch set is required to test with a lot of NIC,  we need more document from Dev about this patch.
        Currently, Qian is working on with Wenzhuo on it now.

Waterman


-----Original Message-----
From: Glynn, Michael J
Sent: Tuesday, March 22, 2016 1:31 AM
To: Cao, Waterman <waterman.cao@intel.com<mailto:waterman.cao@intel.com>>
Cc: Richardson, Bruce <bruce.richardson@intel.com<mailto:bruce.richardson@intel.com>>; Zhu, Heqing <heqing.zhu@intel.com<mailto:heqing.zhu@intel.com>>; O'Driscoll, Tim <tim.odriscoll@intel.com<mailto:tim.odriscoll@intel.com>>; Mcnamara, John <john.mcnamara@intel.com<mailto:john.mcnamara@intel.com>>
Subject: FW: DPDK link speed with Intel devices
Importance: High

Hi Waterman, all

See below - are you aware? And if so where are we with testing/resolution?

Regards
Mike



-----Original Message-----
From: Thomas Monjalon [mailto:thomas.monjalon@6wind.com<mailto:thomas.monjalon@6wind.com>]
Sent: Monday, March 21, 2016 2:19 PM
To: O'Driscoll, Tim <tim.odriscoll@intel.com<mailto:tim.odriscoll@intel.com>>; Glynn, Michael J <michael.j.glynn@intel.com<mailto:michael.j.glynn@intel.com>>; Zhu, Heqing <heqing.zhu@intel.com<mailto:heqing.zhu@intel.com>>
Cc: vincent.jardin@6wind.com<mailto:vincent.jardin@6wind.com>
Subject: DPDK link speed with Intel devices

Hi,

We are still waiting for test feedbacks for this important patchset:
        ethdev: 100G and link speed API refactoring It is possible that it breaks the autonegotiation in e1000/ixgbe/i40e.

Thanks for taking care.



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

* Re: [PATCH v11 0/8] ethdev: 100G and link speed API refactoring
  2016-03-25  1:02                       ` Xu, Qian Q
@ 2016-03-25  9:35                         ` Thomas Monjalon
  2016-03-25 15:07                           ` Zhang, Helin
  0 siblings, 1 reply; 167+ messages in thread
From: Thomas Monjalon @ 2016-03-25  9:35 UTC (permalink / raw)
  To: Xu, Qian Q
  Cc: dev, Marc, Ananyev, Konstantin, Lu, Wenzhuo, Zhang, Helin,
	Richardson, Bruce, Glynn, Michael J

Is there someone investigating the issue?
I think it should be simple to fix for someone mastering these Intel drivers.

2016-03-25 01:02, Xu, Qian Q:
> Marc
> #Test1 is just a simple test. Just launch testpmd with these nic port.
> ./testpmd –c 0x3 –n 4 -- -i
> 
> Thanks
> Qian
> 
> From: marc.sune@gmail.com [mailto:marc.sune@gmail.com] On Behalf Of Marc
> Sent: Thursday, March 24, 2016 3:48 PM
> To: Xu, Qian Q
> Cc: Thomas Monjalon; Ananyev, Konstantin; Lu, Wenzhuo; Zhang, Helin; Richardson, Bruce; dev@dpdk.org
> Subject: Re: [dpdk-dev] [PATCH v11 0/8] ethdev: 100G and link speed API refactoring
> 
> 
> 
> On 24 March 2016 at 07:21, Xu, Qian Q <qian.q.xu@intel.com<mailto:qian.q.xu@intel.com>> wrote:
> Marc
> I didn’t quite get your points, I observed that after applying this patchset, all intel nic can’t be started, maybe something wrong happened when you check the duplex/autoneg value for different NICs. If we want to merge the patchset in RC2, we need fix them. Maybe not an easy job in several days.
> 
> Is this test#1 one of the tests contained in the DPDK repository or is it an internal test?
> 
> Marc
> 
> 
> 
> Thanks
> Qian
> 
> From: marc.sune@gmail.com<mailto:marc.sune@gmail.com> [mailto:marc.sune@gmail.com<mailto:marc.sune@gmail.com>] On Behalf Of Marc
> Sent: Thursday, March 24, 2016 4:54 AM
> To: Xu, Qian Q
> Cc: Thomas Monjalon; Ananyev, Konstantin; Lu, Wenzhuo; Zhang, Helin; Richardson, Bruce; dev@dpdk.org<mailto:dev@dpdk.org>
> 
> Subject: Re: [dpdk-dev] [PATCH v11 0/8] ethdev: 100G and link speed API refactoring
> 
> Qian,
> 
> On 23 March 2016 at 02:18, Xu, Qian Q <qian.q.xu@intel.com<mailto:qian.q.xu@intel.com>> wrote:
> We have tested with intel nic and found port can't be started for all nics:ixgbe/i40e/igb/bonding, see attached mail for more details. Please check and fix it.
> 
> 
> Thanks
> Qian
> 
> -----Original Message-----
> From: dev [mailto:dev-bounces@dpdk.org<mailto:dev-bounces@dpdk.org>] On Behalf Of Thomas Monjalon
> Sent: Wednesday, March 23, 2016 3:59 AM
> To: Ananyev, Konstantin; Lu, Wenzhuo; Zhang, Helin
> Cc: marcdevel@gmail.com<mailto:marcdevel@gmail.com>; Richardson, Bruce; dev@dpdk.org<mailto:dev@dpdk.org>
> Subject: Re: [dpdk-dev] [PATCH v11 0/8] ethdev: 100G and link speed API refactoring
> 
> 2016-03-17 19:08, Thomas Monjalon:
> > There are still too few tests and reviews, especially for
> > autonegotiation with Intel devices (patch #6).
> > I would not be surprised to see some bugs in this rework.
> 
> Any feedback about autoneg in e1000/ixgbe/i40e?
> Has it been tested before its integration in RC2?
> 
> > The capabilities must be adapted per device. It can be improved in a
> > separate patch.
> >
> > It will be integrated in 16.04-rc2.
> > Please test and review shortly, thanks!
> 
> 
> ---------- Forwarded message ----------
> From: "Xu, Qian Q" <qian.q.xu@intel.com<mailto:qian.q.xu@intel.com>>
> To: "Cao, Waterman" <waterman.cao@intel.com<mailto:waterman.cao@intel.com>>, "Glynn, Michael J" <michael.j.glynn@intel.com<mailto:michael.j.glynn@intel.com>>
> Cc: "Richardson, Bruce" <bruce.richardson@intel.com<mailto:bruce.richardson@intel.com>>, "Zhu, Heqing" <heqing.zhu@intel.com<mailto:heqing.zhu@intel.com>>, "O'Driscoll, Tim" <tim.odriscoll@intel.com<mailto:tim.odriscoll@intel.com>>, "Mcnamara, John" <john.mcnamara@intel.com<mailto:john.mcnamara@intel.com>>, "Xu, HuilongX" <huilongx.xu@intel.com<mailto:huilongx.xu@intel.com>>, "Fu, JingguoX" <jingguox.fu@intel.com<mailto:jingguox.fu@intel.com>>, "Xu, Qian Q" <qian.q.xu@intel.com<mailto:qian.q.xu@intel.com>>, "Zhang, Helin" <helin.zhang@intel.com<mailto:helin.zhang@intel.com>>
> Date: Tue, 22 Mar 2016 06:41:37 +0000
> Subject: RE: DPDK link speed with Intel devices
> Hi, all
> We have worked out the basic test cases for the patchset.
> 1. Test the link speed on major Intel NICs to see if the speed is right.
> 2. Test the auto-negoation on major Intel NICs to ensure it's working.
> Nic covered: ixgbe, igb, i40e, fm10k, bonding(SW), virtio(SW)
> 
> When we run the Test#1 for all major NICs. We found that all these NIC port(igb, ixgbe, i40e, fm10k) can't be started. Pls check, if the patch is applied, all INTEL port can't be start, terrible things!
> 
> Interactive-mode selected
> Configuring Port 0 (socket 0)
> PMD: ixgbe_dev_tx_queue_setup(): sw_ring=0x7f13e99e3440 hw_ring=0x7f13e99e5480 dma_addr=0x8299e5480
> PMD: ixgbe_set_tx_function(): Using simple tx code path
> PMD: ixgbe_set_tx_function(): Vector tx enabled.
> PMD: ixgbe_dev_rx_queue_setup(): sw_ring=0x7f13ffcb8080 sw_sc_ring=0x7f13ffcbaac0 hw_ring=0x7f13e99d3380 dma_addr=0x8299d3380
> PMD: ixgbe_dev_start(): Invalid link_speeds for port 0; autonegotiation disabled
> Fail to start port 0
> Configuring Port 1 (socket 0)
> PMD: i40e_set_tx_function_flag(): Vector tx can be enabled on this txq.
> PMD: i40e_dev_rx_queue_setup(): Rx Burst Bulk Alloc Preconditions are satisfied. Rx Burst Bulk Alloc function will be used on port=1, queue=0.
> PMD: i40e_dev_start(): Invalid link_speeds for port 1; autonegotiation disabled
> 
> 
> Just to double-check; is the test#1 adapted to the _new_ API that ethdev has to set link speeds? For the output it seems autoneg is disabled => fixed speed, hence the new bitmaps have to be used.
> 
> (I am not claiming patchset is bug free; there might be issues still)
> 
> Regards
> marc
> 
> Fail to start port 1
> Please stop the ports first
> Done
> 
> Thanks
> Qian
> 
> 
> -----Original Message-----
> From: Cao, Waterman
> Sent: Tuesday, March 22, 2016 11:06 AM
> To: Glynn, Michael J
> Cc: Richardson, Bruce; Zhu, Heqing; O'Driscoll, Tim; Mcnamara, John; Xu, Qian Q; Cao, Waterman
> Subject: RE: DPDK link speed with Intel devices
> 
> Hi Mike,
> 
>         We just knew this patch set last week.
>         Since this patch set is required to test with a lot of NIC,  we need more document from Dev about this patch.
>         Currently, Qian is working on with Wenzhuo on it now.
> 
> Waterman
> 
> 
> -----Original Message-----
> From: Glynn, Michael J
> Sent: Tuesday, March 22, 2016 1:31 AM
> To: Cao, Waterman <waterman.cao@intel.com<mailto:waterman.cao@intel.com>>
> Cc: Richardson, Bruce <bruce.richardson@intel.com<mailto:bruce.richardson@intel.com>>; Zhu, Heqing <heqing.zhu@intel.com<mailto:heqing.zhu@intel.com>>; O'Driscoll, Tim <tim.odriscoll@intel.com<mailto:tim.odriscoll@intel.com>>; Mcnamara, John <john.mcnamara@intel.com<mailto:john.mcnamara@intel.com>>
> Subject: FW: DPDK link speed with Intel devices
> Importance: High
> 
> Hi Waterman, all
> 
> See below - are you aware? And if so where are we with testing/resolution?
> 
> Regards
> Mike
> 
> 
> 
> -----Original Message-----
> From: Thomas Monjalon [mailto:thomas.monjalon@6wind.com<mailto:thomas.monjalon@6wind.com>]
> Sent: Monday, March 21, 2016 2:19 PM
> To: O'Driscoll, Tim <tim.odriscoll@intel.com<mailto:tim.odriscoll@intel.com>>; Glynn, Michael J <michael.j.glynn@intel.com<mailto:michael.j.glynn@intel.com>>; Zhu, Heqing <heqing.zhu@intel.com<mailto:heqing.zhu@intel.com>>
> Cc: vincent.jardin@6wind.com<mailto:vincent.jardin@6wind.com>
> Subject: DPDK link speed with Intel devices
> 
> Hi,
> 
> We are still waiting for test feedbacks for this important patchset:
>         ethdev: 100G and link speed API refactoring It is possible that it breaks the autonegotiation in e1000/ixgbe/i40e.
> 
> Thanks for taking care.
> 
> 

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

* Re: [PATCH v11 0/8] ethdev: 100G and link speed API refactoring
  2016-03-25  9:35                         ` Thomas Monjalon
@ 2016-03-25 15:07                           ` Zhang, Helin
  2016-03-25 15:32                             ` Thomas Monjalon
  2016-03-25 20:41                             ` Marc
  0 siblings, 2 replies; 167+ messages in thread
From: Zhang, Helin @ 2016-03-25 15:07 UTC (permalink / raw)
  To: Thomas Monjalon, Xu, Qian Q, Xing, Beilei
  Cc: dev, Marc, Ananyev, Konstantin, Lu, Wenzhuo, Richardson, Bruce,
	Glynn, Michael J

Hi Thomas

Beilei is investigating that, she will give her findings soon later, and possibly a fix after validating that.
Thanks!

Regards,
Helin

> -----Original Message-----
> From: Thomas Monjalon [mailto:thomas.monjalon@6wind.com]
> Sent: Friday, March 25, 2016 5:36 PM
> To: Xu, Qian Q <qian.q.xu@intel.com>
> Cc: dev@dpdk.org; Marc <marcdevel@gmail.com>; Ananyev, Konstantin
> <konstantin.ananyev@intel.com>; Lu, Wenzhuo <wenzhuo.lu@intel.com>;
> Zhang, Helin <helin.zhang@intel.com>; Richardson, Bruce
> <bruce.richardson@intel.com>; Glynn, Michael J <michael.j.glynn@intel.com>
> Subject: Re: [dpdk-dev] [PATCH v11 0/8] ethdev: 100G and link speed API
> refactoring
> 
> Is there someone investigating the issue?
> I think it should be simple to fix for someone mastering these Intel drivers.
> 
> 2016-03-25 01:02, Xu, Qian Q:
> > Marc
> > #Test1 is just a simple test. Just launch testpmd with these nic port.
> > ./testpmd –c 0x3 –n 4 -- -i
> >
> > Thanks
> > Qian
> >
> > From: marc.sune@gmail.com [mailto:marc.sune@gmail.com] On Behalf Of
> > Marc
> > Sent: Thursday, March 24, 2016 3:48 PM
> > To: Xu, Qian Q
> > Cc: Thomas Monjalon; Ananyev, Konstantin; Lu, Wenzhuo; Zhang, Helin;
> > Richardson, Bruce; dev@dpdk.org
> > Subject: Re: [dpdk-dev] [PATCH v11 0/8] ethdev: 100G and link speed
> > API refactoring
> >
> >
> >
> > On 24 March 2016 at 07:21, Xu, Qian Q
> <qian.q.xu@intel.com<mailto:qian.q.xu@intel.com>> wrote:
> > Marc
> > I didn’t quite get your points, I observed that after applying this patchset, all
> intel nic can’t be started, maybe something wrong happened when you check
> the duplex/autoneg value for different NICs. If we want to merge the patchset in
> RC2, we need fix them. Maybe not an easy job in several days.
> >
> > Is this test#1 one of the tests contained in the DPDK repository or is it an
> internal test?
> >
> > Marc
> >
> >
> >
> > Thanks
> > Qian
> >
> > From: marc.sune@gmail.com<mailto:marc.sune@gmail.com>
> > [mailto:marc.sune@gmail.com<mailto:marc.sune@gmail.com>] On Behalf Of
> > Marc
> > Sent: Thursday, March 24, 2016 4:54 AM
> > To: Xu, Qian Q
> > Cc: Thomas Monjalon; Ananyev, Konstantin; Lu, Wenzhuo; Zhang, Helin;
> > Richardson, Bruce; dev@dpdk.org<mailto:dev@dpdk.org>
> >
> > Subject: Re: [dpdk-dev] [PATCH v11 0/8] ethdev: 100G and link speed
> > API refactoring
> >
> > Qian,
> >
> > On 23 March 2016 at 02:18, Xu, Qian Q
> <qian.q.xu@intel.com<mailto:qian.q.xu@intel.com>> wrote:
> > We have tested with intel nic and found port can't be started for all
> nics:ixgbe/i40e/igb/bonding, see attached mail for more details. Please check
> and fix it.
> >
> >
> > Thanks
> > Qian
> >
> > -----Original Message-----
> > From: dev [mailto:dev-bounces@dpdk.org<mailto:dev-bounces@dpdk.org>]
> > On Behalf Of Thomas Monjalon
> > Sent: Wednesday, March 23, 2016 3:59 AM
> > To: Ananyev, Konstantin; Lu, Wenzhuo; Zhang, Helin
> > Cc: marcdevel@gmail.com<mailto:marcdevel@gmail.com>; Richardson,
> > Bruce; dev@dpdk.org<mailto:dev@dpdk.org>
> > Subject: Re: [dpdk-dev] [PATCH v11 0/8] ethdev: 100G and link speed
> > API refactoring
> >
> > 2016-03-17 19:08, Thomas Monjalon:
> > > There are still too few tests and reviews, especially for
> > > autonegotiation with Intel devices (patch #6).
> > > I would not be surprised to see some bugs in this rework.
> >
> > Any feedback about autoneg in e1000/ixgbe/i40e?
> > Has it been tested before its integration in RC2?
> >
> > > The capabilities must be adapted per device. It can be improved in a
> > > separate patch.
> > >
> > > It will be integrated in 16.04-rc2.
> > > Please test and review shortly, thanks!
> >
> >
> > ---------- Forwarded message ----------
> > From: "Xu, Qian Q" <qian.q.xu@intel.com<mailto:qian.q.xu@intel.com>>
> > To: "Cao, Waterman"
> > <waterman.cao@intel.com<mailto:waterman.cao@intel.com>>, "Glynn,
> > Michael J"
> > <michael.j.glynn@intel.com<mailto:michael.j.glynn@intel.com>>
> > Cc: "Richardson, Bruce"
> > <bruce.richardson@intel.com<mailto:bruce.richardson@intel.com>>, "Zhu,
> > Heqing" <heqing.zhu@intel.com<mailto:heqing.zhu@intel.com>>,
> > "O'Driscoll, Tim"
> > <tim.odriscoll@intel.com<mailto:tim.odriscoll@intel.com>>, "Mcnamara,
> > John" <john.mcnamara@intel.com<mailto:john.mcnamara@intel.com>>, "Xu,
> > HuilongX" <huilongx.xu@intel.com<mailto:huilongx.xu@intel.com>>, "Fu,
> > JingguoX" <jingguox.fu@intel.com<mailto:jingguox.fu@intel.com>>, "Xu,
> > Qian Q" <qian.q.xu@intel.com<mailto:qian.q.xu@intel.com>>, "Zhang,
> > Helin" <helin.zhang@intel.com<mailto:helin.zhang@intel.com>>
> > Date: Tue, 22 Mar 2016 06:41:37 +0000
> > Subject: RE: DPDK link speed with Intel devices Hi, all We have worked
> > out the basic test cases for the patchset.
> > 1. Test the link speed on major Intel NICs to see if the speed is right.
> > 2. Test the auto-negoation on major Intel NICs to ensure it's working.
> > Nic covered: ixgbe, igb, i40e, fm10k, bonding(SW), virtio(SW)
> >
> > When we run the Test#1 for all major NICs. We found that all these NIC port(igb,
> ixgbe, i40e, fm10k) can't be started. Pls check, if the patch is applied, all INTEL
> port can't be start, terrible things!
> >
> > Interactive-mode selected
> > Configuring Port 0 (socket 0)
> > PMD: ixgbe_dev_tx_queue_setup(): sw_ring=0x7f13e99e3440
> > hw_ring=0x7f13e99e5480 dma_addr=0x8299e5480
> > PMD: ixgbe_set_tx_function(): Using simple tx code path
> > PMD: ixgbe_set_tx_function(): Vector tx enabled.
> > PMD: ixgbe_dev_rx_queue_setup(): sw_ring=0x7f13ffcb8080
> > sw_sc_ring=0x7f13ffcbaac0 hw_ring=0x7f13e99d3380 dma_addr=0x8299d3380
> > PMD: ixgbe_dev_start(): Invalid link_speeds for port 0;
> > autonegotiation disabled Fail to start port 0 Configuring Port 1
> > (socket 0)
> > PMD: i40e_set_tx_function_flag(): Vector tx can be enabled on this txq.
> > PMD: i40e_dev_rx_queue_setup(): Rx Burst Bulk Alloc Preconditions are
> satisfied. Rx Burst Bulk Alloc function will be used on port=1, queue=0.
> > PMD: i40e_dev_start(): Invalid link_speeds for port 1; autonegotiation
> > disabled
> >
> >
> > Just to double-check; is the test#1 adapted to the _new_ API that ethdev has
> to set link speeds? For the output it seems autoneg is disabled => fixed speed,
> hence the new bitmaps have to be used.
> >
> > (I am not claiming patchset is bug free; there might be issues still)
> >
> > Regards
> > marc
> >
> > Fail to start port 1
> > Please stop the ports first
> > Done
> >
> > Thanks
> > Qian
> >
> >
> > -----Original Message-----
> > From: Cao, Waterman
> > Sent: Tuesday, March 22, 2016 11:06 AM
> > To: Glynn, Michael J
> > Cc: Richardson, Bruce; Zhu, Heqing; O'Driscoll, Tim; Mcnamara, John;
> > Xu, Qian Q; Cao, Waterman
> > Subject: RE: DPDK link speed with Intel devices
> >
> > Hi Mike,
> >
> >         We just knew this patch set last week.
> >         Since this patch set is required to test with a lot of NIC,  we need
> more document from Dev about this patch.
> >         Currently, Qian is working on with Wenzhuo on it now.
> >
> > Waterman
> >
> >
> > -----Original Message-----
> > From: Glynn, Michael J
> > Sent: Tuesday, March 22, 2016 1:31 AM
> > To: Cao, Waterman
> > <waterman.cao@intel.com<mailto:waterman.cao@intel.com>>
> > Cc: Richardson, Bruce
> > <bruce.richardson@intel.com<mailto:bruce.richardson@intel.com>>; Zhu,
> > Heqing <heqing.zhu@intel.com<mailto:heqing.zhu@intel.com>>;
> > O'Driscoll, Tim
> > <tim.odriscoll@intel.com<mailto:tim.odriscoll@intel.com>>; Mcnamara,
> > John <john.mcnamara@intel.com<mailto:john.mcnamara@intel.com>>
> > Subject: FW: DPDK link speed with Intel devices
> > Importance: High
> >
> > Hi Waterman, all
> >
> > See below - are you aware? And if so where are we with testing/resolution?
> >
> > Regards
> > Mike
> >
> >
> >
> > -----Original Message-----
> > From: Thomas Monjalon
> >
> [mailto:thomas.monjalon@6wind.com<mailto:thomas.monjalon@6wind.com>]
> > Sent: Monday, March 21, 2016 2:19 PM
> > To: O'Driscoll, Tim
> > <tim.odriscoll@intel.com<mailto:tim.odriscoll@intel.com>>; Glynn,
> > Michael J
> > <michael.j.glynn@intel.com<mailto:michael.j.glynn@intel.com>>; Zhu,
> > Heqing <heqing.zhu@intel.com<mailto:heqing.zhu@intel.com>>
> > Cc: vincent.jardin@6wind.com<mailto:vincent.jardin@6wind.com>
> > Subject: DPDK link speed with Intel devices
> >
> > Hi,
> >
> > We are still waiting for test feedbacks for this important patchset:
> >         ethdev: 100G and link speed API refactoring It is possible that it
> breaks the autonegotiation in e1000/ixgbe/i40e.
> >
> > Thanks for taking care.
> >
> >
> 


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

* Re: [PATCH v11 0/8] ethdev: 100G and link speed API refactoring
  2016-03-25 15:07                           ` Zhang, Helin
@ 2016-03-25 15:32                             ` Thomas Monjalon
  2016-03-25 20:41                             ` Marc
  1 sibling, 0 replies; 167+ messages in thread
From: Thomas Monjalon @ 2016-03-25 15:32 UTC (permalink / raw)
  To: Zhang, Helin, Xing, Beilei
  Cc: Xu, Qian Q, dev, Marc, Ananyev, Konstantin, Lu, Wenzhuo,
	Richardson, Bruce, Glynn, Michael J

2016-03-25 15:07, Zhang, Helin:
> From: Thomas Monjalon
> > Is there someone investigating the issue?
> 
> Beilei is investigating that, she will give her findings soon later, and possibly a fix after validating that.
> Thanks!

Great thanks!
After talking with Bruce, we have decided to close RC2 without this patch
and make it a prerequisite for RC3.

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

* [PATCH v12 0/8] ethdev: 100G and link speed API refactoring
  2016-03-17 18:08           ` [PATCH v11 0/8] ethdev: 100G and link speed API refactoring Thomas Monjalon
                               ` (9 preceding siblings ...)
  2016-03-24 17:32             ` Matej Vido
@ 2016-03-25 19:42             ` Thomas Monjalon
  2016-03-25 19:42               ` [PATCH v12 1/8] ethdev: use constants for link state Thomas Monjalon
                                 ` (8 more replies)
  10 siblings, 9 replies; 167+ messages in thread
From: Thomas Monjalon @ 2016-03-25 19:42 UTC (permalink / raw)
  To: marcdevel, bruce.richardson, declan.doherty, konstantin.ananyev,
	wenzhuo.lu, helin.zhang, jing.d.chen, harish.patil,
	rahul.lakkireddy, johndale, vido, adrien.mazarguil,
	alejandro.lucero
  Cc: dev

There are still too few tests and reviews, especially for
autonegotiation with Intel devices (patch #6).
I would not be surprised to see some bugs in this rework.

The capabilities must be adapted per device. It can be
improved in a separate patch.

It will be integrated in 16.04-rc3.
Please test and review shortly, thanks!

--------

This series of patches adds the following capabilities:

* speed_capa bitmap in rte_eth_dev_info, which is filled by the PMDs
  according to the physical device capabilities.
* refactors link API in ethdev to allow the definition of the advertised
  link speeds, fix speed (no auto-negociation) or advertise all supported
  speeds (default).

--------

v12:
    - rebase on 16.04-rc2
    - fix mlx capabilities
    - update ENA driver

v11:
    - rebase on 16.04-rc1
    - replace on more link status value in e1000 driver
    - merge szedata2 patches
    - remove szedata2 temporary comments in code and doc

v10:
    - rebase
    - rework release notes
    - rearrange patch splitting
    - fix doxygen comments
    - fix typos
    - removed log format of link.link_speed as %d (keep %u)
    - complete ETH_LINK_[DOWN/UP] replacement from 0/1
    - change ETH_LINK_SPEED_AUTONEG to 1
    - replace ETH_LINK_SPEED_NEG by ETH_LINK_SPEED_AUTONEG (1)
    - replace ETH_LINK_SPEED_NO_AUTONEG by ETH_LINK_SPEED_FIXED (0)
    - rework rte_eth_speed_to_bm_flag to rte_eth_speed_bitflag
    - complete 100G support in testpmd

v9: rebased to current HEAD. Reverted numeric speed to 32 bit in struct
    rte_eth_link (no atomic link get > 64bit). Fixed mlx5 driver compilation
    and link speeds. Moved documentation to release_16_04.rst and fixed several
    issues. Upgrade NIC notes with speed capabilities.

v8: Rebased to current HEAD. Modified em driver impl. to not touch base files.
    Merged patch 5 into 3 (map file). Changed numeric speed to a 64 bit value.
    Filled-in speed capabilities for drivers bnx2x, cxgbe, mlx5 and nfp in
    addition to the ones of previous patch sets.

v7: Rebased to current HEAD. Moved documentation to v2.3. Still needs testing
    from PMD maintainers.

v6: Move link_duplex to be part of bitfield. Fixed i40 autoneg flag link
    update code. Added rte_eth_speed_to_bm_flag() to .map file. Fixed other
    spelling issues. Rebased to current HEAD.

v5: revert to v2 speed capabilities patch. Fixed MLX4 speed capabilities
    (thanks N. Laranjeiro). Refactored link speed API to allow setting
    advertised speeds (3/4). Added NO_AUTONEG option to explicitely disable
    auto-negociation. Updated 2.2 rel. notes (4/4). Rebased to current HEAD.

v4: fixed errata in the documentation of field speeds of rte_eth_conf, and
    commit 1/2 message. rebased to v2.1.0. v3 was incorrectly based on
    ~2.1.0-rc1.

v3: rebase to v2.1. unified ETH_LINK_SPEED and ETH_SPEED_CAP into ETH_SPEED.
    Converted field speed in struct rte_eth_conf to speed, to allow a bitmap
    for defining the announced speeds, as suggested M. Brorup. Fixed spelling
    issues.

v2: rebase, converted speed_capa into 32 bits bitmap, fixed alignment
    (checkpatch).

--------

Mare Sune (6):
  ethdev: use constants for link duplex
  app/testpmd: move speed and duplex parsing in a function
  ethdev: rename link speed constants
  ethdev: add speed capabilities
  ethdev: redesign link speed config
  ethdev: convert speed number to bitmap flag

Thomas Monjalon (2):
  ethdev: use constants for link state
  ethdev: add 100G link speed

 app/test-pipeline/init.c                           |   2 +-
 app/test-pmd/cmdline.c                             | 125 ++++++++++-----------
 app/test-pmd/testpmd.c                             |   2 +-
 app/test/test_pmd_perf.c                           |   2 +-
 app/test/virtual_pmd.c                             |   8 +-
 doc/guides/nics/overview.rst                       |   1 +
 doc/guides/nics/szedata2.rst                       |   6 -
 doc/guides/rel_notes/deprecation.rst               |   3 -
 doc/guides/rel_notes/release_16_04.rst             |  22 ++++
 doc/guides/testpmd_app_ug/testpmd_funcs.rst        |   2 +-
 drivers/net/af_packet/rte_eth_af_packet.c          |   9 +-
 drivers/net/bnx2x/bnx2x_ethdev.c                   |   7 +-
 drivers/net/bnx2x/elink.c                          |   2 +-
 drivers/net/bonding/rte_eth_bond_8023ad.c          |  14 +--
 drivers/net/bonding/rte_eth_bond_api.c             |   4 +-
 drivers/net/bonding/rte_eth_bond_pmd.c             |  12 +-
 drivers/net/cxgbe/base/t4_hw.c                     |   8 +-
 drivers/net/cxgbe/cxgbe_ethdev.c                   |   1 +
 drivers/net/e1000/em_ethdev.c                      | 113 +++++++++----------
 drivers/net/e1000/igb_ethdev.c                     | 104 +++++++++--------
 drivers/net/ena/ena_ethdev.c                       |  12 +-
 drivers/net/fm10k/fm10k_ethdev.c                   |   6 +-
 drivers/net/i40e/i40e_ethdev.c                     |  76 +++++++------
 drivers/net/i40e/i40e_ethdev_vf.c                  |  11 +-
 drivers/net/ixgbe/ixgbe_ethdev.c                   |  76 ++++++-------
 drivers/net/mlx4/mlx4.c                            |   8 ++
 drivers/net/mlx5/mlx5_ethdev.c                     |   9 ++
 drivers/net/mpipe/mpipe_tilegx.c                   |  18 +--
 drivers/net/nfp/nfp_net.c                          |   6 +-
 drivers/net/null/rte_eth_null.c                    |   9 +-
 drivers/net/pcap/rte_eth_pcap.c                    |   9 +-
 drivers/net/ring/rte_eth_ring.c                    |  13 ++-
 drivers/net/szedata2/rte_eth_szedata2.c            |  19 ++--
 drivers/net/vhost/rte_eth_vhost.c                  |   6 +-
 drivers/net/virtio/virtio_ethdev.c                 |   8 +-
 drivers/net/virtio/virtio_ethdev.h                 |   2 -
 drivers/net/vmxnet3/vmxnet3_ethdev.c               |   5 +-
 drivers/net/xenvirt/rte_eth_xenvirt.c              |   9 +-
 examples/exception_path/main.c                     |   2 +-
 examples/ip_fragmentation/main.c                   |   2 +-
 examples/ip_pipeline/config_parse.c                |   3 +-
 examples/ip_pipeline/init.c                        |   2 +-
 examples/ip_reassembly/main.c                      |   2 +-
 examples/ipsec-secgw/ipsec-secgw.c                 |   2 +-
 examples/ipv4_multicast/main.c                     |   2 +-
 examples/kni/main.c                                |   2 +-
 examples/l2fwd-crypto/main.c                       |   2 +-
 examples/l2fwd-ivshmem/host/host.c                 |   2 +-
 examples/l2fwd-jobstats/main.c                     |   2 +-
 examples/l2fwd-keepalive/main.c                    |   2 +-
 examples/l2fwd/main.c                              |   2 +-
 examples/l3fwd-acl/main.c                          |   2 +-
 examples/l3fwd-power/main.c                        |   2 +-
 examples/l3fwd/main.c                              |   2 +-
 examples/link_status_interrupt/main.c              |   2 +-
 examples/load_balancer/init.c                      |   2 +-
 .../client_server_mp/mp_server/init.c              |   2 +-
 examples/multi_process/l2fwd_fork/main.c           |   2 +-
 examples/multi_process/symmetric_mp/main.c         |   2 +-
 examples/performance-thread/l3fwd-thread/main.c    |   2 +-
 lib/librte_ether/rte_ethdev.c                      |  33 ++++++
 lib/librte_ether/rte_ethdev.h                      |  91 +++++++++++----
 lib/librte_ether/rte_ether_version.map             |   1 +
 63 files changed, 532 insertions(+), 387 deletions(-)

-- 
2.7.0

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

* [PATCH v12 1/8] ethdev: use constants for link state
  2016-03-25 19:42             ` [PATCH v12 " Thomas Monjalon
@ 2016-03-25 19:42               ` Thomas Monjalon
  2016-03-25 19:42               ` [PATCH v12 2/8] ethdev: use constants for link duplex Thomas Monjalon
                                 ` (7 subsequent siblings)
  8 siblings, 0 replies; 167+ messages in thread
From: Thomas Monjalon @ 2016-03-25 19:42 UTC (permalink / raw)
  To: marcdevel, bruce.richardson, declan.doherty, konstantin.ananyev,
	wenzhuo.lu, helin.zhang, jing.d.chen, harish.patil,
	rahul.lakkireddy, johndale, vido, adrien.mazarguil,
	alejandro.lucero
  Cc: dev

Define and use ETH_LINK_UP and ETH_LINK_DOWN where appropriate.

Signed-off-by: Marc Sune <marcdevel@gmail.com>
Signed-off-by: Thomas Monjalon <thomas.monjalon@6wind.com>
---
 app/test-pipeline/init.c                                 |  2 +-
 app/test-pmd/testpmd.c                                   |  2 +-
 app/test/test_pmd_perf.c                                 |  2 +-
 app/test/virtual_pmd.c                                   |  6 +++---
 drivers/net/af_packet/rte_eth_af_packet.c                |  6 +++---
 drivers/net/bnx2x/bnx2x_ethdev.c                         |  2 +-
 drivers/net/bnx2x/elink.c                                |  2 +-
 drivers/net/bonding/rte_eth_bond_api.c                   |  4 ++--
 drivers/net/bonding/rte_eth_bond_pmd.c                   | 12 ++++++------
 drivers/net/e1000/em_ethdev.c                            |  8 ++++----
 drivers/net/e1000/igb_ethdev.c                           |  4 ++--
 drivers/net/fm10k/fm10k_ethdev.c                         |  2 +-
 drivers/net/i40e/i40e_ethdev_vf.c                        |  2 +-
 drivers/net/ixgbe/ixgbe_ethdev.c                         |  4 ++--
 drivers/net/mpipe/mpipe_tilegx.c                         | 12 ++++++------
 drivers/net/nfp/nfp_net.c                                |  2 +-
 drivers/net/null/rte_eth_null.c                          |  6 +++---
 drivers/net/pcap/rte_eth_pcap.c                          |  6 +++---
 drivers/net/ring/rte_eth_ring.c                          | 10 +++++-----
 drivers/net/szedata2/rte_eth_szedata2.c                  |  2 +-
 drivers/net/vhost/rte_eth_vhost.c                        |  6 +++---
 drivers/net/virtio/virtio_ethdev.c                       |  6 +++---
 drivers/net/vmxnet3/vmxnet3_ethdev.c                     |  2 +-
 drivers/net/xenvirt/rte_eth_xenvirt.c                    |  6 +++---
 examples/exception_path/main.c                           |  2 +-
 examples/ip_fragmentation/main.c                         |  2 +-
 examples/ip_pipeline/init.c                              |  2 +-
 examples/ip_reassembly/main.c                            |  2 +-
 examples/ipsec-secgw/ipsec-secgw.c                       |  2 +-
 examples/ipv4_multicast/main.c                           |  2 +-
 examples/kni/main.c                                      |  2 +-
 examples/l2fwd-crypto/main.c                             |  2 +-
 examples/l2fwd-ivshmem/host/host.c                       |  2 +-
 examples/l2fwd-jobstats/main.c                           |  2 +-
 examples/l2fwd-keepalive/main.c                          |  2 +-
 examples/l2fwd/main.c                                    |  2 +-
 examples/l3fwd-acl/main.c                                |  2 +-
 examples/l3fwd-power/main.c                              |  2 +-
 examples/l3fwd/main.c                                    |  2 +-
 examples/link_status_interrupt/main.c                    |  2 +-
 examples/load_balancer/init.c                            |  2 +-
 examples/multi_process/client_server_mp/mp_server/init.c |  2 +-
 examples/multi_process/l2fwd_fork/main.c                 |  2 +-
 examples/multi_process/symmetric_mp/main.c               |  2 +-
 examples/performance-thread/l3fwd-thread/main.c          |  2 +-
 lib/librte_ether/rte_ethdev.h                            |  5 ++++-
 46 files changed, 83 insertions(+), 80 deletions(-)

diff --git a/app/test-pipeline/init.c b/app/test-pipeline/init.c
index db2196b..aef082f 100644
--- a/app/test-pipeline/init.c
+++ b/app/test-pipeline/init.c
@@ -205,7 +205,7 @@ app_ports_check_link(void)
 			link.link_speed / 1000,
 			link.link_status ? "UP" : "DOWN");
 
-		if (link.link_status == 0)
+		if (link.link_status == ETH_LINK_DOWN)
 			all_ports_up = 0;
 	}
 
diff --git a/app/test-pmd/testpmd.c b/app/test-pmd/testpmd.c
index 8605e62..1398c6c 100644
--- a/app/test-pmd/testpmd.c
+++ b/app/test-pmd/testpmd.c
@@ -1641,7 +1641,7 @@ check_all_ports_link_status(uint32_t port_mask)
 				continue;
 			}
 			/* clear all_ports_up flag if any link down */
-			if (link.link_status == 0) {
+			if (link.link_status == ETH_LINK_DOWN) {
 				all_ports_up = 0;
 				break;
 			}
diff --git a/app/test/test_pmd_perf.c b/app/test/test_pmd_perf.c
index 48e16c9..59803f7 100644
--- a/app/test/test_pmd_perf.c
+++ b/app/test/test_pmd_perf.c
@@ -192,7 +192,7 @@ check_all_ports_link_status(uint8_t port_num, uint32_t port_mask)
 				continue;
 			}
 			/* clear all_ports_up flag if any link down */
-			if (link.link_status == 0) {
+			if (link.link_status == ETH_LINK_DOWN) {
 				all_ports_up = 0;
 				break;
 			}
diff --git a/app/test/virtual_pmd.c b/app/test/virtual_pmd.c
index a538c8a..b1d40d7 100644
--- a/app/test/virtual_pmd.c
+++ b/app/test/virtual_pmd.c
@@ -79,7 +79,7 @@ static void  virtual_ethdev_stop(struct rte_eth_dev *eth_dev __rte_unused)
 	void *pkt = NULL;
 	struct virtual_ethdev_private *prv = eth_dev->data->dev_private;
 
-	eth_dev->data->dev_link.link_status = 0;
+	eth_dev->data->dev_link.link_status = ETH_LINK_DOWN;
 	eth_dev->data->dev_started = 0;
 	while (rte_ring_dequeue(prv->rx_queue, &pkt) != -ENOENT)
 		rte_pktmbuf_free(pkt);
@@ -199,7 +199,7 @@ virtual_ethdev_link_update_success(struct rte_eth_dev *bonded_eth_dev,
 		int wait_to_complete __rte_unused)
 {
 	if (!bonded_eth_dev->data->dev_started)
-		bonded_eth_dev->data->dev_link.link_status = 0;
+		bonded_eth_dev->data->dev_link.link_status = ETH_LINK_DOWN;
 
 	return 0;
 }
@@ -603,7 +603,7 @@ virtual_ethdev_create(const char *name, struct ether_addr *mac_addr,
 
 	TAILQ_INIT(&(eth_dev->link_intr_cbs));
 
-	eth_dev->data->dev_link.link_status = 0;
+	eth_dev->data->dev_link.link_status = ETH_LINK_DOWN;
 	eth_dev->data->dev_link.link_speed = ETH_LINK_SPEED_10000;
 	eth_dev->data->dev_link.link_duplex = ETH_LINK_FULL_DUPLEX;
 
diff --git a/drivers/net/af_packet/rte_eth_af_packet.c b/drivers/net/af_packet/rte_eth_af_packet.c
index 5544528..dee7b59 100644
--- a/drivers/net/af_packet/rte_eth_af_packet.c
+++ b/drivers/net/af_packet/rte_eth_af_packet.c
@@ -118,7 +118,7 @@ static const char *drivername = "AF_PACKET PMD";
 static struct rte_eth_link pmd_link = {
 	.link_speed = 10000,
 	.link_duplex = ETH_LINK_FULL_DUPLEX,
-	.link_status = 0
+	.link_status = ETH_LINK_DOWN,
 };
 
 static uint16_t
@@ -234,7 +234,7 @@ eth_af_packet_tx(void *queue, struct rte_mbuf **bufs, uint16_t nb_pkts)
 static int
 eth_dev_start(struct rte_eth_dev *dev)
 {
-	dev->data->dev_link.link_status = 1;
+	dev->data->dev_link.link_status = ETH_LINK_UP;
 	return 0;
 }
 
@@ -257,7 +257,7 @@ eth_dev_stop(struct rte_eth_dev *dev)
 			close(sockfd);
 	}
 
-	dev->data->dev_link.link_status = 0;
+	dev->data->dev_link.link_status = ETH_LINK_DOWN;
 }
 
 static int
diff --git a/drivers/net/bnx2x/bnx2x_ethdev.c b/drivers/net/bnx2x/bnx2x_ethdev.c
index 7e5be08..a3c6c01 100644
--- a/drivers/net/bnx2x/bnx2x_ethdev.c
+++ b/drivers/net/bnx2x/bnx2x_ethdev.c
@@ -266,7 +266,7 @@ bnx2xvf_dev_link_update(struct rte_eth_dev *dev, __rte_unused int wait_to_comple
 	if (sc->old_bulletin.valid_bitmap & (1 << CHANNEL_DOWN)) {
 		PMD_DRV_LOG(ERR, "PF indicated channel is down."
 				"VF device is no longer operational");
-		dev->data->dev_link.link_status = 0;
+		dev->data->dev_link.link_status = ETH_LINK_DOWN;
 	}
 
 	return old_link_status == dev->data->dev_link.link_status ? -1 : 0;
diff --git a/drivers/net/bnx2x/elink.c b/drivers/net/bnx2x/elink.c
index da2366e..b9149b8 100644
--- a/drivers/net/bnx2x/elink.c
+++ b/drivers/net/bnx2x/elink.c
@@ -6312,7 +6312,7 @@ elink_status_t elink_link_update(struct elink_params * params,
 	for (phy_index = ELINK_INT_PHY; phy_index < params->num_phys;
 	     phy_index++) {
 		phy_vars[phy_index].flow_ctrl = 0;
-		phy_vars[phy_index].link_status = 0;
+		phy_vars[phy_index].link_status = ETH_LINK_DOWN;
 		phy_vars[phy_index].line_speed = 0;
 		phy_vars[phy_index].duplex = DUPLEX_FULL;
 		phy_vars[phy_index].phy_link_up = 0;
diff --git a/drivers/net/bonding/rte_eth_bond_api.c b/drivers/net/bonding/rte_eth_bond_api.c
index d473ac2..e9247b5 100644
--- a/drivers/net/bonding/rte_eth_bond_api.c
+++ b/drivers/net/bonding/rte_eth_bond_api.c
@@ -205,7 +205,7 @@ rte_eth_bond_create(const char *name, uint8_t mode, uint8_t socket_id)
 
 	TAILQ_INIT(&(eth_dev->link_intr_cbs));
 
-	eth_dev->data->dev_link.link_status = 0;
+	eth_dev->data->dev_link.link_status = ETH_LINK_DOWN;
 
 	eth_dev->data->mac_addrs = rte_zmalloc_socket(name, ETHER_ADDR_LEN, 0,
 			socket_id);
@@ -420,7 +420,7 @@ __eth_bond_slave_add_lock_free(uint8_t bonded_port_id, uint8_t slave_port_id)
 	if (bonded_eth_dev->data->dev_started) {
 		rte_eth_link_get_nowait(slave_port_id, &link_props);
 
-		 if (link_props.link_status == 1) {
+		 if (link_props.link_status == ETH_LINK_UP) {
 			if (internals->active_slave_count == 0 &&
 			    !internals->user_defined_primary_port)
 				bond_ethdev_primary_set(internals,
diff --git a/drivers/net/bonding/rte_eth_bond_pmd.c b/drivers/net/bonding/rte_eth_bond_pmd.c
index fb26d35..684f285 100644
--- a/drivers/net/bonding/rte_eth_bond_pmd.c
+++ b/drivers/net/bonding/rte_eth_bond_pmd.c
@@ -1506,7 +1506,7 @@ bond_ethdev_start(struct rte_eth_dev *eth_dev)
 		return -1;
 	}
 
-	eth_dev->data->dev_link.link_status = 0;
+	eth_dev->data->dev_link.link_status = ETH_LINK_DOWN;
 	eth_dev->data->dev_started = 1;
 
 	internals = eth_dev->data->dev_private;
@@ -1623,7 +1623,7 @@ bond_ethdev_stop(struct rte_eth_dev *eth_dev)
 	internals->active_slave_count = 0;
 	internals->link_status_polling_enabled = 0;
 
-	eth_dev->data->dev_link.link_status = 0;
+	eth_dev->data->dev_link.link_status = ETH_LINK_DOWN;
 	eth_dev->data->dev_started = 0;
 }
 
@@ -1789,7 +1789,7 @@ bond_ethdev_link_update(struct rte_eth_dev *bonded_eth_dev,
 
 	if (!bonded_eth_dev->data->dev_started ||
 		internals->active_slave_count == 0) {
-		bonded_eth_dev->data->dev_link.link_status = 0;
+		bonded_eth_dev->data->dev_link.link_status = ETH_LINK_DOWN;
 		return 0;
 	} else {
 		struct rte_eth_dev *slave_eth_dev;
@@ -1800,7 +1800,7 @@ bond_ethdev_link_update(struct rte_eth_dev *bonded_eth_dev,
 
 			(*slave_eth_dev->dev_ops->link_update)(slave_eth_dev,
 					wait_to_complete);
-			if (slave_eth_dev->data->dev_link.link_status == 1) {
+			if (slave_eth_dev->data->dev_link.link_status == ETH_LINK_UP) {
 				link_up = 1;
 				break;
 			}
@@ -1969,7 +1969,7 @@ bond_ethdev_lsc_event_callback(uint8_t port_id, enum rte_eth_event_type type,
 		/* if no active slave ports then set this port to be primary port */
 		if (internals->active_slave_count < 1) {
 			/* If first active slave, then change link status */
-			bonded_eth_dev->data->dev_link.link_status = 1;
+			bonded_eth_dev->data->dev_link.link_status = ETH_LINK_UP;
 			internals->current_primary_port = port_id;
 			lsc_flag = 1;
 
@@ -1997,7 +1997,7 @@ bond_ethdev_lsc_event_callback(uint8_t port_id, enum rte_eth_event_type type,
 		 * link properties */
 		if (internals->active_slave_count < 1) {
 			lsc_flag = 1;
-			bonded_eth_dev->data->dev_link.link_status = 0;
+			bonded_eth_dev->data->dev_link.link_status = ETH_LINK_DOWN;
 
 			link_properties_reset(bonded_eth_dev);
 		}
diff --git a/drivers/net/e1000/em_ethdev.c b/drivers/net/e1000/em_ethdev.c
index 1f0a7f4..dc9ed38 100644
--- a/drivers/net/e1000/em_ethdev.c
+++ b/drivers/net/e1000/em_ethdev.c
@@ -1101,14 +1101,14 @@ eth_em_link_update(struct rte_eth_dev *dev, int wait_to_complete)
 	old = link;
 
 	/* Now we check if a transition has happened */
-	if (link_check && (link.link_status == 0)) {
+	if (link_check && (link.link_status == ETH_LINK_DOWN)) {
 		hw->mac.ops.get_link_up_info(hw, &link.link_speed,
 			&link.link_duplex);
-		link.link_status = 1;
-	} else if (!link_check && (link.link_status == 1)) {
+		link.link_status = ETH_LINK_UP;
+	} else if (!link_check && (link.link_status == ETH_LINK_UP)) {
 		link.link_speed = 0;
 		link.link_duplex = 0;
-		link.link_status = 0;
+		link.link_status = ETH_LINK_DOWN;
 	}
 	rte_em_dev_atomic_write_link_status(dev, &link);
 
diff --git a/drivers/net/e1000/igb_ethdev.c b/drivers/net/e1000/igb_ethdev.c
index bd0ae26..045fc63 100644
--- a/drivers/net/e1000/igb_ethdev.c
+++ b/drivers/net/e1000/igb_ethdev.c
@@ -2059,11 +2059,11 @@ eth_igb_link_update(struct rte_eth_dev *dev, int wait_to_complete)
 	if (link_check) {
 		hw->mac.ops.get_link_up_info(hw, &link.link_speed,
 					  &link.link_duplex);
-		link.link_status = 1;
+		link.link_status = ETH_LINK_UP;
 	} else if (!link_check) {
 		link.link_speed = 0;
 		link.link_duplex = 0;
-		link.link_status = 0;
+		link.link_status = ETH_LINK_DOWN;
 	}
 	rte_igb_dev_atomic_write_link_status(dev, &link);
 
diff --git a/drivers/net/fm10k/fm10k_ethdev.c b/drivers/net/fm10k/fm10k_ethdev.c
index b510487..53aa1bb 100644
--- a/drivers/net/fm10k/fm10k_ethdev.c
+++ b/drivers/net/fm10k/fm10k_ethdev.c
@@ -1249,7 +1249,7 @@ fm10k_link_update(struct rte_eth_dev *dev,
 	 * is no 50Gbps Ethernet. */
 	dev->data->dev_link.link_speed  = 0;
 	dev->data->dev_link.link_duplex = ETH_LINK_FULL_DUPLEX;
-	dev->data->dev_link.link_status = 1;
+	dev->data->dev_link.link_status = ETH_LINK_UP;
 
 	return 0;
 }
diff --git a/drivers/net/i40e/i40e_ethdev_vf.c b/drivers/net/i40e/i40e_ethdev_vf.c
index a13d9cc..91df13b 100644
--- a/drivers/net/i40e/i40e_ethdev_vf.c
+++ b/drivers/net/i40e/i40e_ethdev_vf.c
@@ -2127,7 +2127,7 @@ i40evf_dev_link_update(struct rte_eth_dev *dev,
 		/* Always assume it's up, for Linux driver PF host */
 		new_link.link_duplex = ETH_LINK_AUTONEG_DUPLEX;
 		new_link.link_speed  = ETH_LINK_SPEED_10000;
-		new_link.link_status = 1;
+		new_link.link_status = ETH_LINK_UP;
 	}
 	i40evf_dev_atomic_write_link_status(dev, &new_link);
 
diff --git a/drivers/net/ixgbe/ixgbe_ethdev.c b/drivers/net/ixgbe/ixgbe_ethdev.c
index 5812d10..129f36a 100644
--- a/drivers/net/ixgbe/ixgbe_ethdev.c
+++ b/drivers/net/ixgbe/ixgbe_ethdev.c
@@ -3059,7 +3059,7 @@ ixgbe_dev_link_update(struct rte_eth_dev *dev, int wait_to_complete)
 	int link_up;
 	int diag;
 
-	link.link_status = 0;
+	link.link_status = ETH_LINK_DOWN;
 	link.link_speed = 0;
 	link.link_duplex = 0;
 	memset(&old, 0, sizeof(old));
@@ -3088,7 +3088,7 @@ ixgbe_dev_link_update(struct rte_eth_dev *dev, int wait_to_complete)
 			return -1;
 		return 0;
 	}
-	link.link_status = 1;
+	link.link_status = ETH_LINK_UP;
 	link.link_duplex = ETH_LINK_FULL_DUPLEX;
 
 	switch (link_speed) {
diff --git a/drivers/net/mpipe/mpipe_tilegx.c b/drivers/net/mpipe/mpipe_tilegx.c
index 7180e5a..d93ab7e 100644
--- a/drivers/net/mpipe/mpipe_tilegx.c
+++ b/drivers/net/mpipe/mpipe_tilegx.c
@@ -397,11 +397,11 @@ mpipe_link_update(struct rte_eth_dev *dev, int wait_to_complete)
 		if (speed == GXIO_MPIPE_LINK_1G) {
 			new.link_speed = ETH_LINK_SPEED_1000;
 			new.link_duplex = ETH_LINK_FULL_DUPLEX;
-			new.link_status = 1;
+			new.link_status = ETH_LINK_UP;
 		} else if (speed == GXIO_MPIPE_LINK_10G) {
 			new.link_speed = ETH_LINK_SPEED_10000;
 			new.link_duplex = ETH_LINK_FULL_DUPLEX;
-			new.link_status = 1;
+			new.link_status = ETH_LINK_UP;
 		}
 
 		rc = mpipe_link_compare(&old, &new);
@@ -848,9 +848,9 @@ mpipe_start(struct rte_eth_dev *dev)
 
 	/* Start xmit/recv on queues. */
 	for (queue = 0; queue < priv->nb_tx_queues; queue++)
-		mpipe_tx_queue(priv, queue)->q.link_status = 1;
+		mpipe_tx_queue(priv, queue)->q.link_status = ETH_LINK_UP;
 	for (queue = 0; queue < priv->nb_rx_queues; queue++)
-		mpipe_rx_queue(priv, queue)->q.link_status = 1;
+		mpipe_rx_queue(priv, queue)->q.link_status = ETH_LINK_UP;
 	priv->running = 1;
 
 	return 0;
@@ -865,9 +865,9 @@ mpipe_stop(struct rte_eth_dev *dev)
 	int rc;
 
 	for (queue = 0; queue < priv->nb_tx_queues; queue++)
-		mpipe_tx_queue(priv, queue)->q.link_status = 0;
+		mpipe_tx_queue(priv, queue)->q.link_status = ETH_LINK_DOWN;
 	for (queue = 0; queue < priv->nb_rx_queues; queue++)
-		mpipe_rx_queue(priv, queue)->q.link_status = 0;
+		mpipe_rx_queue(priv, queue)->q.link_status = ETH_LINK_DOWN;
 
 	/* Make sure the link_status writes land. */
 	rte_wmb();
diff --git a/drivers/net/nfp/nfp_net.c b/drivers/net/nfp/nfp_net.c
index 92ae48a..80dda85 100644
--- a/drivers/net/nfp/nfp_net.c
+++ b/drivers/net/nfp/nfp_net.c
@@ -817,7 +817,7 @@ nfp_net_link_update(struct rte_eth_dev *dev, __rte_unused int wait_to_complete)
 	memset(&link, 0, sizeof(struct rte_eth_link));
 
 	if (nn_link_status & NFP_NET_CFG_STS_LINK)
-		link.link_status = 1;
+		link.link_status = ETH_LINK_UP;
 
 	link.link_duplex = ETH_LINK_FULL_DUPLEX;
 	/* Other cards can limit the tx and rx rate per VF */
diff --git a/drivers/net/null/rte_eth_null.c b/drivers/net/null/rte_eth_null.c
index 1c354ad..6adea91 100644
--- a/drivers/net/null/rte_eth_null.c
+++ b/drivers/net/null/rte_eth_null.c
@@ -91,7 +91,7 @@ static const char *drivername = "Null PMD";
 static struct rte_eth_link pmd_link = {
 	.link_speed = 10000,
 	.link_duplex = ETH_LINK_FULL_DUPLEX,
-	.link_status = 0
+	.link_status = ETH_LINK_DOWN,
 };
 
 static uint16_t
@@ -199,7 +199,7 @@ eth_dev_start(struct rte_eth_dev *dev)
 	if (dev == NULL)
 		return -EINVAL;
 
-	dev->data->dev_link.link_status = 1;
+	dev->data->dev_link.link_status = ETH_LINK_UP;
 	return 0;
 }
 
@@ -209,7 +209,7 @@ eth_dev_stop(struct rte_eth_dev *dev)
 	if (dev == NULL)
 		return;
 
-	dev->data->dev_link.link_status = 0;
+	dev->data->dev_link.link_status = ETH_LINK_DOWN;
 }
 
 static int
diff --git a/drivers/net/pcap/rte_eth_pcap.c b/drivers/net/pcap/rte_eth_pcap.c
index 5202086..b90c725 100644
--- a/drivers/net/pcap/rte_eth_pcap.c
+++ b/drivers/net/pcap/rte_eth_pcap.c
@@ -125,7 +125,7 @@ static const char *drivername = "Pcap PMD";
 static struct rte_eth_link pmd_link = {
 		.link_speed = 10000,
 		.link_duplex = ETH_LINK_FULL_DUPLEX,
-		.link_status = 0
+		.link_status = ETH_LINK_DOWN,
 };
 
 static int
@@ -428,7 +428,7 @@ eth_dev_start(struct rte_eth_dev *dev)
 
 status_up:
 
-	dev->data->dev_link.link_status = 1;
+	dev->data->dev_link.link_status = ETH_LINK_UP;
 	return 0;
 }
 
@@ -479,7 +479,7 @@ eth_dev_stop(struct rte_eth_dev *dev)
 	}
 
 status_down:
-	dev->data->dev_link.link_status = 0;
+	dev->data->dev_link.link_status = ETH_LINK_DOWN;
 }
 
 static int
diff --git a/drivers/net/ring/rte_eth_ring.c b/drivers/net/ring/rte_eth_ring.c
index ba19cd7..4335c6a 100644
--- a/drivers/net/ring/rte_eth_ring.c
+++ b/drivers/net/ring/rte_eth_ring.c
@@ -79,7 +79,7 @@ static const char *drivername = "Rings PMD";
 static struct rte_eth_link pmd_link = {
 		.link_speed = 10000,
 		.link_duplex = ETH_LINK_FULL_DUPLEX,
-		.link_status = 0
+		.link_status = ETH_LINK_DOWN,
 };
 
 static uint16_t
@@ -119,27 +119,27 @@ eth_dev_configure(struct rte_eth_dev *dev __rte_unused) { return 0; }
 static int
 eth_dev_start(struct rte_eth_dev *dev)
 {
-	dev->data->dev_link.link_status = 1;
+	dev->data->dev_link.link_status = ETH_LINK_UP;
 	return 0;
 }
 
 static void
 eth_dev_stop(struct rte_eth_dev *dev)
 {
-	dev->data->dev_link.link_status = 0;
+	dev->data->dev_link.link_status = ETH_LINK_DOWN;
 }
 
 static int
 eth_dev_set_link_down(struct rte_eth_dev *dev)
 {
-	dev->data->dev_link.link_status = 0;
+	dev->data->dev_link.link_status = ETH_LINK_DOWN;
 	return 0;
 }
 
 static int
 eth_dev_set_link_up(struct rte_eth_dev *dev)
 {
-	dev->data->dev_link.link_status = 1;
+	dev->data->dev_link.link_status = ETH_LINK_UP;
 	return 0;
 }
 
diff --git a/drivers/net/szedata2/rte_eth_szedata2.c b/drivers/net/szedata2/rte_eth_szedata2.c
index 1d6a600..47aa7e3 100644
--- a/drivers/net/szedata2/rte_eth_szedata2.c
+++ b/drivers/net/szedata2/rte_eth_szedata2.c
@@ -1172,7 +1172,7 @@ eth_link_update(struct rte_eth_dev *dev,
 	link.link_duplex = ETH_LINK_FULL_DUPLEX;
 
 	link.link_status = (cgmii_ibuf_is_enabled(ibuf) &&
-			cgmii_ibuf_is_link_up(ibuf)) ? 1 : 0;
+			cgmii_ibuf_is_link_up(ibuf)) ? ETH_LINK_UP : ETH_LINK_DOWN;
 
 	rte_atomic64_cmpset((uint64_t *)dev_link, *(uint64_t *)dev_link,
 			*(uint64_t *)link_ptr);
diff --git a/drivers/net/vhost/rte_eth_vhost.c b/drivers/net/vhost/rte_eth_vhost.c
index ec19c22..4cc6bec 100644
--- a/drivers/net/vhost/rte_eth_vhost.c
+++ b/drivers/net/vhost/rte_eth_vhost.c
@@ -110,7 +110,7 @@ static pthread_t session_th;
 static struct rte_eth_link pmd_link = {
 		.link_speed = 10000,
 		.link_duplex = ETH_LINK_FULL_DUPLEX,
-		.link_status = 0
+		.link_status = ETH_LINK_DOWN
 };
 
 struct rte_vhost_vring_state {
@@ -265,7 +265,7 @@ new_device(struct virtio_net *dev)
 
 	dev->flags |= VIRTIO_DEV_RUNNING;
 	dev->priv = eth_dev;
-	eth_dev->data->dev_link.link_status = 1;
+	eth_dev->data->dev_link.link_status = ETH_LINK_UP;
 
 	for (i = 0; i < eth_dev->data->nb_rx_queues; i++) {
 		vq = eth_dev->data->rx_queues[i];
@@ -323,7 +323,7 @@ destroy_device(volatile struct virtio_net *dev)
 			rte_pause();
 	}
 
-	eth_dev->data->dev_link.link_status = 0;
+	eth_dev->data->dev_link.link_status = ETH_LINK_DOWN;
 
 	dev->priv = NULL;
 	dev->flags &= ~VIRTIO_DEV_RUNNING;
diff --git a/drivers/net/virtio/virtio_ethdev.c b/drivers/net/virtio/virtio_ethdev.c
index 86c96c9..3ebc221 100644
--- a/drivers/net/virtio/virtio_ethdev.c
+++ b/drivers/net/virtio/virtio_ethdev.c
@@ -1410,16 +1410,16 @@ virtio_dev_link_update(struct rte_eth_dev *dev, __rte_unused int wait_to_complet
 				offsetof(struct virtio_net_config, status),
 				&status, sizeof(status));
 		if ((status & VIRTIO_NET_S_LINK_UP) == 0) {
-			link.link_status = 0;
+			link.link_status = ETH_LINK_DOWN;
 			PMD_INIT_LOG(DEBUG, "Port %d is down",
 				     dev->data->port_id);
 		} else {
-			link.link_status = 1;
+			link.link_status = ETH_LINK_UP;
 			PMD_INIT_LOG(DEBUG, "Port %d is up",
 				     dev->data->port_id);
 		}
 	} else {
-		link.link_status = 1;   /* Link up */
+		link.link_status = ETH_LINK_UP;
 	}
 	virtio_dev_atomic_write_link_status(dev, &link);
 
diff --git a/drivers/net/vmxnet3/vmxnet3_ethdev.c b/drivers/net/vmxnet3/vmxnet3_ethdev.c
index f2b6b92..3f26217 100644
--- a/drivers/net/vmxnet3/vmxnet3_ethdev.c
+++ b/drivers/net/vmxnet3/vmxnet3_ethdev.c
@@ -777,7 +777,7 @@ vmxnet3_dev_link_update(struct rte_eth_dev *dev, __attribute__((unused)) int wai
 	ret = VMXNET3_READ_BAR1_REG(hw, VMXNET3_REG_CMD);
 
 	if (ret & 0x1) {
-		link.link_status = 1;
+		link.link_status = ETH_LINK_UP;
 		link.link_duplex = ETH_LINK_FULL_DUPLEX;
 		link.link_speed = ETH_LINK_SPEED_10000;
 	}
diff --git a/drivers/net/xenvirt/rte_eth_xenvirt.c b/drivers/net/xenvirt/rte_eth_xenvirt.c
index 3f31806..9453a06 100644
--- a/drivers/net/xenvirt/rte_eth_xenvirt.c
+++ b/drivers/net/xenvirt/rte_eth_xenvirt.c
@@ -72,7 +72,7 @@ static const char *drivername = "xen virtio PMD";
 static struct rte_eth_link pmd_link = {
 		.link_speed = 10000,
 		.link_duplex = ETH_LINK_FULL_DUPLEX,
-		.link_status = 0
+		.link_status = ETH_LINK_DOWN,
 };
 
 static void
@@ -290,7 +290,7 @@ eth_dev_start(struct rte_eth_dev *dev)
 	struct pmd_internals *pi = (struct pmd_internals *)dev->data->dev_private;
 	int rv;
 
-	dev->data->dev_link.link_status = 1;
+	dev->data->dev_link.link_status = ETH_LINK_UP;
 	while (!virtqueue_full(rxvq)) {
 		m = rte_rxmbuf_alloc(rxvq->mpool);
 		if (m == NULL)
@@ -318,7 +318,7 @@ eth_dev_stop(struct rte_eth_dev *dev)
 {
 	struct pmd_internals *pi = (struct pmd_internals *)dev->data->dev_private;
 
-	dev->data->dev_link.link_status = 0;
+	dev->data->dev_link.link_status = ETH_LINK_DOWN;
 	dev_stop_notify(pi->virtio_idx);
 }
 
diff --git a/examples/exception_path/main.c b/examples/exception_path/main.c
index b3fe170..bec9804 100644
--- a/examples/exception_path/main.c
+++ b/examples/exception_path/main.c
@@ -485,7 +485,7 @@ check_all_ports_link_status(uint8_t port_num, uint32_t port_mask)
 				continue;
 			}
 			/* clear all_ports_up flag if any link down */
-			if (link.link_status == 0) {
+			if (link.link_status == ETH_LINK_DOWN) {
 				all_ports_up = 0;
 				break;
 			}
diff --git a/examples/ip_fragmentation/main.c b/examples/ip_fragmentation/main.c
index 8021702..81a4918 100644
--- a/examples/ip_fragmentation/main.c
+++ b/examples/ip_fragmentation/main.c
@@ -631,7 +631,7 @@ check_all_ports_link_status(uint8_t port_num, uint32_t port_mask)
 				continue;
 			}
 			/* clear all_ports_up flag if any link down */
-			if (link.link_status == 0) {
+			if (link.link_status == ETH_LINK_DOWN) {
 				all_ports_up = 0;
 				break;
 			}
diff --git a/examples/ip_pipeline/init.c b/examples/ip_pipeline/init.c
index e59a6b4..83422e8 100644
--- a/examples/ip_pipeline/init.c
+++ b/examples/ip_pipeline/init.c
@@ -856,7 +856,7 @@ app_check_link(struct app_params *app)
 			link_params.link_speed / 1000,
 			link_params.link_status ? "UP" : "DOWN");
 
-		if (link_params.link_status == 0)
+		if (link_params.link_status == ETH_LINK_DOWN)
 			all_links_up = 0;
 	}
 
diff --git a/examples/ip_reassembly/main.c b/examples/ip_reassembly/main.c
index 19ec46c..c27e735 100644
--- a/examples/ip_reassembly/main.c
+++ b/examples/ip_reassembly/main.c
@@ -763,7 +763,7 @@ check_all_ports_link_status(uint8_t port_num, uint32_t port_mask)
 				continue;
 			}
 			/* clear all_ports_up flag if any link down */
-			if (link.link_status == 0) {
+			if (link.link_status == ETH_LINK_DOWN) {
 				all_ports_up = 0;
 				break;
 			}
diff --git a/examples/ipsec-secgw/ipsec-secgw.c b/examples/ipsec-secgw/ipsec-secgw.c
index d6c9a5d..393f9bd 100644
--- a/examples/ipsec-secgw/ipsec-secgw.c
+++ b/examples/ipsec-secgw/ipsec-secgw.c
@@ -945,7 +945,7 @@ check_all_ports_link_status(uint8_t port_num, uint32_t port_mask)
 				continue;
 			}
 			/* clear all_ports_up flag if any link down */
-			if (link.link_status == 0) {
+			if (link.link_status == ETH_LINK_DOWN) {
 				all_ports_up = 0;
 				break;
 			}
diff --git a/examples/ipv4_multicast/main.c b/examples/ipv4_multicast/main.c
index 5dbea1a..96b4157 100644
--- a/examples/ipv4_multicast/main.c
+++ b/examples/ipv4_multicast/main.c
@@ -642,7 +642,7 @@ check_all_ports_link_status(uint8_t port_num, uint32_t port_mask)
 				continue;
 			}
 			/* clear all_ports_up flag if any link down */
-			if (link.link_status == 0) {
+			if (link.link_status == ETH_LINK_DOWN) {
 				all_ports_up = 0;
 				break;
 			}
diff --git a/examples/kni/main.c b/examples/kni/main.c
index 6d434ad..a5297f2 100644
--- a/examples/kni/main.c
+++ b/examples/kni/main.c
@@ -670,7 +670,7 @@ check_all_ports_link_status(uint8_t port_num, uint32_t port_mask)
 				continue;
 			}
 			/* clear all_ports_up flag if any link down */
-			if (link.link_status == 0) {
+			if (link.link_status == ETH_LINK_DOWN) {
 				all_ports_up = 0;
 				break;
 			}
diff --git a/examples/l2fwd-crypto/main.c b/examples/l2fwd-crypto/main.c
index 5fd4ff1..1c3aaa0 100644
--- a/examples/l2fwd-crypto/main.c
+++ b/examples/l2fwd-crypto/main.c
@@ -1277,7 +1277,7 @@ check_all_ports_link_status(uint8_t port_num, uint32_t port_mask)
 				continue;
 			}
 			/* clear all_ports_up flag if any link down */
-			if (link.link_status == 0) {
+			if (link.link_status == ETH_LINK_DOWN) {
 				all_ports_up = 0;
 				break;
 			}
diff --git a/examples/l2fwd-ivshmem/host/host.c b/examples/l2fwd-ivshmem/host/host.c
index 6e6ed5e..4bd7c41 100644
--- a/examples/l2fwd-ivshmem/host/host.c
+++ b/examples/l2fwd-ivshmem/host/host.c
@@ -371,7 +371,7 @@ check_all_ports_link_status(uint8_t port_num, uint32_t port_mask)
 				continue;
 			}
 			/* clear all_ports_up flag if any link down */
-			if (link.link_status == 0) {
+			if (link.link_status == ETH_LINK_DOWN) {
 				all_ports_up = 0;
 				break;
 			}
diff --git a/examples/l2fwd-jobstats/main.c b/examples/l2fwd-jobstats/main.c
index d1e9bf7..9f3a77d 100644
--- a/examples/l2fwd-jobstats/main.c
+++ b/examples/l2fwd-jobstats/main.c
@@ -746,7 +746,7 @@ check_all_ports_link_status(uint8_t port_num, uint32_t port_mask)
 				continue;
 			}
 			/* clear all_ports_up flag if any link down */
-			if (link.link_status == 0) {
+			if (link.link_status == ETH_LINK_DOWN) {
 				all_ports_up = 0;
 				break;
 			}
diff --git a/examples/l2fwd-keepalive/main.c b/examples/l2fwd-keepalive/main.c
index 94b8677..8da89aa 100644
--- a/examples/l2fwd-keepalive/main.c
+++ b/examples/l2fwd-keepalive/main.c
@@ -499,7 +499,7 @@ check_all_ports_link_status(uint8_t port_num, uint32_t port_mask)
 				continue;
 			}
 			/* clear all_ports_up flag if any link down */
-			if (link.link_status == 0) {
+			if (link.link_status == ETH_LINK_DOWN) {
 				all_ports_up = 0;
 				break;
 			}
diff --git a/examples/l2fwd/main.c b/examples/l2fwd/main.c
index e175681..1ad9488 100644
--- a/examples/l2fwd/main.c
+++ b/examples/l2fwd/main.c
@@ -480,7 +480,7 @@ check_all_ports_link_status(uint8_t port_num, uint32_t port_mask)
 				continue;
 			}
 			/* clear all_ports_up flag if any link down */
-			if (link.link_status == 0) {
+			if (link.link_status == ETH_LINK_DOWN) {
 				all_ports_up = 0;
 				break;
 			}
diff --git a/examples/l3fwd-acl/main.c b/examples/l3fwd-acl/main.c
index 3a895b7..621872f 100644
--- a/examples/l3fwd-acl/main.c
+++ b/examples/l3fwd-acl/main.c
@@ -1858,7 +1858,7 @@ check_all_ports_link_status(uint8_t port_num, uint32_t port_mask)
 				continue;
 			}
 			/* clear all_ports_up flag if any link down */
-			if (link.link_status == 0) {
+			if (link.link_status == ETH_LINK_DOWN) {
 				all_ports_up = 0;
 				break;
 			}
diff --git a/examples/l3fwd-power/main.c b/examples/l3fwd-power/main.c
index e7ebe30..5934efe 100644
--- a/examples/l3fwd-power/main.c
+++ b/examples/l3fwd-power/main.c
@@ -1509,7 +1509,7 @@ check_all_ports_link_status(uint8_t port_num, uint32_t port_mask)
 				continue;
 			}
 			/* clear all_ports_up flag if any link down */
-			if (link.link_status == 0) {
+			if (link.link_status == ETH_LINK_DOWN) {
 				all_ports_up = 0;
 				break;
 			}
diff --git a/examples/l3fwd/main.c b/examples/l3fwd/main.c
index e10dab9..5c627e5 100644
--- a/examples/l3fwd/main.c
+++ b/examples/l3fwd/main.c
@@ -769,7 +769,7 @@ check_all_ports_link_status(uint8_t port_num, uint32_t port_mask)
 				continue;
 			}
 			/* clear all_ports_up flag if any link down */
-			if (link.link_status == 0) {
+			if (link.link_status == ETH_LINK_DOWN) {
 				all_ports_up = 0;
 				break;
 			}
diff --git a/examples/link_status_interrupt/main.c b/examples/link_status_interrupt/main.c
index cbc29bc..9981598 100644
--- a/examples/link_status_interrupt/main.c
+++ b/examples/link_status_interrupt/main.c
@@ -523,7 +523,7 @@ check_all_ports_link_status(uint8_t port_num, uint32_t port_mask)
 				continue;
 			}
 			/* clear all_ports_up flag if any link down */
-			if (link.link_status == 0) {
+			if (link.link_status == ETH_LINK_DOWN) {
 				all_ports_up = 0;
 				break;
 			}
diff --git a/examples/load_balancer/init.c b/examples/load_balancer/init.c
index a96d778..e07850b 100644
--- a/examples/load_balancer/init.c
+++ b/examples/load_balancer/init.c
@@ -395,7 +395,7 @@ check_all_ports_link_status(uint8_t port_num, uint32_t port_mask)
 				continue;
 			}
 			/* clear all_ports_up flag if any link down */
-			if (link.link_status == 0) {
+			if (link.link_status == ETH_LINK_DOWN) {
 				all_ports_up = 0;
 				break;
 			}
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 1078ffd..ecb61c6 100644
--- a/examples/multi_process/client_server_mp/mp_server/init.c
+++ b/examples/multi_process/client_server_mp/mp_server/init.c
@@ -226,7 +226,7 @@ check_all_ports_link_status(uint8_t port_num, uint32_t port_mask)
 				continue;
 			}
 			/* clear all_ports_up flag if any link down */
-			if (link.link_status == 0) {
+			if (link.link_status == ETH_LINK_DOWN) {
 				all_ports_up = 0;
 				break;
 			}
diff --git a/examples/multi_process/l2fwd_fork/main.c b/examples/multi_process/l2fwd_fork/main.c
index aebf531..2dc8b82 100644
--- a/examples/multi_process/l2fwd_fork/main.c
+++ b/examples/multi_process/l2fwd_fork/main.c
@@ -900,7 +900,7 @@ check_all_ports_link_status(uint8_t port_num, uint32_t port_mask)
 				continue;
 			}
 			/* clear all_ports_up flag if any link down */
-			if (link.link_status == 0) {
+			if (link.link_status == ETH_LINK_DOWN) {
 				all_ports_up = 0;
 				break;
 			}
diff --git a/examples/multi_process/symmetric_mp/main.c b/examples/multi_process/symmetric_mp/main.c
index 72bad54..6bbff07 100644
--- a/examples/multi_process/symmetric_mp/main.c
+++ b/examples/multi_process/symmetric_mp/main.c
@@ -388,7 +388,7 @@ check_all_ports_link_status(uint8_t port_num, uint32_t port_mask)
 				continue;
 			}
 			/* clear all_ports_up flag if any link down */
-			if (link.link_status == 0) {
+			if (link.link_status == ETH_LINK_DOWN) {
 				all_ports_up = 0;
 				break;
 			}
diff --git a/examples/performance-thread/l3fwd-thread/main.c b/examples/performance-thread/l3fwd-thread/main.c
index 61c023e..15c0a4d 100644
--- a/examples/performance-thread/l3fwd-thread/main.c
+++ b/examples/performance-thread/l3fwd-thread/main.c
@@ -3408,7 +3408,7 @@ check_all_ports_link_status(uint8_t port_num, uint32_t port_mask)
 				continue;
 			}
 			/* clear all_ports_up flag if any link down */
-			if (link.link_status == 0) {
+			if (link.link_status == ETH_LINK_DOWN) {
 				all_ports_up = 0;
 				break;
 			}
diff --git a/lib/librte_ether/rte_ethdev.h b/lib/librte_ether/rte_ethdev.h
index e7de34a..c5a215a 100644
--- a/lib/librte_ether/rte_ethdev.h
+++ b/lib/librte_ether/rte_ethdev.h
@@ -247,7 +247,7 @@ struct rte_eth_stats {
 struct rte_eth_link {
 	uint16_t link_speed;      /**< ETH_LINK_SPEED_[10, 100, 1000, 10000] */
 	uint16_t link_duplex;     /**< ETH_LINK_[HALF_DUPLEX, FULL_DUPLEX] */
-	uint8_t  link_status : 1; /**< 1 -> link up, 0 -> link down */
+	uint8_t  link_status : 1; /**< ETH_LINK_[DOWN/UP] */
 }__attribute__((aligned(8)));     /**< aligned for atomic64 read/write */
 
 #define ETH_LINK_SPEED_AUTONEG  0       /**< Auto-negotiate link speed. */
@@ -259,9 +259,12 @@ struct rte_eth_link {
 #define ETH_LINK_SPEED_20G      20000   /**< 20 gigabits/second. */
 #define ETH_LINK_SPEED_40G      40000   /**< 40 gigabits/second. */
 
+/* Utility constants */
 #define ETH_LINK_AUTONEG_DUPLEX 0       /**< Auto-negotiate duplex. */
 #define ETH_LINK_HALF_DUPLEX    1       /**< Half-duplex connection. */
 #define ETH_LINK_FULL_DUPLEX    2       /**< Full-duplex connection. */
+#define ETH_LINK_DOWN           0 /**< Link is down. */
+#define ETH_LINK_UP             1 /**< Link is up. */
 
 /**
  * A structure used to configure the ring threshold registers of an RX/TX
-- 
2.7.0

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

* [PATCH v12 2/8] ethdev: use constants for link duplex
  2016-03-25 19:42             ` [PATCH v12 " Thomas Monjalon
  2016-03-25 19:42               ` [PATCH v12 1/8] ethdev: use constants for link state Thomas Monjalon
@ 2016-03-25 19:42               ` Thomas Monjalon
  2016-03-25 19:42               ` [PATCH v12 3/8] app/testpmd: move speed and duplex parsing in a function Thomas Monjalon
                                 ` (6 subsequent siblings)
  8 siblings, 0 replies; 167+ messages in thread
From: Thomas Monjalon @ 2016-03-25 19:42 UTC (permalink / raw)
  To: marcdevel, bruce.richardson, declan.doherty, konstantin.ananyev,
	wenzhuo.lu, helin.zhang, jing.d.chen, harish.patil,
	rahul.lakkireddy, johndale, vido, adrien.mazarguil,
	alejandro.lucero
  Cc: dev

From: Marc Sune <marcdevel@gmail.com>

Some duplex values are replaced from 0 to half-duplex when link is down.

Some drivers are still using their own constants for duplex modes.

Signed-off-by: Marc Sune <marcdevel@gmail.com>
---
 drivers/net/e1000/em_ethdev.c      | 2 +-
 drivers/net/e1000/igb_ethdev.c     | 2 +-
 drivers/net/ixgbe/ixgbe_ethdev.c   | 2 +-
 drivers/net/virtio/virtio_ethdev.c | 2 +-
 drivers/net/virtio/virtio_ethdev.h | 2 --
 lib/librte_ether/rte_ethdev.h      | 2 +-
 6 files changed, 5 insertions(+), 7 deletions(-)

diff --git a/drivers/net/e1000/em_ethdev.c b/drivers/net/e1000/em_ethdev.c
index dc9ed38..fad8f2f 100644
--- a/drivers/net/e1000/em_ethdev.c
+++ b/drivers/net/e1000/em_ethdev.c
@@ -1107,7 +1107,7 @@ eth_em_link_update(struct rte_eth_dev *dev, int wait_to_complete)
 		link.link_status = ETH_LINK_UP;
 	} else if (!link_check && (link.link_status == ETH_LINK_UP)) {
 		link.link_speed = 0;
-		link.link_duplex = 0;
+		link.link_duplex = ETH_LINK_HALF_DUPLEX;
 		link.link_status = ETH_LINK_DOWN;
 	}
 	rte_em_dev_atomic_write_link_status(dev, &link);
diff --git a/drivers/net/e1000/igb_ethdev.c b/drivers/net/e1000/igb_ethdev.c
index 045fc63..4dfa7e3 100644
--- a/drivers/net/e1000/igb_ethdev.c
+++ b/drivers/net/e1000/igb_ethdev.c
@@ -2062,7 +2062,7 @@ eth_igb_link_update(struct rte_eth_dev *dev, int wait_to_complete)
 		link.link_status = ETH_LINK_UP;
 	} else if (!link_check) {
 		link.link_speed = 0;
-		link.link_duplex = 0;
+		link.link_duplex = ETH_LINK_HALF_DUPLEX;
 		link.link_status = ETH_LINK_DOWN;
 	}
 	rte_igb_dev_atomic_write_link_status(dev, &link);
diff --git a/drivers/net/ixgbe/ixgbe_ethdev.c b/drivers/net/ixgbe/ixgbe_ethdev.c
index 129f36a..21a3b8c 100644
--- a/drivers/net/ixgbe/ixgbe_ethdev.c
+++ b/drivers/net/ixgbe/ixgbe_ethdev.c
@@ -3061,7 +3061,7 @@ ixgbe_dev_link_update(struct rte_eth_dev *dev, int wait_to_complete)
 
 	link.link_status = ETH_LINK_DOWN;
 	link.link_speed = 0;
-	link.link_duplex = 0;
+	link.link_duplex = ETH_LINK_HALF_DUPLEX;
 	memset(&old, 0, sizeof(old));
 	rte_ixgbe_dev_atomic_read_link_status(dev, &old);
 
diff --git a/drivers/net/virtio/virtio_ethdev.c b/drivers/net/virtio/virtio_ethdev.c
index 3ebc221..63a368a 100644
--- a/drivers/net/virtio/virtio_ethdev.c
+++ b/drivers/net/virtio/virtio_ethdev.c
@@ -1401,7 +1401,7 @@ virtio_dev_link_update(struct rte_eth_dev *dev, __rte_unused int wait_to_complet
 	memset(&link, 0, sizeof(link));
 	virtio_dev_atomic_read_link_status(dev, &link);
 	old = link;
-	link.link_duplex = FULL_DUPLEX;
+	link.link_duplex = ETH_LINK_FULL_DUPLEX;
 	link.link_speed  = SPEED_10G;
 
 	if (vtpci_with_feature(hw, VIRTIO_NET_F_STATUS)) {
diff --git a/drivers/net/virtio/virtio_ethdev.h b/drivers/net/virtio/virtio_ethdev.h
index fed9571..66423a0 100644
--- a/drivers/net/virtio/virtio_ethdev.h
+++ b/drivers/net/virtio/virtio_ethdev.h
@@ -42,8 +42,6 @@
 #define SPEED_100	100
 #define SPEED_1000	1000
 #define SPEED_10G	10000
-#define HALF_DUPLEX	1
-#define FULL_DUPLEX	2
 
 #ifndef PAGE_SIZE
 #define PAGE_SIZE 4096
diff --git a/lib/librte_ether/rte_ethdev.h b/lib/librte_ether/rte_ethdev.h
index c5a215a..2d13f92 100644
--- a/lib/librte_ether/rte_ethdev.h
+++ b/lib/librte_ether/rte_ethdev.h
@@ -246,7 +246,7 @@ struct rte_eth_stats {
  */
 struct rte_eth_link {
 	uint16_t link_speed;      /**< ETH_LINK_SPEED_[10, 100, 1000, 10000] */
-	uint16_t link_duplex;     /**< ETH_LINK_[HALF_DUPLEX, FULL_DUPLEX] */
+	uint16_t link_duplex;     /**< ETH_LINK_[HALF/FULL]_DUPLEX */
 	uint8_t  link_status : 1; /**< ETH_LINK_[DOWN/UP] */
 }__attribute__((aligned(8)));     /**< aligned for atomic64 read/write */
 
-- 
2.7.0

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

* [PATCH v12 3/8] app/testpmd: move speed and duplex parsing in a function
  2016-03-25 19:42             ` [PATCH v12 " Thomas Monjalon
  2016-03-25 19:42               ` [PATCH v12 1/8] ethdev: use constants for link state Thomas Monjalon
  2016-03-25 19:42               ` [PATCH v12 2/8] ethdev: use constants for link duplex Thomas Monjalon
@ 2016-03-25 19:42               ` Thomas Monjalon
  2016-03-25 19:42               ` [PATCH v12 4/8] ethdev: rename link speed constants Thomas Monjalon
                                 ` (5 subsequent siblings)
  8 siblings, 0 replies; 167+ messages in thread
From: Thomas Monjalon @ 2016-03-25 19:42 UTC (permalink / raw)
  To: marcdevel, bruce.richardson, declan.doherty, konstantin.ananyev,
	wenzhuo.lu, helin.zhang, jing.d.chen, harish.patil,
	rahul.lakkireddy, johndale, vido, adrien.mazarguil,
	alejandro.lucero
  Cc: dev

From: Marc Sune <marcdevel@gmail.com>

The code for checking and parsing speed/duplex was duplicated.
The new function is also checking the speed/duplex combination.

Signed-off-by: Marc Sune <marcdevel@gmail.com>
---
 app/test-pmd/cmdline.c | 99 ++++++++++++++++++++++++--------------------------
 1 file changed, 47 insertions(+), 52 deletions(-)

diff --git a/app/test-pmd/cmdline.c b/app/test-pmd/cmdline.c
index 93203f4..eb7bbb4 100644
--- a/app/test-pmd/cmdline.c
+++ b/app/test-pmd/cmdline.c
@@ -988,6 +988,49 @@ struct cmd_config_speed_all {
 	cmdline_fixed_string_t value2;
 };
 
+static int
+parse_and_check_speed_duplex(char *speedstr, char *duplexstr, uint16_t *speed)
+{
+
+	int duplex;
+
+	if (!strcmp(duplexstr, "half")) {
+		duplex = ETH_LINK_HALF_DUPLEX;
+	} else if (!strcmp(duplexstr, "full")) {
+		duplex = ETH_LINK_FULL_DUPLEX;
+	} else if (!strcmp(duplexstr, "auto")) {
+		duplex = ETH_LINK_FULL_DUPLEX;
+	} else {
+		printf("Unknown duplex parameter\n");
+		return -1;
+	}
+
+	if (!strcmp(speedstr, "10")) {
+		*speed = ETH_LINK_SPEED_10;
+	} else if (!strcmp(speedstr, "100")) {
+		*speed = ETH_LINK_SPEED_100;
+	} else {
+		if (duplex != ETH_LINK_FULL_DUPLEX) {
+			printf("Invalid speed/duplex parameters\n");
+			return -1;
+		}
+		if (!strcmp(speedstr, "1000")) {
+			*speed = ETH_LINK_SPEED_1000;
+		} else if (!strcmp(speedstr, "10000")) {
+			*speed = ETH_LINK_SPEED_10G;
+		} else if (!strcmp(speedstr, "40000")) {
+			*speed = ETH_LINK_SPEED_40G;
+		} else if (!strcmp(speedstr, "auto")) {
+			*speed = ETH_LINK_SPEED_AUTONEG;
+		} else {
+			printf("Unknown speed parameter\n");
+			return -1;
+		}
+	}
+
+	return 0;
+}
+
 static void
 cmd_config_speed_all_parsed(void *parsed_result,
 			__attribute__((unused)) struct cmdline *cl,
@@ -1003,33 +1046,9 @@ cmd_config_speed_all_parsed(void *parsed_result,
 		return;
 	}
 
-	if (!strcmp(res->value1, "10"))
-		link_speed = ETH_LINK_SPEED_10;
-	else if (!strcmp(res->value1, "100"))
-		link_speed = ETH_LINK_SPEED_100;
-	else if (!strcmp(res->value1, "1000"))
-		link_speed = ETH_LINK_SPEED_1000;
-	else if (!strcmp(res->value1, "10000"))
-		link_speed = ETH_LINK_SPEED_10G;
-	else if (!strcmp(res->value1, "40000"))
-		link_speed = ETH_LINK_SPEED_40G;
-	else if (!strcmp(res->value1, "auto"))
-		link_speed = ETH_LINK_SPEED_AUTONEG;
-	else {
-		printf("Unknown parameter\n");
+	if (parse_and_check_speed_duplex(res->value1, res->value2,
+			&link_speed) < 0)
 		return;
-	}
-
-	if (!strcmp(res->value2, "half"))
-		link_duplex = ETH_LINK_HALF_DUPLEX;
-	else if (!strcmp(res->value2, "full"))
-		link_duplex = ETH_LINK_FULL_DUPLEX;
-	else if (!strcmp(res->value2, "auto"))
-		link_duplex = ETH_LINK_AUTONEG_DUPLEX;
-	else {
-		printf("Unknown parameter\n");
-		return;
-	}
 
 	FOREACH_PORT(pid, ports) {
 		ports[pid].dev_conf.link_speed = link_speed;
@@ -1102,33 +1121,9 @@ cmd_config_speed_specific_parsed(void *parsed_result,
 	if (port_id_is_invalid(res->id, ENABLED_WARN))
 		return;
 
-	if (!strcmp(res->value1, "10"))
-		link_speed = ETH_LINK_SPEED_10;
-	else if (!strcmp(res->value1, "100"))
-		link_speed = ETH_LINK_SPEED_100;
-	else if (!strcmp(res->value1, "1000"))
-		link_speed = ETH_LINK_SPEED_1000;
-	else if (!strcmp(res->value1, "10000"))
-		link_speed = ETH_LINK_SPEED_10000;
-	else if (!strcmp(res->value1, "40000"))
-		link_speed = ETH_LINK_SPEED_40G;
-	else if (!strcmp(res->value1, "auto"))
-		link_speed = ETH_LINK_SPEED_AUTONEG;
-	else {
-		printf("Unknown parameter\n");
-		return;
-	}
-
-	if (!strcmp(res->value2, "half"))
-		link_duplex = ETH_LINK_HALF_DUPLEX;
-	else if (!strcmp(res->value2, "full"))
-		link_duplex = ETH_LINK_FULL_DUPLEX;
-	else if (!strcmp(res->value2, "auto"))
-		link_duplex = ETH_LINK_AUTONEG_DUPLEX;
-	else {
-		printf("Unknown parameter\n");
+	if (parse_and_check_speed_duplex(res->value1, res->value2,
+			&link_speed) < 0)
 		return;
-	}
 
 	ports[res->id].dev_conf.link_speed = link_speed;
 	ports[res->id].dev_conf.link_duplex = link_duplex;
-- 
2.7.0

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

* [PATCH v12 4/8] ethdev: rename link speed constants
  2016-03-25 19:42             ` [PATCH v12 " Thomas Monjalon
                                 ` (2 preceding siblings ...)
  2016-03-25 19:42               ` [PATCH v12 3/8] app/testpmd: move speed and duplex parsing in a function Thomas Monjalon
@ 2016-03-25 19:42               ` Thomas Monjalon
  2016-03-25 19:42               ` [PATCH v12 5/8] ethdev: add speed capabilities Thomas Monjalon
                                 ` (4 subsequent siblings)
  8 siblings, 0 replies; 167+ messages in thread
From: Thomas Monjalon @ 2016-03-25 19:42 UTC (permalink / raw)
  To: marcdevel, bruce.richardson, declan.doherty, konstantin.ananyev,
	wenzhuo.lu, helin.zhang, jing.d.chen, harish.patil,
	rahul.lakkireddy, johndale, vido, adrien.mazarguil,
	alejandro.lucero
  Cc: dev

From: Marc Sune <marcdevel@gmail.com>

The speed numbers ETH_LINK_SPEED_ are renamed ETH_SPEED_NUM_.
The prefix ETH_LINK_SPEED_ is kept for AUTONEG and will be used
for bit flags in next patch.

Signed-off-by: Marc Sune <marcdevel@gmail.com>
---
 app/test-pmd/cmdline.c                    | 10 +++++-----
 app/test/virtual_pmd.c                    |  2 +-
 drivers/net/af_packet/rte_eth_af_packet.c |  2 +-
 drivers/net/bonding/rte_eth_bond_8023ad.c | 12 ++++++------
 drivers/net/cxgbe/base/t4_hw.c            |  8 ++++----
 drivers/net/e1000/em_ethdev.c             |  8 ++++----
 drivers/net/e1000/igb_ethdev.c            |  8 ++++----
 drivers/net/ena/ena_ethdev.c              |  2 +-
 drivers/net/i40e/i40e_ethdev.c            | 30 +++++++++++++++---------------
 drivers/net/i40e/i40e_ethdev_vf.c         |  2 +-
 drivers/net/ixgbe/ixgbe_ethdev.c          | 22 +++++++++++-----------
 drivers/net/mpipe/mpipe_tilegx.c          |  4 ++--
 drivers/net/nfp/nfp_net.c                 |  2 +-
 drivers/net/null/rte_eth_null.c           |  2 +-
 drivers/net/pcap/rte_eth_pcap.c           |  2 +-
 drivers/net/ring/rte_eth_ring.c           |  2 +-
 drivers/net/szedata2/rte_eth_szedata2.c   |  8 ++++----
 drivers/net/vmxnet3/vmxnet3_ethdev.c      |  2 +-
 drivers/net/xenvirt/rte_eth_xenvirt.c     |  2 +-
 lib/librte_ether/rte_ethdev.h             | 29 ++++++++++++++++++-----------
 20 files changed, 83 insertions(+), 76 deletions(-)

diff --git a/app/test-pmd/cmdline.c b/app/test-pmd/cmdline.c
index eb7bbb4..815b53b 100644
--- a/app/test-pmd/cmdline.c
+++ b/app/test-pmd/cmdline.c
@@ -1006,20 +1006,20 @@ parse_and_check_speed_duplex(char *speedstr, char *duplexstr, uint16_t *speed)
 	}
 
 	if (!strcmp(speedstr, "10")) {
-		*speed = ETH_LINK_SPEED_10;
+		*speed = ETH_SPEED_NUM_10M;
 	} else if (!strcmp(speedstr, "100")) {
-		*speed = ETH_LINK_SPEED_100;
+		*speed = ETH_SPEED_NUM_100M;
 	} else {
 		if (duplex != ETH_LINK_FULL_DUPLEX) {
 			printf("Invalid speed/duplex parameters\n");
 			return -1;
 		}
 		if (!strcmp(speedstr, "1000")) {
-			*speed = ETH_LINK_SPEED_1000;
+			*speed = ETH_SPEED_NUM_1G;
 		} else if (!strcmp(speedstr, "10000")) {
-			*speed = ETH_LINK_SPEED_10G;
+			*speed = ETH_SPEED_NUM_10G;
 		} else if (!strcmp(speedstr, "40000")) {
-			*speed = ETH_LINK_SPEED_40G;
+			*speed = ETH_SPEED_NUM_40G;
 		} else if (!strcmp(speedstr, "auto")) {
 			*speed = ETH_LINK_SPEED_AUTONEG;
 		} else {
diff --git a/app/test/virtual_pmd.c b/app/test/virtual_pmd.c
index b1d40d7..b4bd2f2 100644
--- a/app/test/virtual_pmd.c
+++ b/app/test/virtual_pmd.c
@@ -604,7 +604,7 @@ virtual_ethdev_create(const char *name, struct ether_addr *mac_addr,
 	TAILQ_INIT(&(eth_dev->link_intr_cbs));
 
 	eth_dev->data->dev_link.link_status = ETH_LINK_DOWN;
-	eth_dev->data->dev_link.link_speed = ETH_LINK_SPEED_10000;
+	eth_dev->data->dev_link.link_speed = ETH_SPEED_NUM_10G;
 	eth_dev->data->dev_link.link_duplex = ETH_LINK_FULL_DUPLEX;
 
 	eth_dev->data->mac_addrs = rte_zmalloc(name, ETHER_ADDR_LEN, 0);
diff --git a/drivers/net/af_packet/rte_eth_af_packet.c b/drivers/net/af_packet/rte_eth_af_packet.c
index dee7b59..641f849 100644
--- a/drivers/net/af_packet/rte_eth_af_packet.c
+++ b/drivers/net/af_packet/rte_eth_af_packet.c
@@ -116,7 +116,7 @@ static const char *valid_arguments[] = {
 static const char *drivername = "AF_PACKET PMD";
 
 static struct rte_eth_link pmd_link = {
-	.link_speed = 10000,
+	.link_speed = ETH_SPEED_NUM_10G,
 	.link_duplex = ETH_LINK_FULL_DUPLEX,
 	.link_status = ETH_LINK_DOWN,
 };
diff --git a/drivers/net/bonding/rte_eth_bond_8023ad.c b/drivers/net/bonding/rte_eth_bond_8023ad.c
index 1b7e93a..ac8306f 100644
--- a/drivers/net/bonding/rte_eth_bond_8023ad.c
+++ b/drivers/net/bonding/rte_eth_bond_8023ad.c
@@ -711,22 +711,22 @@ link_speed_key(uint16_t speed) {
 	case ETH_LINK_SPEED_AUTONEG:
 		key_speed = 0x00;
 		break;
-	case ETH_LINK_SPEED_10:
+	case ETH_SPEED_NUM_10M:
 		key_speed = BOND_LINK_SPEED_KEY_10M;
 		break;
-	case ETH_LINK_SPEED_100:
+	case ETH_SPEED_NUM_100M:
 		key_speed = BOND_LINK_SPEED_KEY_100M;
 		break;
-	case ETH_LINK_SPEED_1000:
+	case ETH_SPEED_NUM_1G:
 		key_speed = BOND_LINK_SPEED_KEY_1000M;
 		break;
-	case ETH_LINK_SPEED_10G:
+	case ETH_SPEED_NUM_10G:
 		key_speed = BOND_LINK_SPEED_KEY_10G;
 		break;
-	case ETH_LINK_SPEED_20G:
+	case ETH_SPEED_NUM_20G:
 		key_speed = BOND_LINK_SPEED_KEY_20G;
 		break;
-	case ETH_LINK_SPEED_40G:
+	case ETH_SPEED_NUM_40G:
 		key_speed = BOND_LINK_SPEED_KEY_40G;
 		break;
 	default:
diff --git a/drivers/net/cxgbe/base/t4_hw.c b/drivers/net/cxgbe/base/t4_hw.c
index 884d2cf..79af806 100644
--- a/drivers/net/cxgbe/base/t4_hw.c
+++ b/drivers/net/cxgbe/base/t4_hw.c
@@ -2159,13 +2159,13 @@ int t4_handle_fw_rpl(struct adapter *adap, const __be64 *rpl)
 		if (stat & F_FW_PORT_CMD_TXPAUSE)
 			fc |= PAUSE_TX;
 		if (stat & V_FW_PORT_CMD_LSPEED(FW_PORT_CAP_SPEED_100M))
-			speed = ETH_LINK_SPEED_100;
+			speed = ETH_SPEED_NUM_100M;
 		else if (stat & V_FW_PORT_CMD_LSPEED(FW_PORT_CAP_SPEED_1G))
-			speed = ETH_LINK_SPEED_1000;
+			speed = ETH_SPEED_NUM_1G;
 		else if (stat & V_FW_PORT_CMD_LSPEED(FW_PORT_CAP_SPEED_10G))
-			speed = ETH_LINK_SPEED_10000;
+			speed = ETH_SPEED_NUM_10G;
 		else if (stat & V_FW_PORT_CMD_LSPEED(FW_PORT_CAP_SPEED_40G))
-			speed = ETH_LINK_SPEED_40G;
+			speed = ETH_SPEED_NUM_40G;
 
 		for_each_port(adap, i) {
 			pi = adap2pinfo(adap, i);
diff --git a/drivers/net/e1000/em_ethdev.c b/drivers/net/e1000/em_ethdev.c
index fad8f2f..473d77f 100644
--- a/drivers/net/e1000/em_ethdev.c
+++ b/drivers/net/e1000/em_ethdev.c
@@ -625,7 +625,7 @@ eth_em_start(struct rte_eth_dev *dev)
 		else
 			goto error_invalid_config;
 		break;
-	case ETH_LINK_SPEED_10:
+	case ETH_SPEED_NUM_10M:
 		if (dev->data->dev_conf.link_duplex == ETH_LINK_AUTONEG_DUPLEX)
 			hw->phy.autoneg_advertised = E1000_ALL_10_SPEED;
 		else if (dev->data->dev_conf.link_duplex ==
@@ -637,7 +637,7 @@ eth_em_start(struct rte_eth_dev *dev)
 		else
 			goto error_invalid_config;
 		break;
-	case ETH_LINK_SPEED_100:
+	case ETH_SPEED_NUM_100M:
 		if (dev->data->dev_conf.link_duplex == ETH_LINK_AUTONEG_DUPLEX)
 			hw->phy.autoneg_advertised = E1000_ALL_100_SPEED;
 		else if (dev->data->dev_conf.link_duplex ==
@@ -649,7 +649,7 @@ eth_em_start(struct rte_eth_dev *dev)
 		else
 			goto error_invalid_config;
 		break;
-	case ETH_LINK_SPEED_1000:
+	case ETH_SPEED_NUM_1G:
 		if ((dev->data->dev_conf.link_duplex ==
 				ETH_LINK_AUTONEG_DUPLEX) ||
 			(dev->data->dev_conf.link_duplex ==
@@ -658,7 +658,7 @@ eth_em_start(struct rte_eth_dev *dev)
 		else
 			goto error_invalid_config;
 		break;
-	case ETH_LINK_SPEED_10000:
+	case ETH_SPEED_NUM_10G:
 	default:
 		goto error_invalid_config;
 	}
diff --git a/drivers/net/e1000/igb_ethdev.c b/drivers/net/e1000/igb_ethdev.c
index 4dfa7e3..86f25f6 100644
--- a/drivers/net/e1000/igb_ethdev.c
+++ b/drivers/net/e1000/igb_ethdev.c
@@ -1244,7 +1244,7 @@ eth_igb_start(struct rte_eth_dev *dev)
 		else
 			goto error_invalid_config;
 		break;
-	case ETH_LINK_SPEED_10:
+	case ETH_SPEED_NUM_10M:
 		if (dev->data->dev_conf.link_duplex == ETH_LINK_AUTONEG_DUPLEX)
 			hw->phy.autoneg_advertised = E1000_ALL_10_SPEED;
 		else if (dev->data->dev_conf.link_duplex == ETH_LINK_HALF_DUPLEX)
@@ -1254,7 +1254,7 @@ eth_igb_start(struct rte_eth_dev *dev)
 		else
 			goto error_invalid_config;
 		break;
-	case ETH_LINK_SPEED_100:
+	case ETH_SPEED_NUM_100M:
 		if (dev->data->dev_conf.link_duplex == ETH_LINK_AUTONEG_DUPLEX)
 			hw->phy.autoneg_advertised = E1000_ALL_100_SPEED;
 		else if (dev->data->dev_conf.link_duplex == ETH_LINK_HALF_DUPLEX)
@@ -1264,14 +1264,14 @@ eth_igb_start(struct rte_eth_dev *dev)
 		else
 			goto error_invalid_config;
 		break;
-	case ETH_LINK_SPEED_1000:
+	case ETH_SPEED_NUM_1G:
 		if ((dev->data->dev_conf.link_duplex == ETH_LINK_AUTONEG_DUPLEX) ||
 				(dev->data->dev_conf.link_duplex == ETH_LINK_FULL_DUPLEX))
 			hw->phy.autoneg_advertised = ADVERTISE_1000_FULL;
 		else
 			goto error_invalid_config;
 		break;
-	case ETH_LINK_SPEED_10000:
+	case ETH_SPEED_NUM_10G:
 	default:
 		goto error_invalid_config;
 	}
diff --git a/drivers/net/ena/ena_ethdev.c b/drivers/net/ena/ena_ethdev.c
index 325c513..1046286 100644
--- a/drivers/net/ena/ena_ethdev.c
+++ b/drivers/net/ena/ena_ethdev.c
@@ -504,7 +504,7 @@ static int ena_link_update(struct rte_eth_dev *dev,
 	struct rte_eth_link *link = &dev->data->dev_link;
 
 	link->link_status = 1;
-	link->link_speed = ETH_LINK_SPEED_10G;
+	link->link_speed = ETH_SPEED_NUM_10G;
 	link->link_duplex = ETH_LINK_FULL_DUPLEX;
 
 	return 0;
diff --git a/drivers/net/i40e/i40e_ethdev.c b/drivers/net/i40e/i40e_ethdev.c
index 05126e8..cce9e6f 100644
--- a/drivers/net/i40e/i40e_ethdev.c
+++ b/drivers/net/i40e/i40e_ethdev.c
@@ -1386,19 +1386,19 @@ i40e_parse_link_speed(uint16_t eth_link_speed)
 	uint8_t link_speed = I40E_LINK_SPEED_UNKNOWN;
 
 	switch (eth_link_speed) {
-	case ETH_LINK_SPEED_40G:
+	case ETH_SPEED_NUM_40G:
 		link_speed = I40E_LINK_SPEED_40GB;
 		break;
-	case ETH_LINK_SPEED_20G:
+	case ETH_SPEED_NUM_20G:
 		link_speed = I40E_LINK_SPEED_20GB;
 		break;
-	case ETH_LINK_SPEED_10G:
+	case ETH_SPEED_NUM_10G:
 		link_speed = I40E_LINK_SPEED_10GB;
 		break;
-	case ETH_LINK_SPEED_1000:
+	case ETH_SPEED_NUM_1G:
 		link_speed = I40E_LINK_SPEED_1GB;
 		break;
-	case ETH_LINK_SPEED_100:
+	case ETH_SPEED_NUM_100M:
 		link_speed = I40E_LINK_SPEED_100MB;
 		break;
 	}
@@ -1768,7 +1768,7 @@ i40e_dev_link_update(struct rte_eth_dev *dev,
 		/* Get link status information from hardware */
 		status = i40e_aq_get_link_info(hw, false, &link_status, NULL);
 		if (status != I40E_SUCCESS) {
-			link.link_speed = ETH_LINK_SPEED_100;
+			link.link_speed = ETH_SPEED_NUM_100M;
 			link.link_duplex = ETH_LINK_FULL_DUPLEX;
 			PMD_DRV_LOG(ERR, "Failed to get link info");
 			goto out;
@@ -1790,22 +1790,22 @@ i40e_dev_link_update(struct rte_eth_dev *dev,
 	/* Parse the link status */
 	switch (link_status.link_speed) {
 	case I40E_LINK_SPEED_100MB:
-		link.link_speed = ETH_LINK_SPEED_100;
+		link.link_speed = ETH_SPEED_NUM_100M;
 		break;
 	case I40E_LINK_SPEED_1GB:
-		link.link_speed = ETH_LINK_SPEED_1000;
+		link.link_speed = ETH_SPEED_NUM_1G;
 		break;
 	case I40E_LINK_SPEED_10GB:
-		link.link_speed = ETH_LINK_SPEED_10G;
+		link.link_speed = ETH_SPEED_NUM_10G;
 		break;
 	case I40E_LINK_SPEED_20GB:
-		link.link_speed = ETH_LINK_SPEED_20G;
+		link.link_speed = ETH_SPEED_NUM_20G;
 		break;
 	case I40E_LINK_SPEED_40GB:
-		link.link_speed = ETH_LINK_SPEED_40G;
+		link.link_speed = ETH_SPEED_NUM_40G;
 		break;
 	default:
-		link.link_speed = ETH_LINK_SPEED_100;
+		link.link_speed = ETH_SPEED_NUM_100M;
 		break;
 	}
 
@@ -8158,15 +8158,15 @@ i40e_start_timecounters(struct rte_eth_dev *dev)
 	rte_i40e_dev_atomic_read_link_status(dev, &link);
 
 	switch (link.link_speed) {
-	case ETH_LINK_SPEED_40G:
+	case ETH_SPEED_NUM_40G:
 		tsync_inc_l = I40E_PTP_40GB_INCVAL & 0xFFFFFFFF;
 		tsync_inc_h = I40E_PTP_40GB_INCVAL >> 32;
 		break;
-	case ETH_LINK_SPEED_10G:
+	case ETH_SPEED_NUM_10G:
 		tsync_inc_l = I40E_PTP_10GB_INCVAL & 0xFFFFFFFF;
 		tsync_inc_h = I40E_PTP_10GB_INCVAL >> 32;
 		break;
-	case ETH_LINK_SPEED_1000:
+	case ETH_SPEED_NUM_1G:
 		tsync_inc_l = I40E_PTP_1GB_INCVAL & 0xFFFFFFFF;
 		tsync_inc_h = I40E_PTP_1GB_INCVAL >> 32;
 		break;
diff --git a/drivers/net/i40e/i40e_ethdev_vf.c b/drivers/net/i40e/i40e_ethdev_vf.c
index 91df13b..295dcd2 100644
--- a/drivers/net/i40e/i40e_ethdev_vf.c
+++ b/drivers/net/i40e/i40e_ethdev_vf.c
@@ -2126,7 +2126,7 @@ i40evf_dev_link_update(struct rte_eth_dev *dev,
 	else {
 		/* Always assume it's up, for Linux driver PF host */
 		new_link.link_duplex = ETH_LINK_AUTONEG_DUPLEX;
-		new_link.link_speed  = ETH_LINK_SPEED_10000;
+		new_link.link_speed  = ETH_SPEED_NUM_10G;
 		new_link.link_status = ETH_LINK_UP;
 	}
 	i40evf_dev_atomic_write_link_status(dev, &new_link);
diff --git a/drivers/net/ixgbe/ixgbe_ethdev.c b/drivers/net/ixgbe/ixgbe_ethdev.c
index 21a3b8c..a0179d2 100644
--- a/drivers/net/ixgbe/ixgbe_ethdev.c
+++ b/drivers/net/ixgbe/ixgbe_ethdev.c
@@ -2199,17 +2199,17 @@ ixgbe_dev_start(struct rte_eth_dev *dev)
 				IXGBE_LINK_SPEED_82599_AUTONEG :
 				IXGBE_LINK_SPEED_82598_AUTONEG;
 		break;
-	case ETH_LINK_SPEED_100:
+	case ETH_SPEED_NUM_100M:
 		/*
 		 * Invalid for 82598 but error will be detected by
 		 * ixgbe_setup_link()
 		 */
 		speed = IXGBE_LINK_SPEED_100_FULL;
 		break;
-	case ETH_LINK_SPEED_1000:
+	case ETH_SPEED_NUM_1G:
 		speed = IXGBE_LINK_SPEED_1GB_FULL;
 		break;
-	case ETH_LINK_SPEED_10000:
+	case ETH_SPEED_NUM_10G:
 		speed = IXGBE_LINK_SPEED_10GB_FULL;
 		break;
 	default:
@@ -3074,7 +3074,7 @@ ixgbe_dev_link_update(struct rte_eth_dev *dev, int wait_to_complete)
 		diag = ixgbe_check_link(hw, &link_speed, &link_up, 1);
 
 	if (diag != 0) {
-		link.link_speed = ETH_LINK_SPEED_100;
+		link.link_speed = ETH_SPEED_NUM_100M;
 		link.link_duplex = ETH_LINK_HALF_DUPLEX;
 		rte_ixgbe_dev_atomic_write_link_status(dev, &link);
 		if (link.link_status == old.link_status)
@@ -3095,19 +3095,19 @@ ixgbe_dev_link_update(struct rte_eth_dev *dev, int wait_to_complete)
 	default:
 	case IXGBE_LINK_SPEED_UNKNOWN:
 		link.link_duplex = ETH_LINK_HALF_DUPLEX;
-		link.link_speed = ETH_LINK_SPEED_100;
+		link.link_speed = ETH_SPEED_NUM_100M;
 		break;
 
 	case IXGBE_LINK_SPEED_100_FULL:
-		link.link_speed = ETH_LINK_SPEED_100;
+		link.link_speed = ETH_SPEED_NUM_100M;
 		break;
 
 	case IXGBE_LINK_SPEED_1GB_FULL:
-		link.link_speed = ETH_LINK_SPEED_1000;
+		link.link_speed = ETH_SPEED_NUM_1G;
 		break;
 
 	case IXGBE_LINK_SPEED_10GB_FULL:
-		link.link_speed = ETH_LINK_SPEED_10000;
+		link.link_speed = ETH_SPEED_NUM_10G;
 		break;
 	}
 	rte_ixgbe_dev_atomic_write_link_status(dev, &link);
@@ -5909,15 +5909,15 @@ ixgbe_start_timecounters(struct rte_eth_dev *dev)
 	rte_ixgbe_dev_atomic_read_link_status(dev, &link);
 
 	switch (link.link_speed) {
-	case ETH_LINK_SPEED_100:
+	case ETH_SPEED_NUM_100M:
 		incval = IXGBE_INCVAL_100;
 		shift = IXGBE_INCVAL_SHIFT_100;
 		break;
-	case ETH_LINK_SPEED_1000:
+	case ETH_SPEED_NUM_1G:
 		incval = IXGBE_INCVAL_1GB;
 		shift = IXGBE_INCVAL_SHIFT_1GB;
 		break;
-	case ETH_LINK_SPEED_10000:
+	case ETH_SPEED_NUM_10G:
 	default:
 		incval = IXGBE_INCVAL_10GB;
 		shift = IXGBE_INCVAL_SHIFT_10GB;
diff --git a/drivers/net/mpipe/mpipe_tilegx.c b/drivers/net/mpipe/mpipe_tilegx.c
index d93ab7e..1a77c7a 100644
--- a/drivers/net/mpipe/mpipe_tilegx.c
+++ b/drivers/net/mpipe/mpipe_tilegx.c
@@ -395,11 +395,11 @@ mpipe_link_update(struct rte_eth_dev *dev, int wait_to_complete)
 		speed = state & GXIO_MPIPE_LINK_SPEED_MASK;
 
 		if (speed == GXIO_MPIPE_LINK_1G) {
-			new.link_speed = ETH_LINK_SPEED_1000;
+			new.link_speed = ETH_SPEED_NUM_1G;
 			new.link_duplex = ETH_LINK_FULL_DUPLEX;
 			new.link_status = ETH_LINK_UP;
 		} else if (speed == GXIO_MPIPE_LINK_10G) {
-			new.link_speed = ETH_LINK_SPEED_10000;
+			new.link_speed = ETH_SPEED_NUM_10G;
 			new.link_duplex = ETH_LINK_FULL_DUPLEX;
 			new.link_status = ETH_LINK_UP;
 		}
diff --git a/drivers/net/nfp/nfp_net.c b/drivers/net/nfp/nfp_net.c
index 80dda85..18ea0f4 100644
--- a/drivers/net/nfp/nfp_net.c
+++ b/drivers/net/nfp/nfp_net.c
@@ -821,7 +821,7 @@ nfp_net_link_update(struct rte_eth_dev *dev, __rte_unused int wait_to_complete)
 
 	link.link_duplex = ETH_LINK_FULL_DUPLEX;
 	/* Other cards can limit the tx and rx rate per VF */
-	link.link_speed = ETH_LINK_SPEED_40G;
+	link.link_speed = ETH_SPEED_NUM_40G;
 
 	if (old.link_status != link.link_status) {
 		nfp_net_dev_atomic_write_link_status(dev, &link);
diff --git a/drivers/net/null/rte_eth_null.c b/drivers/net/null/rte_eth_null.c
index 6adea91..5640585 100644
--- a/drivers/net/null/rte_eth_null.c
+++ b/drivers/net/null/rte_eth_null.c
@@ -89,7 +89,7 @@ struct pmd_internals {
 static struct ether_addr eth_addr = { .addr_bytes = {0} };
 static const char *drivername = "Null PMD";
 static struct rte_eth_link pmd_link = {
-	.link_speed = 10000,
+	.link_speed = ETH_SPEED_NUM_10G,
 	.link_duplex = ETH_LINK_FULL_DUPLEX,
 	.link_status = ETH_LINK_DOWN,
 };
diff --git a/drivers/net/pcap/rte_eth_pcap.c b/drivers/net/pcap/rte_eth_pcap.c
index b90c725..c657951 100644
--- a/drivers/net/pcap/rte_eth_pcap.c
+++ b/drivers/net/pcap/rte_eth_pcap.c
@@ -123,7 +123,7 @@ static int open_single_iface(const char *iface, pcap_t **pcap);
 static struct ether_addr eth_addr = { .addr_bytes = { 0, 0, 0, 0x1, 0x2, 0x3 } };
 static const char *drivername = "Pcap PMD";
 static struct rte_eth_link pmd_link = {
-		.link_speed = 10000,
+		.link_speed = ETH_SPEED_NUM_10G,
 		.link_duplex = ETH_LINK_FULL_DUPLEX,
 		.link_status = ETH_LINK_DOWN,
 };
diff --git a/drivers/net/ring/rte_eth_ring.c b/drivers/net/ring/rte_eth_ring.c
index 4335c6a..58685e9 100644
--- a/drivers/net/ring/rte_eth_ring.c
+++ b/drivers/net/ring/rte_eth_ring.c
@@ -77,7 +77,7 @@ struct pmd_internals {
 
 static const char *drivername = "Rings PMD";
 static struct rte_eth_link pmd_link = {
-		.link_speed = 10000,
+		.link_speed = ETH_SPEED_NUM_10G,
 		.link_duplex = ETH_LINK_FULL_DUPLEX,
 		.link_status = ETH_LINK_DOWN,
 };
diff --git a/drivers/net/szedata2/rte_eth_szedata2.c b/drivers/net/szedata2/rte_eth_szedata2.c
index 47aa7e3..dd1ae9e 100644
--- a/drivers/net/szedata2/rte_eth_szedata2.c
+++ b/drivers/net/szedata2/rte_eth_szedata2.c
@@ -1149,10 +1149,10 @@ eth_link_update(struct rte_eth_dev *dev,
 
 	switch (cgmii_link_speed(ibuf)) {
 	case SZEDATA2_LINK_SPEED_10G:
-		link.link_speed = ETH_LINK_SPEED_10G;
+		link.link_speed = ETH_SPEED_NUM_10G;
 		break;
 	case SZEDATA2_LINK_SPEED_40G:
-		link.link_speed = ETH_LINK_SPEED_40G;
+		link.link_speed = ETH_SPEED_NUM_40G;
 		break;
 	case SZEDATA2_LINK_SPEED_100G:
 		/*
@@ -1161,10 +1161,10 @@ eth_link_update(struct rte_eth_dev *dev,
 		 * will be changed to support 100Gbps speed change
 		 * this value to 100G.
 		 */
-		link.link_speed = ETH_LINK_SPEED_10G;
+		link.link_speed = ETH_SPEED_NUM_10G;
 		break;
 	default:
-		link.link_speed = ETH_LINK_SPEED_10G;
+		link.link_speed = ETH_SPEED_NUM_10G;
 		break;
 	}
 
diff --git a/drivers/net/vmxnet3/vmxnet3_ethdev.c b/drivers/net/vmxnet3/vmxnet3_ethdev.c
index 3f26217..6afa14e 100644
--- a/drivers/net/vmxnet3/vmxnet3_ethdev.c
+++ b/drivers/net/vmxnet3/vmxnet3_ethdev.c
@@ -779,7 +779,7 @@ vmxnet3_dev_link_update(struct rte_eth_dev *dev, __attribute__((unused)) int wai
 	if (ret & 0x1) {
 		link.link_status = ETH_LINK_UP;
 		link.link_duplex = ETH_LINK_FULL_DUPLEX;
-		link.link_speed = ETH_LINK_SPEED_10000;
+		link.link_speed = ETH_SPEED_NUM_10G;
 	}
 
 	vmxnet3_dev_atomic_write_link_status(dev, &link);
diff --git a/drivers/net/xenvirt/rte_eth_xenvirt.c b/drivers/net/xenvirt/rte_eth_xenvirt.c
index 9453a06..77d3ba1 100644
--- a/drivers/net/xenvirt/rte_eth_xenvirt.c
+++ b/drivers/net/xenvirt/rte_eth_xenvirt.c
@@ -70,7 +70,7 @@ static int virtio_idx = 0;
 static const char *drivername = "xen virtio PMD";
 
 static struct rte_eth_link pmd_link = {
-		.link_speed = 10000,
+		.link_speed = ETH_SPEED_NUM_10G,
 		.link_duplex = ETH_LINK_FULL_DUPLEX,
 		.link_status = ETH_LINK_DOWN,
 };
diff --git a/lib/librte_ether/rte_ethdev.h b/lib/librte_ether/rte_ethdev.h
index 2d13f92..bc7d607 100644
--- a/lib/librte_ether/rte_ethdev.h
+++ b/lib/librte_ether/rte_ethdev.h
@@ -242,23 +242,30 @@ struct rte_eth_stats {
 };
 
 /**
+ * Ethernet numeric link speeds in Mbps
+ */
+#define ETH_LINK_SPEED_AUTONEG     0 /**< Auto-negotiate link speed. */
+#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 */
+
+/**
  * A structure used to retrieve link-level information of an Ethernet port.
  */
 struct rte_eth_link {
-	uint16_t link_speed;      /**< ETH_LINK_SPEED_[10, 100, 1000, 10000] */
+	uint16_t link_speed;      /**< ETH_SPEED_NUM_ */
 	uint16_t link_duplex;     /**< ETH_LINK_[HALF/FULL]_DUPLEX */
 	uint8_t  link_status : 1; /**< ETH_LINK_[DOWN/UP] */
 }__attribute__((aligned(8)));     /**< aligned for atomic64 read/write */
 
-#define ETH_LINK_SPEED_AUTONEG  0       /**< Auto-negotiate link speed. */
-#define ETH_LINK_SPEED_10       10      /**< 10 megabits/second. */
-#define ETH_LINK_SPEED_100      100     /**< 100 megabits/second. */
-#define ETH_LINK_SPEED_1000     1000    /**< 1 gigabits/second. */
-#define ETH_LINK_SPEED_10000    10000   /**< 10 gigabits/second. */
-#define ETH_LINK_SPEED_10G      10000   /**< alias of 10 gigabits/second. */
-#define ETH_LINK_SPEED_20G      20000   /**< 20 gigabits/second. */
-#define ETH_LINK_SPEED_40G      40000   /**< 40 gigabits/second. */
-
 /* Utility constants */
 #define ETH_LINK_AUTONEG_DUPLEX 0       /**< Auto-negotiate duplex. */
 #define ETH_LINK_HALF_DUPLEX    1       /**< Half-duplex connection. */
@@ -779,7 +786,7 @@ struct rte_intr_conf {
  */
 struct rte_eth_conf {
 	uint16_t link_speed;
-	/**< ETH_LINK_SPEED_10[0|00|000], or 0 for autonegotation */
+	/**< ETH_SPEED_NUM_ or 0 for autonegotiation */
 	uint16_t link_duplex;
 	/**< ETH_LINK_[HALF_DUPLEX|FULL_DUPLEX], or 0 for autonegotation */
 	struct rte_eth_rxmode rxmode; /**< Port RX configuration. */
-- 
2.7.0

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

* [PATCH v12 5/8] ethdev: add speed capabilities
  2016-03-25 19:42             ` [PATCH v12 " Thomas Monjalon
                                 ` (3 preceding siblings ...)
  2016-03-25 19:42               ` [PATCH v12 4/8] ethdev: rename link speed constants Thomas Monjalon
@ 2016-03-25 19:42               ` Thomas Monjalon
  2016-03-25 19:42               ` [PATCH v12 6/8] ethdev: redesign link speed config Thomas Monjalon
                                 ` (3 subsequent siblings)
  8 siblings, 0 replies; 167+ messages in thread
From: Thomas Monjalon @ 2016-03-25 19:42 UTC (permalink / raw)
  To: marcdevel, bruce.richardson, declan.doherty, konstantin.ananyev,
	wenzhuo.lu, helin.zhang, jing.d.chen, harish.patil,
	rahul.lakkireddy, johndale, vido, adrien.mazarguil,
	alejandro.lucero
  Cc: dev

From: Marc Sune <marcdevel@gmail.com>

The speed capabilities of a device can be retrieved with
rte_eth_dev_info_get().

The new field speed_capa is initialized in the drivers without
taking care of device characteristics in this patch.
When the capabilities of a driver are accurate, the table in
overview.rst must be filled.

Signed-off-by: Marc Sune <marcdevel@gmail.com>
---
 doc/guides/nics/overview.rst           |  1 +
 doc/guides/rel_notes/release_16_04.rst |  8 ++++++++
 drivers/net/bnx2x/bnx2x_ethdev.c       |  1 +
 drivers/net/cxgbe/cxgbe_ethdev.c       |  1 +
 drivers/net/e1000/em_ethdev.c          |  4 ++++
 drivers/net/e1000/igb_ethdev.c         |  4 ++++
 drivers/net/ena/ena_ethdev.c           |  9 +++++++++
 drivers/net/fm10k/fm10k_ethdev.c       |  4 ++++
 drivers/net/i40e/i40e_ethdev.c         |  8 ++++++++
 drivers/net/ixgbe/ixgbe_ethdev.c       |  8 ++++++++
 drivers/net/mlx4/mlx4.c                |  6 ++++++
 drivers/net/mlx5/mlx5_ethdev.c         |  8 ++++++++
 drivers/net/nfp/nfp_net.c              |  2 ++
 lib/librte_ether/rte_ethdev.h          | 21 +++++++++++++++++++++
 14 files changed, 85 insertions(+)

diff --git a/doc/guides/nics/overview.rst b/doc/guides/nics/overview.rst
index 542479a..62f1868 100644
--- a/doc/guides/nics/overview.rst
+++ b/doc/guides/nics/overview.rst
@@ -86,6 +86,7 @@ Most of these differences are summarized below.
                                           e   e       e   e   e                     e
                                           c   c       c   c   c                     c
    ==================== = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
+   speed capabilities
    link status                  X       X X                                   X X
    link status event                    X X                                     X
    queue status event                                                           X
diff --git a/doc/guides/rel_notes/release_16_04.rst b/doc/guides/rel_notes/release_16_04.rst
index 79d76e1..9e7b0b7 100644
--- a/doc/guides/rel_notes/release_16_04.rst
+++ b/doc/guides/rel_notes/release_16_04.rst
@@ -47,6 +47,11 @@ This section should contain new features added in this release. Sample format:
   A new function ``rte_pktmbuf_alloc_bulk()`` has been added to allow the user
   to allocate a bulk of mbufs.
 
+* **Added device link speed capabilities.**
+
+  The structure ``rte_eth_dev_info`` has now a ``speed_capa`` bitmap, which
+  allows the application to know the supported speeds of each device.
+
 * **Added new poll-mode driver for Amazon Elastic Network Adapters (ENA).**
 
   The driver operates variety of ENA adapters through feature negotiation
@@ -456,6 +461,9 @@ This section should contain API changes. Sample format:
   All drivers are now counting the missed packets only once, i.e. drivers will
   not increment ierrors anymore for missed packets.
 
+* The ethdev structure ``rte_eth_dev_info`` was changed to support device
+  speed capabilities.
+
 * The functions ``rte_eth_dev_udp_tunnel_add`` and ``rte_eth_dev_udp_tunnel_delete``
   have been renamed into ``rte_eth_dev_udp_tunnel_port_add`` and
   ``rte_eth_dev_udp_tunnel_port_delete``.
diff --git a/drivers/net/bnx2x/bnx2x_ethdev.c b/drivers/net/bnx2x/bnx2x_ethdev.c
index a3c6c01..897081f 100644
--- a/drivers/net/bnx2x/bnx2x_ethdev.c
+++ b/drivers/net/bnx2x/bnx2x_ethdev.c
@@ -327,6 +327,7 @@ bnx2x_dev_infos_get(struct rte_eth_dev *dev, __rte_unused struct rte_eth_dev_inf
 	dev_info->min_rx_bufsize = BNX2X_MIN_RX_BUF_SIZE;
 	dev_info->max_rx_pktlen  = BNX2X_MAX_RX_PKT_LEN;
 	dev_info->max_mac_addrs  = BNX2X_MAX_MAC_ADDRS;
+	dev_info->speed_capa = ETH_LINK_SPEED_10G | ETH_LINK_SPEED_20G;
 }
 
 static void
diff --git a/drivers/net/cxgbe/cxgbe_ethdev.c b/drivers/net/cxgbe/cxgbe_ethdev.c
index 8845c76..bb134e5 100644
--- a/drivers/net/cxgbe/cxgbe_ethdev.c
+++ b/drivers/net/cxgbe/cxgbe_ethdev.c
@@ -171,6 +171,7 @@ static void cxgbe_dev_info_get(struct rte_eth_dev *eth_dev,
 
 	device_info->rx_desc_lim = cxgbe_desc_lim;
 	device_info->tx_desc_lim = cxgbe_desc_lim;
+	device_info->speed_capa = ETH_LINK_SPEED_10G | ETH_LINK_SPEED_40G;
 }
 
 static void cxgbe_dev_promiscuous_enable(struct rte_eth_dev *eth_dev)
diff --git a/drivers/net/e1000/em_ethdev.c b/drivers/net/e1000/em_ethdev.c
index 473d77f..d5f8c7f 100644
--- a/drivers/net/e1000/em_ethdev.c
+++ b/drivers/net/e1000/em_ethdev.c
@@ -1054,6 +1054,10 @@ eth_em_infos_get(struct rte_eth_dev *dev, struct rte_eth_dev_info *dev_info)
 		.nb_min = E1000_MIN_RING_DESC,
 		.nb_align = EM_TXD_ALIGN,
 	};
+
+	dev_info->speed_capa = ETH_LINK_SPEED_10M_HD | ETH_LINK_SPEED_10M |
+			ETH_LINK_SPEED_100M_HD | ETH_LINK_SPEED_100M |
+			ETH_LINK_SPEED_1G;
 }
 
 /* return 0 means link status changed, -1 means not changed */
diff --git a/drivers/net/e1000/igb_ethdev.c b/drivers/net/e1000/igb_ethdev.c
index 86f25f6..95d1711 100644
--- a/drivers/net/e1000/igb_ethdev.c
+++ b/drivers/net/e1000/igb_ethdev.c
@@ -1921,6 +1921,10 @@ eth_igb_infos_get(struct rte_eth_dev *dev, struct rte_eth_dev_info *dev_info)
 
 	dev_info->rx_desc_lim = rx_desc_lim;
 	dev_info->tx_desc_lim = tx_desc_lim;
+
+	dev_info->speed_capa = ETH_LINK_SPEED_10M_HD | ETH_LINK_SPEED_10M |
+			ETH_LINK_SPEED_100M_HD | ETH_LINK_SPEED_100M |
+			ETH_LINK_SPEED_1G;
 }
 
 static const uint32_t *
diff --git a/drivers/net/ena/ena_ethdev.c b/drivers/net/ena/ena_ethdev.c
index 1046286..4e403af 100644
--- a/drivers/net/ena/ena_ethdev.c
+++ b/drivers/net/ena/ena_ethdev.c
@@ -1170,6 +1170,15 @@ static void ena_infos_get(struct rte_eth_dev *dev,
 	ena_dev = &adapter->ena_dev;
 	ena_assert_msg(ena_dev != NULL, "Uninitialized device");
 
+	dev_info->speed_capa =
+			ETH_LINK_SPEED_1G   |
+			ETH_LINK_SPEED_2_5G |
+			ETH_LINK_SPEED_5G   |
+			ETH_LINK_SPEED_10G  |
+			ETH_LINK_SPEED_25G  |
+			ETH_LINK_SPEED_40G  |
+			ETH_LINK_SPEED_50G;
+
 	/* Get supported features from HW */
 	rc = ena_com_get_dev_attr_feat(ena_dev, &feat);
 	if (unlikely(rc)) {
diff --git a/drivers/net/fm10k/fm10k_ethdev.c b/drivers/net/fm10k/fm10k_ethdev.c
index 53aa1bb..85ad0df 100644
--- a/drivers/net/fm10k/fm10k_ethdev.c
+++ b/drivers/net/fm10k/fm10k_ethdev.c
@@ -1410,6 +1410,10 @@ fm10k_dev_infos_get(struct rte_eth_dev *dev,
 		.nb_min = FM10K_MIN_TX_DESC,
 		.nb_align = FM10K_MULT_TX_DESC,
 	};
+
+	dev_info->speed_capa = ETH_LINK_SPEED_1G | ETH_LINK_SPEED_2_5G |
+			ETH_LINK_SPEED_10G | ETH_LINK_SPEED_25G |
+			ETH_LINK_SPEED_40G;
 }
 
 #ifdef RTE_LIBRTE_FM10K_RX_OLFLAGS_ENABLE
diff --git a/drivers/net/i40e/i40e_ethdev.c b/drivers/net/i40e/i40e_ethdev.c
index cce9e6f..dce31db 100644
--- a/drivers/net/i40e/i40e_ethdev.c
+++ b/drivers/net/i40e/i40e_ethdev.c
@@ -2287,6 +2287,7 @@ static void
 i40e_dev_info_get(struct rte_eth_dev *dev, struct rte_eth_dev_info *dev_info)
 {
 	struct i40e_pf *pf = I40E_DEV_PRIVATE_TO_PF(dev->data->dev_private);
+	struct i40e_hw *hw = I40E_DEV_PRIVATE_TO_HW(dev->data->dev_private);
 	struct i40e_vsi *vsi = pf->main_vsi;
 
 	dev_info->max_rx_queues = vsi->nb_qps;
@@ -2358,6 +2359,13 @@ i40e_dev_info_get(struct rte_eth_dev *dev, struct rte_eth_dev_info *dev_info)
 		dev_info->max_rx_queues += dev_info->vmdq_queue_num;
 		dev_info->max_tx_queues += dev_info->vmdq_queue_num;
 	}
+
+	if (i40e_is_40G_device(hw->device_id))
+		/* For XL710 */
+		dev_info->speed_capa = ETH_LINK_SPEED_1G | ETH_LINK_SPEED_10G;
+	else
+		/* For X710 */
+		dev_info->speed_capa = ETH_LINK_SPEED_10G | ETH_LINK_SPEED_40G;
 }
 
 static int
diff --git a/drivers/net/ixgbe/ixgbe_ethdev.c b/drivers/net/ixgbe/ixgbe_ethdev.c
index a0179d2..a98e8eb 100644
--- a/drivers/net/ixgbe/ixgbe_ethdev.c
+++ b/drivers/net/ixgbe/ixgbe_ethdev.c
@@ -2960,6 +2960,14 @@ ixgbe_dev_info_get(struct rte_eth_dev *dev, struct rte_eth_dev_info *dev_info)
 	dev_info->hash_key_size = IXGBE_HKEY_MAX_INDEX * sizeof(uint32_t);
 	dev_info->reta_size = ixgbe_reta_size_get(hw->mac.type);
 	dev_info->flow_type_rss_offloads = IXGBE_RSS_OFFLOAD_ALL;
+
+	dev_info->speed_capa = ETH_LINK_SPEED_1G | ETH_LINK_SPEED_10G;
+	if (hw->mac.type == ixgbe_mac_X540 ||
+	    hw->mac.type == ixgbe_mac_X540_vf ||
+	    hw->mac.type == ixgbe_mac_X550 ||
+	    hw->mac.type == ixgbe_mac_X550_vf) {
+		dev_info->speed_capa |= ETH_LINK_SPEED_100M;
+	}
 }
 
 static const uint32_t *
diff --git a/drivers/net/mlx4/mlx4.c b/drivers/net/mlx4/mlx4.c
index f946f08..59ac423 100644
--- a/drivers/net/mlx4/mlx4.c
+++ b/drivers/net/mlx4/mlx4.c
@@ -4313,6 +4313,12 @@ mlx4_dev_infos_get(struct rte_eth_dev *dev, struct rte_eth_dev_info *info)
 		 0);
 	if (priv_get_ifname(priv, &ifname) == 0)
 		info->if_index = if_nametoindex(ifname);
+	info->speed_capa =
+			ETH_LINK_SPEED_1G |
+			ETH_LINK_SPEED_10G |
+			ETH_LINK_SPEED_20G |
+			ETH_LINK_SPEED_40G |
+			ETH_LINK_SPEED_56G;
 	priv_unlock(priv);
 }
 
diff --git a/drivers/net/mlx5/mlx5_ethdev.c b/drivers/net/mlx5/mlx5_ethdev.c
index 58bfa16..d7a0eea 100644
--- a/drivers/net/mlx5/mlx5_ethdev.c
+++ b/drivers/net/mlx5/mlx5_ethdev.c
@@ -559,6 +559,14 @@ mlx5_dev_infos_get(struct rte_eth_dev *dev, struct rte_eth_dev_info *info)
 	 * size if it is not fixed.
 	 * The API should be updated to solve this problem. */
 	info->reta_size = priv->ind_table_max_size;
+	info->speed_capa =
+			ETH_LINK_SPEED_1G |
+			ETH_LINK_SPEED_10G |
+			ETH_LINK_SPEED_20G |
+			ETH_LINK_SPEED_25G |
+			ETH_LINK_SPEED_40G |
+			ETH_LINK_SPEED_50G |
+			ETH_LINK_SPEED_56G;
 	priv_unlock(priv);
 }
 
diff --git a/drivers/net/nfp/nfp_net.c b/drivers/net/nfp/nfp_net.c
index 18ea0f4..bdeb21f 100644
--- a/drivers/net/nfp/nfp_net.c
+++ b/drivers/net/nfp/nfp_net.c
@@ -1061,6 +1061,8 @@ nfp_net_infos_get(struct rte_eth_dev *dev, struct rte_eth_dev_info *dev_info)
 
 	dev_info->reta_size = NFP_NET_CFG_RSS_ITBL_SZ;
 	dev_info->hash_key_size = NFP_NET_CFG_RSS_KEY_SZ;
+
+	dev_info->speed_capa = ETH_LINK_SPEED_50G;
 }
 
 static const uint32_t *
diff --git a/lib/librte_ether/rte_ethdev.h b/lib/librte_ether/rte_ethdev.h
index bc7d607..49fdcb7 100644
--- a/lib/librte_ether/rte_ethdev.h
+++ b/lib/librte_ether/rte_ethdev.h
@@ -242,6 +242,23 @@ struct rte_eth_stats {
 };
 
 /**
+ * Device supported speeds bitmap flags
+ */
+#define ETH_LINK_SPEED_10M_HD   (1 <<  1)  /**<  10 Mbps half-duplex */
+#define ETH_LINK_SPEED_10M      (1 <<  2)  /**<  10 Mbps full-duplex */
+#define ETH_LINK_SPEED_100M_HD  (1 <<  3)  /**< 100 Mbps half-duplex */
+#define ETH_LINK_SPEED_100M     (1 <<  4)  /**< 100 Mbps full-duplex */
+#define ETH_LINK_SPEED_1G       (1 <<  5)  /**<   1 Gbps */
+#define ETH_LINK_SPEED_2_5G     (1 <<  6)  /**< 2.5 Gbps */
+#define ETH_LINK_SPEED_5G       (1 <<  7)  /**<   5 Gbps */
+#define ETH_LINK_SPEED_10G      (1 <<  8)  /**<  10 Gbps */
+#define ETH_LINK_SPEED_20G      (1 <<  9)  /**<  20 Gbps */
+#define ETH_LINK_SPEED_25G      (1 << 10)  /**<  25 Gbps */
+#define ETH_LINK_SPEED_40G      (1 << 11)  /**<  40 Gbps */
+#define ETH_LINK_SPEED_50G      (1 << 12)  /**<  50 Gbps */
+#define ETH_LINK_SPEED_56G      (1 << 13)  /**<  56 Gbps */
+
+/**
  * Ethernet numeric link speeds in Mbps
  */
 #define ETH_LINK_SPEED_AUTONEG     0 /**< Auto-negotiate link speed. */
@@ -850,6 +867,9 @@ struct rte_eth_conf {
 #define DEV_TX_OFFLOAD_OUTER_IPV4_CKSUM 0x00000080 /**< Used for tunneling packet. */
 #define DEV_TX_OFFLOAD_QINQ_INSERT 0x00000100
 
+/**
+ * Ethernet device information
+ */
 struct rte_eth_dev_info {
 	struct rte_pci_device *pci_dev; /**< Device PCI information. */
 	const char *driver_name; /**< Device Driver name. */
@@ -878,6 +898,7 @@ struct rte_eth_dev_info {
 	uint16_t vmdq_pool_base;  /**< First ID of VMDQ pools. */
 	struct rte_eth_desc_lim rx_desc_lim;  /**< RX descriptors limits */
 	struct rte_eth_desc_lim tx_desc_lim;  /**< TX descriptors limits */
+	uint32_t speed_capa;  /**< Supported speeds bitmap (ETH_LINK_SPEED_). */
 };
 
 /**
-- 
2.7.0

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

* [PATCH v12 6/8] ethdev: redesign link speed config
  2016-03-25 19:42             ` [PATCH v12 " Thomas Monjalon
                                 ` (4 preceding siblings ...)
  2016-03-25 19:42               ` [PATCH v12 5/8] ethdev: add speed capabilities Thomas Monjalon
@ 2016-03-25 19:42               ` Thomas Monjalon
  2016-03-25 19:42               ` [PATCH v12 7/8] ethdev: convert speed number to bitmap flag Thomas Monjalon
                                 ` (2 subsequent siblings)
  8 siblings, 0 replies; 167+ messages in thread
From: Thomas Monjalon @ 2016-03-25 19:42 UTC (permalink / raw)
  To: marcdevel, bruce.richardson, declan.doherty, konstantin.ananyev,
	wenzhuo.lu, helin.zhang, jing.d.chen, harish.patil,
	rahul.lakkireddy, johndale, vido, adrien.mazarguil,
	alejandro.lucero
  Cc: dev

From: Marc Sune <marcdevel@gmail.com>

This patch redesigns the API to set the link speed/s configuration
of an ethernet port. Specifically:

- it allows to define a set of advertised speeds for
  auto-negociation.
- it allows to disable link auto-negociation (single fixed speed).
- default: auto-negociate all supported speeds.

A flag autoneg in struct rte_eth_link indicates if link speed was a
result of auto-negociation or was fixed by configuration.

Signed-off-by: Marc Sune <marcdevel@gmail.com>
Tested-by: Nelio Laranjeiro <nelio.laranjeiro@6wind.com>
Signed-off-by: Thomas Monjalon <thomas.monjalon@6wind.com>
---

PLEASE REVIEW CAREFULLY THIS PATCH

 app/test-pmd/cmdline.c                    | 26 ++++----
 doc/guides/rel_notes/deprecation.rst      |  3 -
 doc/guides/rel_notes/release_16_04.rst    |  9 +++
 drivers/net/af_packet/rte_eth_af_packet.c |  1 +
 drivers/net/bnx2x/bnx2x_ethdev.c          |  4 +-
 drivers/net/bonding/rte_eth_bond_8023ad.c |  2 +-
 drivers/net/e1000/em_ethdev.c             | 99 +++++++++++++++----------------
 drivers/net/e1000/igb_ethdev.c            | 94 +++++++++++++++--------------
 drivers/net/i40e/i40e_ethdev.c            | 48 +++++++--------
 drivers/net/i40e/i40e_ethdev_vf.c         |  7 ++-
 drivers/net/ixgbe/ixgbe_ethdev.c          | 46 ++++++--------
 drivers/net/mlx4/mlx4.c                   |  2 +
 drivers/net/mpipe/mpipe_tilegx.c          |  2 +
 drivers/net/null/rte_eth_null.c           |  1 +
 drivers/net/pcap/rte_eth_pcap.c           |  1 +
 drivers/net/ring/rte_eth_ring.c           |  1 +
 drivers/net/szedata2/rte_eth_szedata2.c   |  2 +
 drivers/net/vmxnet3/vmxnet3_ethdev.c      |  1 +
 drivers/net/xenvirt/rte_eth_xenvirt.c     |  1 +
 examples/ip_pipeline/config_parse.c       |  3 +-
 lib/librte_ether/rte_ethdev.h             | 29 +++++----
 21 files changed, 196 insertions(+), 186 deletions(-)

diff --git a/app/test-pmd/cmdline.c b/app/test-pmd/cmdline.c
index 815b53b..741cac3 100644
--- a/app/test-pmd/cmdline.c
+++ b/app/test-pmd/cmdline.c
@@ -989,7 +989,7 @@ struct cmd_config_speed_all {
 };
 
 static int
-parse_and_check_speed_duplex(char *speedstr, char *duplexstr, uint16_t *speed)
+parse_and_check_speed_duplex(char *speedstr, char *duplexstr, uint32_t *speed)
 {
 
 	int duplex;
@@ -1006,20 +1006,22 @@ parse_and_check_speed_duplex(char *speedstr, char *duplexstr, uint16_t *speed)
 	}
 
 	if (!strcmp(speedstr, "10")) {
-		*speed = ETH_SPEED_NUM_10M;
+		*speed = (duplex == ETH_LINK_HALF_DUPLEX) ?
+				ETH_LINK_SPEED_10M_HD : ETH_LINK_SPEED_10M;
 	} else if (!strcmp(speedstr, "100")) {
-		*speed = ETH_SPEED_NUM_100M;
+		*speed = (duplex == ETH_LINK_HALF_DUPLEX) ?
+				ETH_LINK_SPEED_100M_HD : ETH_LINK_SPEED_100M;
 	} else {
 		if (duplex != ETH_LINK_FULL_DUPLEX) {
 			printf("Invalid speed/duplex parameters\n");
 			return -1;
 		}
 		if (!strcmp(speedstr, "1000")) {
-			*speed = ETH_SPEED_NUM_1G;
+			*speed = ETH_LINK_SPEED_1G;
 		} else if (!strcmp(speedstr, "10000")) {
-			*speed = ETH_SPEED_NUM_10G;
+			*speed = ETH_LINK_SPEED_10G;
 		} else if (!strcmp(speedstr, "40000")) {
-			*speed = ETH_SPEED_NUM_40G;
+			*speed = ETH_LINK_SPEED_40G;
 		} else if (!strcmp(speedstr, "auto")) {
 			*speed = ETH_LINK_SPEED_AUTONEG;
 		} else {
@@ -1037,8 +1039,7 @@ cmd_config_speed_all_parsed(void *parsed_result,
 			__attribute__((unused)) void *data)
 {
 	struct cmd_config_speed_all *res = parsed_result;
-	uint16_t link_speed = ETH_LINK_SPEED_AUTONEG;
-	uint16_t link_duplex = 0;
+	uint32_t link_speed;
 	portid_t pid;
 
 	if (!all_ports_stopped()) {
@@ -1051,8 +1052,7 @@ cmd_config_speed_all_parsed(void *parsed_result,
 		return;
 
 	FOREACH_PORT(pid, ports) {
-		ports[pid].dev_conf.link_speed = link_speed;
-		ports[pid].dev_conf.link_duplex = link_duplex;
+		ports[pid].dev_conf.link_speeds = link_speed;
 	}
 
 	cmd_reconfig_device_queue(RTE_PORT_ALL, 1, 1);
@@ -1110,8 +1110,7 @@ cmd_config_speed_specific_parsed(void *parsed_result,
 				__attribute__((unused)) void *data)
 {
 	struct cmd_config_speed_specific *res = parsed_result;
-	uint16_t link_speed = ETH_LINK_SPEED_AUTONEG;
-	uint16_t link_duplex = 0;
+	uint32_t link_speed;
 
 	if (!all_ports_stopped()) {
 		printf("Please stop all ports first\n");
@@ -1125,8 +1124,7 @@ cmd_config_speed_specific_parsed(void *parsed_result,
 			&link_speed) < 0)
 		return;
 
-	ports[res->id].dev_conf.link_speed = link_speed;
-	ports[res->id].dev_conf.link_duplex = link_duplex;
+	ports[res->id].dev_conf.link_speeds = link_speed;
 
 	cmd_reconfig_device_queue(RTE_PORT_ALL, 1, 1);
 }
diff --git a/doc/guides/rel_notes/deprecation.rst b/doc/guides/rel_notes/deprecation.rst
index 179e30f..c47610d 100644
--- a/doc/guides/rel_notes/deprecation.rst
+++ b/doc/guides/rel_notes/deprecation.rst
@@ -19,9 +19,6 @@ Deprecation Notices
   ibadcrc, ibadlen, imcasts, fdirmatch, fdirmiss,
   tx_pause_xon, rx_pause_xon, tx_pause_xoff, rx_pause_xoff
 
-* The ethdev structures rte_eth_link, rte_eth_dev_info and rte_eth_conf
-  must be updated to support 100G link and to have a cleaner link speed API.
-
 * ABI changes are planned for adding four new flow types. This impacts
   RTE_ETH_FLOW_MAX. The release 2.2 does not contain these ABI changes,
   but release 2.3 will. [postponed]
diff --git a/doc/guides/rel_notes/release_16_04.rst b/doc/guides/rel_notes/release_16_04.rst
index 9e7b0b7..c891a55 100644
--- a/doc/guides/rel_notes/release_16_04.rst
+++ b/doc/guides/rel_notes/release_16_04.rst
@@ -52,6 +52,12 @@ This section should contain new features added in this release. Sample format:
   The structure ``rte_eth_dev_info`` has now a ``speed_capa`` bitmap, which
   allows the application to know the supported speeds of each device.
 
+* **Added bitmap of link speeds to advertise.**
+
+  Allow defining a set of advertised speeds for auto-negotiation,
+  explicitly disabling link auto-negotiation (single speed)
+  and full auto-negotiation.
+
 * **Added new poll-mode driver for Amazon Elastic Network Adapters (ENA).**
 
   The driver operates variety of ENA adapters through feature negotiation
@@ -464,6 +470,9 @@ This section should contain API changes. Sample format:
 * The ethdev structure ``rte_eth_dev_info`` was changed to support device
   speed capabilities.
 
+* The ethdev structures ``rte_eth_link`` and ``rte_eth_conf`` were changed to
+  support the new link API.
+
 * The functions ``rte_eth_dev_udp_tunnel_add`` and ``rte_eth_dev_udp_tunnel_delete``
   have been renamed into ``rte_eth_dev_udp_tunnel_port_add`` and
   ``rte_eth_dev_udp_tunnel_port_delete``.
diff --git a/drivers/net/af_packet/rte_eth_af_packet.c b/drivers/net/af_packet/rte_eth_af_packet.c
index 641f849..f17bd7e 100644
--- a/drivers/net/af_packet/rte_eth_af_packet.c
+++ b/drivers/net/af_packet/rte_eth_af_packet.c
@@ -119,6 +119,7 @@ static struct rte_eth_link pmd_link = {
 	.link_speed = ETH_SPEED_NUM_10G,
 	.link_duplex = ETH_LINK_FULL_DUPLEX,
 	.link_status = ETH_LINK_DOWN,
+	.link_autoneg = ETH_LINK_SPEED_AUTONEG
 };
 
 static uint16_t
diff --git a/drivers/net/bnx2x/bnx2x_ethdev.c b/drivers/net/bnx2x/bnx2x_ethdev.c
index 897081f..af84175 100644
--- a/drivers/net/bnx2x/bnx2x_ethdev.c
+++ b/drivers/net/bnx2x/bnx2x_ethdev.c
@@ -44,9 +44,9 @@ bnx2x_link_update(struct rte_eth_dev *dev)
 		case DUPLEX_HALF:
 			dev->data->dev_link.link_duplex = ETH_LINK_HALF_DUPLEX;
 			break;
-		default:
-			dev->data->dev_link.link_duplex = ETH_LINK_AUTONEG_DUPLEX;
 	}
+	dev->data->dev_link.link_autoneg = (dev->data->dev_conf.link_speeds &
+			ETH_LINK_SPEED_AUTONEG);
 	dev->data->dev_link.link_status = sc->link_vars.link_up;
 }
 
diff --git a/drivers/net/bonding/rte_eth_bond_8023ad.c b/drivers/net/bonding/rte_eth_bond_8023ad.c
index ac8306f..cca7cc3 100644
--- a/drivers/net/bonding/rte_eth_bond_8023ad.c
+++ b/drivers/net/bonding/rte_eth_bond_8023ad.c
@@ -708,7 +708,7 @@ link_speed_key(uint16_t speed) {
 	uint16_t key_speed;
 
 	switch (speed) {
-	case ETH_LINK_SPEED_AUTONEG:
+	case ETH_SPEED_NUM_NONE:
 		key_speed = 0x00;
 		break;
 	case ETH_SPEED_NUM_10M:
diff --git a/drivers/net/e1000/em_ethdev.c b/drivers/net/e1000/em_ethdev.c
index d5f8c7f..3e26ab0 100644
--- a/drivers/net/e1000/em_ethdev.c
+++ b/drivers/net/e1000/em_ethdev.c
@@ -538,6 +538,9 @@ eth_em_start(struct rte_eth_dev *dev)
 	struct rte_intr_handle *intr_handle = &dev->pci_dev->intr_handle;
 	int ret, mask;
 	uint32_t intr_vector = 0;
+	uint32_t *speeds;
+	int num_speeds;
+	bool autoneg;
 
 	PMD_INIT_FUNC_TRACE();
 
@@ -612,56 +615,46 @@ eth_em_start(struct rte_eth_dev *dev)
 	E1000_WRITE_REG(hw, E1000_ITR, UINT16_MAX);
 
 	/* Setup link speed and duplex */
-	switch (dev->data->dev_conf.link_speed) {
-	case ETH_LINK_SPEED_AUTONEG:
-		if (dev->data->dev_conf.link_duplex == ETH_LINK_AUTONEG_DUPLEX)
-			hw->phy.autoneg_advertised = E1000_ALL_SPEED_DUPLEX;
-		else if (dev->data->dev_conf.link_duplex ==
-					ETH_LINK_HALF_DUPLEX)
-			hw->phy.autoneg_advertised = E1000_ALL_HALF_DUPLEX;
-		else if (dev->data->dev_conf.link_duplex ==
-					ETH_LINK_FULL_DUPLEX)
-			hw->phy.autoneg_advertised = E1000_ALL_FULL_DUPLEX;
-		else
-			goto error_invalid_config;
-		break;
-	case ETH_SPEED_NUM_10M:
-		if (dev->data->dev_conf.link_duplex == ETH_LINK_AUTONEG_DUPLEX)
-			hw->phy.autoneg_advertised = E1000_ALL_10_SPEED;
-		else if (dev->data->dev_conf.link_duplex ==
-					ETH_LINK_HALF_DUPLEX)
-			hw->phy.autoneg_advertised = ADVERTISE_10_HALF;
-		else if (dev->data->dev_conf.link_duplex ==
-					ETH_LINK_FULL_DUPLEX)
-			hw->phy.autoneg_advertised = ADVERTISE_10_FULL;
-		else
-			goto error_invalid_config;
-		break;
-	case ETH_SPEED_NUM_100M:
-		if (dev->data->dev_conf.link_duplex == ETH_LINK_AUTONEG_DUPLEX)
-			hw->phy.autoneg_advertised = E1000_ALL_100_SPEED;
-		else if (dev->data->dev_conf.link_duplex ==
-					ETH_LINK_HALF_DUPLEX)
-			hw->phy.autoneg_advertised = ADVERTISE_100_HALF;
-		else if (dev->data->dev_conf.link_duplex ==
-					ETH_LINK_FULL_DUPLEX)
-			hw->phy.autoneg_advertised = ADVERTISE_100_FULL;
-		else
+	speeds = &dev->data->dev_conf.link_speeds;
+	if (*speeds == ETH_LINK_SPEED_AUTONEG) {
+		hw->phy.autoneg_advertised = E1000_ALL_SPEED_DUPLEX;
+	} else {
+		num_speeds = 0;
+		autoneg = (*speeds & ETH_LINK_SPEED_AUTONEG);
+
+		/* Reset */
+		hw->phy.autoneg_advertised = 0;
+
+		if (*speeds & ~(ETH_LINK_SPEED_10M_HD | ETH_LINK_SPEED_10M |
+				ETH_LINK_SPEED_100M_HD | ETH_LINK_SPEED_100M |
+				ETH_LINK_SPEED_1G)) {
+			num_speeds = -1;
 			goto error_invalid_config;
-		break;
-	case ETH_SPEED_NUM_1G:
-		if ((dev->data->dev_conf.link_duplex ==
-				ETH_LINK_AUTONEG_DUPLEX) ||
-			(dev->data->dev_conf.link_duplex ==
-					ETH_LINK_FULL_DUPLEX))
-			hw->phy.autoneg_advertised = ADVERTISE_1000_FULL;
-		else
+		}
+		if (*speeds & ETH_LINK_SPEED_10M_HD) {
+			hw->phy.autoneg_advertised |= ADVERTISE_10_HALF;
+			num_speeds++;
+		}
+		if (*speeds & ETH_LINK_SPEED_10M) {
+			hw->phy.autoneg_advertised |= ADVERTISE_10_FULL;
+			num_speeds++;
+		}
+		if (*speeds & ETH_LINK_SPEED_100M_HD) {
+			hw->phy.autoneg_advertised |= ADVERTISE_100_HALF;
+			num_speeds++;
+		}
+		if (*speeds & ETH_LINK_SPEED_100M) {
+			hw->phy.autoneg_advertised |= ADVERTISE_100_FULL;
+			num_speeds++;
+		}
+		if (*speeds & ETH_LINK_SPEED_1G) {
+			hw->phy.autoneg_advertised |= ADVERTISE_1000_FULL;
+			num_speeds++;
+		}
+		if (num_speeds == 0 || (!autoneg && (num_speeds > 2)))
 			goto error_invalid_config;
-		break;
-	case ETH_SPEED_NUM_10G:
-	default:
-		goto error_invalid_config;
 	}
+
 	e1000_setup_link(hw);
 
 	if (rte_intr_allow_others(intr_handle)) {
@@ -694,9 +687,8 @@ eth_em_start(struct rte_eth_dev *dev)
 	return 0;
 
 error_invalid_config:
-	PMD_INIT_LOG(ERR, "Invalid link_speed/link_duplex (%u/%u) for port %u",
-		     dev->data->dev_conf.link_speed,
-		     dev->data->dev_conf.link_duplex, dev->data->port_id);
+	PMD_INIT_LOG(ERR, "Invalid advertised speeds (%u) for port %u",
+		     dev->data->dev_conf.link_speeds, dev->data->port_id);
 	em_dev_clear_queues(dev);
 	return -EINVAL;
 }
@@ -1106,8 +1098,11 @@ eth_em_link_update(struct rte_eth_dev *dev, int wait_to_complete)
 
 	/* Now we check if a transition has happened */
 	if (link_check && (link.link_status == ETH_LINK_DOWN)) {
-		hw->mac.ops.get_link_up_info(hw, &link.link_speed,
-			&link.link_duplex);
+		uint16_t duplex, speed;
+		hw->mac.ops.get_link_up_info(hw, &speed, &duplex);
+		link.link_duplex = duplex ? ETH_LINK_FULL_DUPLEX :
+				ETH_LINK_HALF_DUPLEX;
+		link.link_speed = speed;
 		link.link_status = ETH_LINK_UP;
 	} else if (!link_check && (link.link_status == ETH_LINK_UP)) {
 		link.link_speed = 0;
diff --git a/drivers/net/e1000/igb_ethdev.c b/drivers/net/e1000/igb_ethdev.c
index 95d1711..ced864c 100644
--- a/drivers/net/e1000/igb_ethdev.c
+++ b/drivers/net/e1000/igb_ethdev.c
@@ -1133,6 +1133,9 @@ eth_igb_start(struct rte_eth_dev *dev)
 	int ret, mask;
 	uint32_t intr_vector = 0;
 	uint32_t ctrl_ext;
+	uint32_t *speeds;
+	int num_speeds;
+	bool autoneg;
 
 	PMD_INIT_FUNC_TRACE();
 
@@ -1233,48 +1236,46 @@ eth_igb_start(struct rte_eth_dev *dev)
 	}
 
 	/* Setup link speed and duplex */
-	switch (dev->data->dev_conf.link_speed) {
-	case ETH_LINK_SPEED_AUTONEG:
-		if (dev->data->dev_conf.link_duplex == ETH_LINK_AUTONEG_DUPLEX)
-			hw->phy.autoneg_advertised = E1000_ALL_SPEED_DUPLEX;
-		else if (dev->data->dev_conf.link_duplex == ETH_LINK_HALF_DUPLEX)
-			hw->phy.autoneg_advertised = E1000_ALL_HALF_DUPLEX;
-		else if (dev->data->dev_conf.link_duplex == ETH_LINK_FULL_DUPLEX)
-			hw->phy.autoneg_advertised = E1000_ALL_FULL_DUPLEX;
-		else
-			goto error_invalid_config;
-		break;
-	case ETH_SPEED_NUM_10M:
-		if (dev->data->dev_conf.link_duplex == ETH_LINK_AUTONEG_DUPLEX)
-			hw->phy.autoneg_advertised = E1000_ALL_10_SPEED;
-		else if (dev->data->dev_conf.link_duplex == ETH_LINK_HALF_DUPLEX)
-			hw->phy.autoneg_advertised = ADVERTISE_10_HALF;
-		else if (dev->data->dev_conf.link_duplex == ETH_LINK_FULL_DUPLEX)
-			hw->phy.autoneg_advertised = ADVERTISE_10_FULL;
-		else
-			goto error_invalid_config;
-		break;
-	case ETH_SPEED_NUM_100M:
-		if (dev->data->dev_conf.link_duplex == ETH_LINK_AUTONEG_DUPLEX)
-			hw->phy.autoneg_advertised = E1000_ALL_100_SPEED;
-		else if (dev->data->dev_conf.link_duplex == ETH_LINK_HALF_DUPLEX)
-			hw->phy.autoneg_advertised = ADVERTISE_100_HALF;
-		else if (dev->data->dev_conf.link_duplex == ETH_LINK_FULL_DUPLEX)
-			hw->phy.autoneg_advertised = ADVERTISE_100_FULL;
-		else
+	speeds = &dev->data->dev_conf.link_speeds;
+	if (*speeds == ETH_LINK_SPEED_AUTONEG) {
+		hw->phy.autoneg_advertised = E1000_ALL_SPEED_DUPLEX;
+	} else {
+		num_speeds = 0;
+		autoneg = (*speeds & ETH_LINK_SPEED_AUTONEG);
+
+		/* Reset */
+		hw->phy.autoneg_advertised = 0;
+
+		if (*speeds & ~(ETH_LINK_SPEED_10M_HD | ETH_LINK_SPEED_10M |
+				ETH_LINK_SPEED_100M_HD | ETH_LINK_SPEED_100M |
+				ETH_LINK_SPEED_1G)) {
+			num_speeds = -1;
 			goto error_invalid_config;
-		break;
-	case ETH_SPEED_NUM_1G:
-		if ((dev->data->dev_conf.link_duplex == ETH_LINK_AUTONEG_DUPLEX) ||
-				(dev->data->dev_conf.link_duplex == ETH_LINK_FULL_DUPLEX))
-			hw->phy.autoneg_advertised = ADVERTISE_1000_FULL;
-		else
+		}
+		if (*speeds & ETH_LINK_SPEED_10M_HD) {
+			hw->phy.autoneg_advertised |= ADVERTISE_10_HALF;
+			num_speeds++;
+		}
+		if (*speeds & ETH_LINK_SPEED_10M) {
+			hw->phy.autoneg_advertised |= ADVERTISE_10_FULL;
+			num_speeds++;
+		}
+		if (*speeds & ETH_LINK_SPEED_100M_HD) {
+			hw->phy.autoneg_advertised |= ADVERTISE_100_HALF;
+			num_speeds++;
+		}
+		if (*speeds & ETH_LINK_SPEED_100M) {
+			hw->phy.autoneg_advertised |= ADVERTISE_100_FULL;
+			num_speeds++;
+		}
+		if (*speeds & ETH_LINK_SPEED_1G) {
+			hw->phy.autoneg_advertised |= ADVERTISE_1000_FULL;
+			num_speeds++;
+		}
+		if (num_speeds == 0 || (!autoneg && (num_speeds > 2)))
 			goto error_invalid_config;
-		break;
-	case ETH_SPEED_NUM_10G:
-	default:
-		goto error_invalid_config;
 	}
+
 	e1000_setup_link(hw);
 
 	if (rte_intr_allow_others(intr_handle)) {
@@ -1306,9 +1307,8 @@ eth_igb_start(struct rte_eth_dev *dev)
 	return 0;
 
 error_invalid_config:
-	PMD_INIT_LOG(ERR, "Invalid link_speed/link_duplex (%u/%u) for port %u",
-		     dev->data->dev_conf.link_speed,
-		     dev->data->dev_conf.link_duplex, dev->data->port_id);
+	PMD_INIT_LOG(ERR, "Invalid advertised speeds (%u) for port %u",
+		     dev->data->dev_conf.link_speeds, dev->data->port_id);
 	igb_dev_clear_queues(dev);
 	return -EINVAL;
 }
@@ -2061,13 +2061,19 @@ eth_igb_link_update(struct rte_eth_dev *dev, int wait_to_complete)
 
 	/* Now we check if a transition has happened */
 	if (link_check) {
-		hw->mac.ops.get_link_up_info(hw, &link.link_speed,
-					  &link.link_duplex);
+		uint16_t duplex, speed;
+		hw->mac.ops.get_link_up_info(hw, &speed, &duplex);
+		link.link_duplex = duplex ? ETH_LINK_FULL_DUPLEX :
+				ETH_LINK_HALF_DUPLEX;
+		link.link_speed = speed;
 		link.link_status = ETH_LINK_UP;
+		link.link_autoneg = (dev->data->dev_conf.link_speeds &
+				ETH_LINK_SPEED_AUTONEG);
 	} else if (!link_check) {
 		link.link_speed = 0;
 		link.link_duplex = ETH_LINK_HALF_DUPLEX;
 		link.link_status = ETH_LINK_DOWN;
+		link.link_autoneg = ETH_LINK_SPEED_FIXED;
 	}
 	rte_igb_dev_atomic_write_link_status(dev, &link);
 
diff --git a/drivers/net/i40e/i40e_ethdev.c b/drivers/net/i40e/i40e_ethdev.c
index dce31db..87bc767 100644
--- a/drivers/net/i40e/i40e_ethdev.c
+++ b/drivers/net/i40e/i40e_ethdev.c
@@ -1381,27 +1381,20 @@ i40e_vsi_disable_queues_intr(struct i40e_vsi *vsi)
 }
 
 static inline uint8_t
-i40e_parse_link_speed(uint16_t eth_link_speed)
+i40e_parse_link_speeds(uint16_t link_speeds)
 {
 	uint8_t link_speed = I40E_LINK_SPEED_UNKNOWN;
 
-	switch (eth_link_speed) {
-	case ETH_SPEED_NUM_40G:
-		link_speed = I40E_LINK_SPEED_40GB;
-		break;
-	case ETH_SPEED_NUM_20G:
-		link_speed = I40E_LINK_SPEED_20GB;
-		break;
-	case ETH_SPEED_NUM_10G:
-		link_speed = I40E_LINK_SPEED_10GB;
-		break;
-	case ETH_SPEED_NUM_1G:
-		link_speed = I40E_LINK_SPEED_1GB;
-		break;
-	case ETH_SPEED_NUM_100M:
-		link_speed = I40E_LINK_SPEED_100MB;
-		break;
-	}
+	if (link_speeds & ETH_LINK_SPEED_40G)
+		link_speed |= I40E_LINK_SPEED_40GB;
+	if (link_speeds & ETH_LINK_SPEED_20G)
+		link_speed |= I40E_LINK_SPEED_20GB;
+	if (link_speeds & ETH_LINK_SPEED_10G)
+		link_speed |= I40E_LINK_SPEED_10GB;
+	if (link_speeds & ETH_LINK_SPEED_1G)
+		link_speed |= I40E_LINK_SPEED_1GB;
+	if (link_speeds & ETH_LINK_SPEED_100M)
+		link_speed |= I40E_LINK_SPEED_100MB;
 
 	return link_speed;
 }
@@ -1427,9 +1420,9 @@ i40e_apply_link_speed(struct rte_eth_dev *dev)
 	struct i40e_hw *hw = I40E_DEV_PRIVATE_TO_HW(dev->data->dev_private);
 	struct rte_eth_conf *conf = &dev->data->dev_conf;
 
-	speed = i40e_parse_link_speed(conf->link_speed);
+	speed = i40e_parse_link_speeds(conf->link_speeds);
 	abilities |= I40E_AQ_PHY_ENABLE_ATOMIC_LINK;
-	if (conf->link_speed == ETH_LINK_SPEED_AUTONEG)
+	if (conf->link_speeds & ETH_LINK_SPEED_AUTONEG)
 		abilities |= I40E_AQ_PHY_AN_ENABLED;
 	else
 		abilities |= I40E_AQ_PHY_LINK_ENABLED;
@@ -1449,10 +1442,8 @@ i40e_dev_start(struct rte_eth_dev *dev)
 
 	hw->adapter_stopped = 0;
 
-	if ((dev->data->dev_conf.link_duplex != ETH_LINK_AUTONEG_DUPLEX) &&
-		(dev->data->dev_conf.link_duplex != ETH_LINK_FULL_DUPLEX)) {
-		PMD_INIT_LOG(ERR, "Invalid link_duplex (%hu) for port %hhu",
-			     dev->data->dev_conf.link_duplex,
+	if (!(dev->data->dev_conf.link_speeds & ETH_LINK_SPEED_AUTONEG)) {
+		PMD_INIT_LOG(ERR, "Invalid link_speeds for port %hhu; autonegotiation disabled",
 			     dev->data->port_id);
 		return -EINVAL;
 	}
@@ -1525,6 +1516,12 @@ i40e_dev_start(struct rte_eth_dev *dev)
 	}
 
 	/* Apply link configure */
+	if (dev->data->dev_conf.link_speeds & ~(ETH_LINK_SPEED_100M |
+				ETH_LINK_SPEED_1G | ETH_LINK_SPEED_10G |
+				ETH_LINK_SPEED_20G | ETH_LINK_SPEED_40G)) {
+		PMD_DRV_LOG(ERR, "Invalid link setting");
+		goto err_up;
+	}
 	ret = i40e_apply_link_speed(dev);
 	if (I40E_SUCCESS != ret) {
 		PMD_DRV_LOG(ERR, "Fail to apply link setting");
@@ -1809,6 +1806,9 @@ i40e_dev_link_update(struct rte_eth_dev *dev,
 		break;
 	}
 
+	link.link_autoneg = (dev->data->dev_conf.link_speeds &
+			ETH_LINK_SPEED_AUTONEG);
+
 out:
 	rte_i40e_dev_atomic_write_link_status(dev, &link);
 	if (link.link_status == old.link_status)
diff --git a/drivers/net/i40e/i40e_ethdev_vf.c b/drivers/net/i40e/i40e_ethdev_vf.c
index 295dcd2..8cf22ee 100644
--- a/drivers/net/i40e/i40e_ethdev_vf.c
+++ b/drivers/net/i40e/i40e_ethdev_vf.c
@@ -2121,12 +2121,13 @@ i40evf_dev_link_update(struct rte_eth_dev *dev,
 	 * DPDK pf host provide interfacet to acquire link status
 	 * while Linux driver does not
 	 */
-	if (vf->version_major == I40E_DPDK_VERSION_MAJOR)
+	if (vf->version_major == I40E_DPDK_VERSION_MAJOR) {
 		i40evf_get_link_status(dev, &new_link);
-	else {
+	} else {
 		/* Always assume it's up, for Linux driver PF host */
-		new_link.link_duplex = ETH_LINK_AUTONEG_DUPLEX;
 		new_link.link_speed  = ETH_SPEED_NUM_10G;
+		new_link.link_duplex = ETH_LINK_FULL_DUPLEX;
+		new_link.link_autoneg = ETH_LINK_SPEED_AUTONEG;
 		new_link.link_status = ETH_LINK_UP;
 	}
 	i40evf_dev_atomic_write_link_status(dev, &new_link);
diff --git a/drivers/net/ixgbe/ixgbe_ethdev.c b/drivers/net/ixgbe/ixgbe_ethdev.c
index a98e8eb..ff23d7d 100644
--- a/drivers/net/ixgbe/ixgbe_ethdev.c
+++ b/drivers/net/ixgbe/ixgbe_ethdev.c
@@ -2094,14 +2094,13 @@ ixgbe_dev_start(struct rte_eth_dev *dev)
 	int mask = 0;
 	int status;
 	uint16_t vf, idx;
+	uint32_t *link_speeds;
 
 	PMD_INIT_FUNC_TRACE();
 
 	/* IXGBE devices don't support half duplex */
-	if ((dev->data->dev_conf.link_duplex != ETH_LINK_AUTONEG_DUPLEX) &&
-			(dev->data->dev_conf.link_duplex != ETH_LINK_FULL_DUPLEX)) {
-		PMD_INIT_LOG(ERR, "Invalid link_duplex (%hu) for port %hhu",
-			     dev->data->dev_conf.link_duplex,
+	if (!(dev->data->dev_conf.link_speeds & ETH_LINK_SPEED_AUTONEG)) {
+		PMD_INIT_LOG(ERR, "Invalid link_speeds for port %hhu; autonegotiation disabled",
 			     dev->data->port_id);
 		return -EINVAL;
 	}
@@ -2193,32 +2192,21 @@ ixgbe_dev_start(struct rte_eth_dev *dev)
 	if (err)
 		goto error;
 
-	switch(dev->data->dev_conf.link_speed) {
-	case ETH_LINK_SPEED_AUTONEG:
-		speed = (hw->mac.type != ixgbe_mac_82598EB) ?
-				IXGBE_LINK_SPEED_82599_AUTONEG :
-				IXGBE_LINK_SPEED_82598_AUTONEG;
-		break;
-	case ETH_SPEED_NUM_100M:
-		/*
-		 * Invalid for 82598 but error will be detected by
-		 * ixgbe_setup_link()
-		 */
-		speed = IXGBE_LINK_SPEED_100_FULL;
-		break;
-	case ETH_SPEED_NUM_1G:
-		speed = IXGBE_LINK_SPEED_1GB_FULL;
-		break;
-	case ETH_SPEED_NUM_10G:
-		speed = IXGBE_LINK_SPEED_10GB_FULL;
-		break;
-	default:
-		PMD_INIT_LOG(ERR, "Invalid link_speed (%hu) for port %hhu",
-			     dev->data->dev_conf.link_speed,
-			     dev->data->port_id);
+	link_speeds = &dev->data->dev_conf.link_speeds;
+	if (*link_speeds & ~(ETH_LINK_SPEED_100M | ETH_LINK_SPEED_1G |
+			ETH_LINK_SPEED_10G)) {
+		PMD_INIT_LOG(ERR, "Invalid link setting");
 		goto error;
 	}
 
+	speed = 0x0;
+	if (*link_speeds & ETH_LINK_SPEED_10G)
+		speed |= IXGBE_LINK_SPEED_10GB_FULL;
+	if (*link_speeds & ETH_LINK_SPEED_1G)
+		speed |= IXGBE_LINK_SPEED_1GB_FULL;
+	if (*link_speeds & ETH_LINK_SPEED_100M)
+		speed |= IXGBE_LINK_SPEED_100_FULL;
+
 	err = ixgbe_setup_link(hw, speed, link_up);
 	if (err)
 		goto error;
@@ -3083,7 +3071,7 @@ ixgbe_dev_link_update(struct rte_eth_dev *dev, int wait_to_complete)
 
 	if (diag != 0) {
 		link.link_speed = ETH_SPEED_NUM_100M;
-		link.link_duplex = ETH_LINK_HALF_DUPLEX;
+		link.link_duplex = ETH_LINK_FULL_DUPLEX;
 		rte_ixgbe_dev_atomic_write_link_status(dev, &link);
 		if (link.link_status == old.link_status)
 			return -1;
@@ -3102,7 +3090,7 @@ ixgbe_dev_link_update(struct rte_eth_dev *dev, int wait_to_complete)
 	switch (link_speed) {
 	default:
 	case IXGBE_LINK_SPEED_UNKNOWN:
-		link.link_duplex = ETH_LINK_HALF_DUPLEX;
+		link.link_duplex = ETH_LINK_FULL_DUPLEX;
 		link.link_speed = ETH_SPEED_NUM_100M;
 		break;
 
diff --git a/drivers/net/mlx4/mlx4.c b/drivers/net/mlx4/mlx4.c
index 59ac423..43ac763 100644
--- a/drivers/net/mlx4/mlx4.c
+++ b/drivers/net/mlx4/mlx4.c
@@ -4721,6 +4721,8 @@ mlx4_link_update_unlocked(struct rte_eth_dev *dev, int wait_to_complete)
 		dev_link.link_speed = link_speed;
 	dev_link.link_duplex = ((edata.duplex == DUPLEX_HALF) ?
 				ETH_LINK_HALF_DUPLEX : ETH_LINK_FULL_DUPLEX);
+	dev_link.link_autoneg = (dev->data->dev_conf.link_speeds &
+			ETH_LINK_SPEED_AUTONEG);
 	if (memcmp(&dev_link, &dev->data->dev_link, sizeof(dev_link))) {
 		/* Link status changed. */
 		dev->data->dev_link = dev_link;
diff --git a/drivers/net/mpipe/mpipe_tilegx.c b/drivers/net/mpipe/mpipe_tilegx.c
index 1a77c7a..adcbc19 100644
--- a/drivers/net/mpipe/mpipe_tilegx.c
+++ b/drivers/net/mpipe/mpipe_tilegx.c
@@ -394,6 +394,8 @@ mpipe_link_update(struct rte_eth_dev *dev, int wait_to_complete)
 
 		speed = state & GXIO_MPIPE_LINK_SPEED_MASK;
 
+		new.link_autoneg = (dev->data->dev_conf.link_speeds &
+				ETH_LINK_SPEED_AUTONEG);
 		if (speed == GXIO_MPIPE_LINK_1G) {
 			new.link_speed = ETH_SPEED_NUM_1G;
 			new.link_duplex = ETH_LINK_FULL_DUPLEX;
diff --git a/drivers/net/null/rte_eth_null.c b/drivers/net/null/rte_eth_null.c
index 5640585..5e8e203 100644
--- a/drivers/net/null/rte_eth_null.c
+++ b/drivers/net/null/rte_eth_null.c
@@ -92,6 +92,7 @@ static struct rte_eth_link pmd_link = {
 	.link_speed = ETH_SPEED_NUM_10G,
 	.link_duplex = ETH_LINK_FULL_DUPLEX,
 	.link_status = ETH_LINK_DOWN,
+	.link_autoneg = ETH_LINK_SPEED_AUTONEG,
 };
 
 static uint16_t
diff --git a/drivers/net/pcap/rte_eth_pcap.c b/drivers/net/pcap/rte_eth_pcap.c
index c657951..c98e234 100644
--- a/drivers/net/pcap/rte_eth_pcap.c
+++ b/drivers/net/pcap/rte_eth_pcap.c
@@ -126,6 +126,7 @@ static struct rte_eth_link pmd_link = {
 		.link_speed = ETH_SPEED_NUM_10G,
 		.link_duplex = ETH_LINK_FULL_DUPLEX,
 		.link_status = ETH_LINK_DOWN,
+		.link_autoneg = ETH_LINK_SPEED_FIXED,
 };
 
 static int
diff --git a/drivers/net/ring/rte_eth_ring.c b/drivers/net/ring/rte_eth_ring.c
index 58685e9..b1783c3 100644
--- a/drivers/net/ring/rte_eth_ring.c
+++ b/drivers/net/ring/rte_eth_ring.c
@@ -80,6 +80,7 @@ static struct rte_eth_link pmd_link = {
 		.link_speed = ETH_SPEED_NUM_10G,
 		.link_duplex = ETH_LINK_FULL_DUPLEX,
 		.link_status = ETH_LINK_DOWN,
+		.link_autoneg = ETH_LINK_SPEED_AUTONEG
 };
 
 static uint16_t
diff --git a/drivers/net/szedata2/rte_eth_szedata2.c b/drivers/net/szedata2/rte_eth_szedata2.c
index dd1ae9e..ee97a4e 100644
--- a/drivers/net/szedata2/rte_eth_szedata2.c
+++ b/drivers/net/szedata2/rte_eth_szedata2.c
@@ -1174,6 +1174,8 @@ eth_link_update(struct rte_eth_dev *dev,
 	link.link_status = (cgmii_ibuf_is_enabled(ibuf) &&
 			cgmii_ibuf_is_link_up(ibuf)) ? ETH_LINK_UP : ETH_LINK_DOWN;
 
+	link.link_autoneg = ETH_LINK_SPEED_FIXED;
+
 	rte_atomic64_cmpset((uint64_t *)dev_link, *(uint64_t *)dev_link,
 			*(uint64_t *)link_ptr);
 
diff --git a/drivers/net/vmxnet3/vmxnet3_ethdev.c b/drivers/net/vmxnet3/vmxnet3_ethdev.c
index 6afa14e..94d1b2c 100644
--- a/drivers/net/vmxnet3/vmxnet3_ethdev.c
+++ b/drivers/net/vmxnet3/vmxnet3_ethdev.c
@@ -780,6 +780,7 @@ vmxnet3_dev_link_update(struct rte_eth_dev *dev, __attribute__((unused)) int wai
 		link.link_status = ETH_LINK_UP;
 		link.link_duplex = ETH_LINK_FULL_DUPLEX;
 		link.link_speed = ETH_SPEED_NUM_10G;
+		link.link_autoneg = ETH_LINK_SPEED_FIXED;
 	}
 
 	vmxnet3_dev_atomic_write_link_status(dev, &link);
diff --git a/drivers/net/xenvirt/rte_eth_xenvirt.c b/drivers/net/xenvirt/rte_eth_xenvirt.c
index 77d3ba1..b9638d9 100644
--- a/drivers/net/xenvirt/rte_eth_xenvirt.c
+++ b/drivers/net/xenvirt/rte_eth_xenvirt.c
@@ -73,6 +73,7 @@ static struct rte_eth_link pmd_link = {
 		.link_speed = ETH_SPEED_NUM_10G,
 		.link_duplex = ETH_LINK_FULL_DUPLEX,
 		.link_status = ETH_LINK_DOWN,
+		.link_autoneg = ETH_LINK_SPEED_FIXED
 };
 
 static void
diff --git a/examples/ip_pipeline/config_parse.c b/examples/ip_pipeline/config_parse.c
index 152889d..2cd5707 100644
--- a/examples/ip_pipeline/config_parse.c
+++ b/examples/ip_pipeline/config_parse.c
@@ -87,8 +87,7 @@ static const struct app_link_params link_params_default = {
 	.pci_bdf = {0},
 
 	.conf = {
-		.link_speed = 0,
-		.link_duplex = 0,
+		.link_speeds = 0,
 		.rxmode = {
 			.mq_mode = ETH_MQ_RX_NONE,
 
diff --git a/lib/librte_ether/rte_ethdev.h b/lib/librte_ether/rte_ethdev.h
index 49fdcb7..03d3278 100644
--- a/lib/librte_ether/rte_ethdev.h
+++ b/lib/librte_ether/rte_ethdev.h
@@ -244,6 +244,8 @@ struct rte_eth_stats {
 /**
  * Device supported speeds bitmap flags
  */
+#define ETH_LINK_SPEED_FIXED    (0 <<  0)  /**< Disable autoneg (fixed speed) */
+#define ETH_LINK_SPEED_AUTONEG  (1 <<  0)  /**< Autonegotiate (all speeds) */
 #define ETH_LINK_SPEED_10M_HD   (1 <<  1)  /**<  10 Mbps half-duplex */
 #define ETH_LINK_SPEED_10M      (1 <<  2)  /**<  10 Mbps full-duplex */
 #define ETH_LINK_SPEED_100M_HD  (1 <<  3)  /**< 100 Mbps half-duplex */
@@ -261,7 +263,7 @@ struct rte_eth_stats {
 /**
  * Ethernet numeric link speeds in Mbps
  */
-#define ETH_LINK_SPEED_AUTONEG     0 /**< Auto-negotiate link speed. */
+#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 */
@@ -278,15 +280,15 @@ struct rte_eth_stats {
  * A structure used to retrieve link-level information of an Ethernet port.
  */
 struct rte_eth_link {
-	uint16_t link_speed;      /**< ETH_SPEED_NUM_ */
-	uint16_t link_duplex;     /**< ETH_LINK_[HALF/FULL]_DUPLEX */
-	uint8_t  link_status : 1; /**< ETH_LINK_[DOWN/UP] */
-}__attribute__((aligned(8)));     /**< aligned for atomic64 read/write */
+	uint16_t link_speed;        /**< ETH_SPEED_NUM_ */
+	uint16_t link_duplex  : 1;  /**< ETH_LINK_[HALF/FULL]_DUPLEX */
+	uint16_t link_autoneg : 1;  /**< ETH_LINK_SPEED_[AUTONEG/FIXED] */
+	uint16_t link_status  : 1;  /**< ETH_LINK_[DOWN/UP] */
+} __attribute__((aligned(8)));      /**< aligned for atomic64 read/write */
 
 /* Utility constants */
-#define ETH_LINK_AUTONEG_DUPLEX 0       /**< Auto-negotiate duplex. */
-#define ETH_LINK_HALF_DUPLEX    1       /**< Half-duplex connection. */
-#define ETH_LINK_FULL_DUPLEX    2       /**< Full-duplex connection. */
+#define ETH_LINK_HALF_DUPLEX    0 /**< Half-duplex connection. */
+#define ETH_LINK_FULL_DUPLEX    1 /**< Full-duplex connection. */
 #define ETH_LINK_DOWN           0 /**< Link is down. */
 #define ETH_LINK_UP             1 /**< Link is up. */
 
@@ -802,10 +804,13 @@ struct rte_intr_conf {
  * configuration settings may be needed.
  */
 struct rte_eth_conf {
-	uint16_t link_speed;
-	/**< ETH_SPEED_NUM_ or 0 for autonegotiation */
-	uint16_t link_duplex;
-	/**< ETH_LINK_[HALF_DUPLEX|FULL_DUPLEX], or 0 for autonegotation */
+	uint32_t link_speeds; /**< bitmap of ETH_LINK_SPEED_XXX of speeds to be
+				used. ETH_LINK_SPEED_FIXED disables link
+				autonegotiation, and a unique speed shall be
+				set. Otherwise, the bitmap defines the set of
+				speeds to be advertised. If the special value
+				ETH_LINK_SPEED_AUTONEG (0) is used, all speeds
+				supported are advertised. */
 	struct rte_eth_rxmode rxmode; /**< Port RX configuration. */
 	struct rte_eth_txmode txmode; /**< Port TX configuration. */
 	uint32_t lpbk_mode; /**< Loopback operation mode. By default the value
-- 
2.7.0

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

* [PATCH v12 7/8] ethdev: convert speed number to bitmap flag
  2016-03-25 19:42             ` [PATCH v12 " Thomas Monjalon
                                 ` (5 preceding siblings ...)
  2016-03-25 19:42               ` [PATCH v12 6/8] ethdev: redesign link speed config Thomas Monjalon
@ 2016-03-25 19:42               ` Thomas Monjalon
  2016-03-25 19:42               ` [PATCH v12 8/8] ethdev: add 100G link speed Thomas Monjalon
  2016-03-26  1:27               ` [PATCH v13 0/8] ethdev: 100G and link speed API refactoring Marc Sune
  8 siblings, 0 replies; 167+ messages in thread
From: Thomas Monjalon @ 2016-03-25 19:42 UTC (permalink / raw)
  To: marcdevel, bruce.richardson, declan.doherty, konstantin.ananyev,
	wenzhuo.lu, helin.zhang, jing.d.chen, harish.patil,
	rahul.lakkireddy, johndale, vido, adrien.mazarguil,
	alejandro.lucero
  Cc: dev

From: Marc Sune <marcdevel@gmail.com>

It is a helper for the bitmap configuration.

Signed-off-by: Marc Sune <marcdevel@gmail.com>
Signed-off-by: Thomas Monjalon <thomas.monjalon@6wind.com>
---
 lib/librte_ether/rte_ethdev.c          | 31 +++++++++++++++++++++++++++++++
 lib/librte_ether/rte_ethdev.h          | 13 +++++++++++++
 lib/librte_ether/rte_ether_version.map |  1 +
 3 files changed, 45 insertions(+)

diff --git a/lib/librte_ether/rte_ethdev.c b/lib/librte_ether/rte_ethdev.c
index 76a30fd..695b475 100644
--- a/lib/librte_ether/rte_ethdev.c
+++ b/lib/librte_ether/rte_ethdev.c
@@ -866,6 +866,37 @@ rte_eth_dev_tx_queue_config(struct rte_eth_dev *dev, uint16_t nb_queues)
 	return 0;
 }
 
+uint32_t
+rte_eth_speed_bitflag(uint32_t speed, int duplex)
+{
+	switch (speed) {
+	case ETH_SPEED_NUM_10M:
+		return duplex ? ETH_LINK_SPEED_10M : ETH_LINK_SPEED_10M_HD;
+	case ETH_SPEED_NUM_100M:
+		return duplex ? ETH_LINK_SPEED_100M : ETH_LINK_SPEED_100M_HD;
+	case ETH_SPEED_NUM_1G:
+		return ETH_LINK_SPEED_1G;
+	case ETH_SPEED_NUM_2_5G:
+		return ETH_LINK_SPEED_2_5G;
+	case ETH_SPEED_NUM_5G:
+		return ETH_LINK_SPEED_5G;
+	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;
+	default:
+		return 0;
+	}
+}
+
 int
 rte_eth_dev_configure(uint8_t port_id, uint16_t nb_rx_q, uint16_t nb_tx_q,
 		      const struct rte_eth_conf *dev_conf)
diff --git a/lib/librte_ether/rte_ethdev.h b/lib/librte_ether/rte_ethdev.h
index 03d3278..bb08ead 100644
--- a/lib/librte_ether/rte_ethdev.h
+++ b/lib/librte_ether/rte_ethdev.h
@@ -1876,6 +1876,19 @@ struct eth_driver {
 void rte_eth_driver_register(struct eth_driver *eth_drv);
 
 /**
+ * Convert a numerical speed in Mbps to a bitmap flag that can be used in
+ * the bitmap link_speeds of the struct rte_eth_conf
+ *
+ * @param speed
+ *   Numerical speed value in Mbps
+ * @param duplex
+ *   ETH_LINK_[HALF/FULL]_DUPLEX (only for 10/100M speeds)
+ * @return
+ *   0 if the speed cannot be mapped
+ */
+uint32_t rte_eth_speed_bitflag(uint32_t speed, int duplex);
+
+/**
  * Configure an Ethernet device.
  * This function must be invoked first before any other function in the
  * Ethernet API. This function can also be re-invoked when a device is in the
diff --git a/lib/librte_ether/rte_ether_version.map b/lib/librte_ether/rte_ether_version.map
index b1f4475..214ecc7 100644
--- a/lib/librte_ether/rte_ether_version.map
+++ b/lib/librte_ether/rte_ether_version.map
@@ -125,6 +125,7 @@ DPDK_16.04 {
 	rte_eth_dev_set_vlan_ether_type;
 	rte_eth_dev_udp_tunnel_port_add;
 	rte_eth_dev_udp_tunnel_port_delete;
+	rte_eth_speed_bitflag;
 	rte_eth_tx_buffer_count_callback;
 	rte_eth_tx_buffer_drop_callback;
 	rte_eth_tx_buffer_init;
-- 
2.7.0

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

* [PATCH v12 8/8] ethdev: add 100G link speed
  2016-03-25 19:42             ` [PATCH v12 " Thomas Monjalon
                                 ` (6 preceding siblings ...)
  2016-03-25 19:42               ` [PATCH v12 7/8] ethdev: convert speed number to bitmap flag Thomas Monjalon
@ 2016-03-25 19:42               ` Thomas Monjalon
  2016-03-26  1:27               ` [PATCH v13 0/8] ethdev: 100G and link speed API refactoring Marc Sune
  8 siblings, 0 replies; 167+ messages in thread
From: Thomas Monjalon @ 2016-03-25 19:42 UTC (permalink / raw)
  To: marcdevel, bruce.richardson, declan.doherty, konstantin.ananyev,
	wenzhuo.lu, helin.zhang, jing.d.chen, harish.patil,
	rahul.lakkireddy, johndale, vido, adrien.mazarguil,
	alejandro.lucero
  Cc: dev

The link speed configuration is now done with bitmaps so 100G speed
requires only a new bit flag.
The actual link speed is a number so its size must be increased from
16-bit to 32-bit.

Signed-off-by: Marc Sune <marcdevel@gmail.com>
Signed-off-by: Thomas Monjalon <thomas.monjalon@6wind.com>
Tested-by: Nelio Laranjeiro <nelio.laranjeiro@6wind.com>
Tested-by: Matej Vido <vido@cesnet.cz>
---
 app/test-pmd/cmdline.c                      | 12 +++++++-----
 doc/guides/nics/szedata2.rst                |  6 ------
 doc/guides/rel_notes/release_16_04.rst      |  5 +++++
 doc/guides/testpmd_app_ug/testpmd_funcs.rst |  2 +-
 drivers/net/ena/ena_ethdev.c                |  3 ++-
 drivers/net/fm10k/fm10k_ethdev.c            |  2 +-
 drivers/net/mlx5/mlx5_ethdev.c              |  3 ++-
 drivers/net/nfp/nfp_net.c                   |  2 +-
 drivers/net/szedata2/rte_eth_szedata2.c     |  9 ++-------
 lib/librte_ether/rte_ethdev.c               |  2 ++
 lib/librte_ether/rte_ethdev.h               |  4 +++-
 11 files changed, 26 insertions(+), 24 deletions(-)

diff --git a/app/test-pmd/cmdline.c b/app/test-pmd/cmdline.c
index 741cac3..c5b9479 100644
--- a/app/test-pmd/cmdline.c
+++ b/app/test-pmd/cmdline.c
@@ -549,7 +549,7 @@ static void cmd_help_long_parsed(void *parsed_result,
 			"    Detach physical or virtual dev by port_id\n\n"
 
 			"port config (port_id|all)"
-			" speed (10|100|1000|10000|40000|auto)"
+			" speed (10|100|1000|10000|40000|100000|auto)"
 			" duplex (half|full|auto)\n"
 			"    Set speed and duplex for all ports or port_id\n\n"
 
@@ -1022,6 +1022,8 @@ parse_and_check_speed_duplex(char *speedstr, char *duplexstr, uint32_t *speed)
 			*speed = ETH_LINK_SPEED_10G;
 		} else if (!strcmp(speedstr, "40000")) {
 			*speed = ETH_LINK_SPEED_40G;
+		} else if (!strcmp(speedstr, "100000")) {
+			*speed = ETH_LINK_SPEED_100G;
 		} else if (!strcmp(speedstr, "auto")) {
 			*speed = ETH_LINK_SPEED_AUTONEG;
 		} else {
@@ -1069,7 +1071,7 @@ cmdline_parse_token_string_t cmd_config_speed_all_item1 =
 	TOKEN_STRING_INITIALIZER(struct cmd_config_speed_all, item1, "speed");
 cmdline_parse_token_string_t cmd_config_speed_all_value1 =
 	TOKEN_STRING_INITIALIZER(struct cmd_config_speed_all, value1,
-						"10#100#1000#10000#40000#auto");
+						"10#100#1000#10000#40000#100000#auto");
 cmdline_parse_token_string_t cmd_config_speed_all_item2 =
 	TOKEN_STRING_INITIALIZER(struct cmd_config_speed_all, item2, "duplex");
 cmdline_parse_token_string_t cmd_config_speed_all_value2 =
@@ -1079,7 +1081,7 @@ cmdline_parse_token_string_t cmd_config_speed_all_value2 =
 cmdline_parse_inst_t cmd_config_speed_all = {
 	.f = cmd_config_speed_all_parsed,
 	.data = NULL,
-	.help_str = "port config all speed 10|100|1000|10000|40000|auto duplex "
+	.help_str = "port config all speed 10|100|1000|10000|40000|100000|auto duplex "
 							"half|full|auto",
 	.tokens = {
 		(void *)&cmd_config_speed_all_port,
@@ -1143,7 +1145,7 @@ cmdline_parse_token_string_t cmd_config_speed_specific_item1 =
 								"speed");
 cmdline_parse_token_string_t cmd_config_speed_specific_value1 =
 	TOKEN_STRING_INITIALIZER(struct cmd_config_speed_specific, value1,
-						"10#100#1000#10000#40000#auto");
+						"10#100#1000#10000#40000#100000#auto");
 cmdline_parse_token_string_t cmd_config_speed_specific_item2 =
 	TOKEN_STRING_INITIALIZER(struct cmd_config_speed_specific, item2,
 								"duplex");
@@ -1154,7 +1156,7 @@ cmdline_parse_token_string_t cmd_config_speed_specific_value2 =
 cmdline_parse_inst_t cmd_config_speed_specific = {
 	.f = cmd_config_speed_specific_parsed,
 	.data = NULL,
-	.help_str = "port config X speed 10|100|1000|10000|40000|auto duplex "
+	.help_str = "port config X speed 10|100|1000|10000|40000|100000|auto duplex "
 							"half|full|auto",
 	.tokens = {
 		(void *)&cmd_config_speed_specific_port,
diff --git a/doc/guides/nics/szedata2.rst b/doc/guides/nics/szedata2.rst
index 77c15b3..741b400 100644
--- a/doc/guides/nics/szedata2.rst
+++ b/doc/guides/nics/szedata2.rst
@@ -148,9 +148,3 @@ Example output:
      TX threshold registers: pthresh=0 hthresh=0 wthresh=0
      TX RS bit threshold=0 - TXQ flags=0x0
    testpmd>
-
-.. note::
-
-   Link speed API currently supports speeds up to 40 Gbps.
-   Therefore there is used 10G constant for 100 Gbps cards until the link speed
-   API is not changed.
diff --git a/doc/guides/rel_notes/release_16_04.rst b/doc/guides/rel_notes/release_16_04.rst
index c891a55..a0fc02d 100644
--- a/doc/guides/rel_notes/release_16_04.rst
+++ b/doc/guides/rel_notes/release_16_04.rst
@@ -320,6 +320,11 @@ EAL
 Drivers
 ~~~~~~~
 
+* **ethdev: Fixed overflow for 100Gbps.**
+
+  100Gbps in Mbps (100000) was exceeding 16-bit max value of ``link_speed``
+  in ``rte_eth_link``.
+
 * **ethdev: Fixed byte order consistency between fdir flow and mask.**
 
   Fixed issue in ethdev library that the structure for setting
diff --git a/doc/guides/testpmd_app_ug/testpmd_funcs.rst b/doc/guides/testpmd_app_ug/testpmd_funcs.rst
index 94fba6a..aed5e47 100644
--- a/doc/guides/testpmd_app_ug/testpmd_funcs.rst
+++ b/doc/guides/testpmd_app_ug/testpmd_funcs.rst
@@ -1155,7 +1155,7 @@ port config - speed
 
 Set the speed and duplex mode for all ports or a specific port::
 
-   testpmd> port config (port_id|all) speed (10|100|1000|10000|auto) \
+   testpmd> port config (port_id|all) speed (10|100|1000|10000|40000|100000|auto) \
             duplex (half|full|auto)
 
 port config - queues/descriptors
diff --git a/drivers/net/ena/ena_ethdev.c b/drivers/net/ena/ena_ethdev.c
index 4e403af..02af67a 100644
--- a/drivers/net/ena/ena_ethdev.c
+++ b/drivers/net/ena/ena_ethdev.c
@@ -1177,7 +1177,8 @@ static void ena_infos_get(struct rte_eth_dev *dev,
 			ETH_LINK_SPEED_10G  |
 			ETH_LINK_SPEED_25G  |
 			ETH_LINK_SPEED_40G  |
-			ETH_LINK_SPEED_50G;
+			ETH_LINK_SPEED_50G  |
+			ETH_LINK_SPEED_100G;
 
 	/* Get supported features from HW */
 	rc = ena_com_get_dev_attr_feat(ena_dev, &feat);
diff --git a/drivers/net/fm10k/fm10k_ethdev.c b/drivers/net/fm10k/fm10k_ethdev.c
index 85ad0df..953d9c1 100644
--- a/drivers/net/fm10k/fm10k_ethdev.c
+++ b/drivers/net/fm10k/fm10k_ethdev.c
@@ -1413,7 +1413,7 @@ fm10k_dev_infos_get(struct rte_eth_dev *dev,
 
 	dev_info->speed_capa = ETH_LINK_SPEED_1G | ETH_LINK_SPEED_2_5G |
 			ETH_LINK_SPEED_10G | ETH_LINK_SPEED_25G |
-			ETH_LINK_SPEED_40G;
+			ETH_LINK_SPEED_40G | ETH_LINK_SPEED_100G;
 }
 
 #ifdef RTE_LIBRTE_FM10K_RX_OLFLAGS_ENABLE
diff --git a/drivers/net/mlx5/mlx5_ethdev.c b/drivers/net/mlx5/mlx5_ethdev.c
index d7a0eea..477939f 100644
--- a/drivers/net/mlx5/mlx5_ethdev.c
+++ b/drivers/net/mlx5/mlx5_ethdev.c
@@ -566,7 +566,8 @@ mlx5_dev_infos_get(struct rte_eth_dev *dev, struct rte_eth_dev_info *info)
 			ETH_LINK_SPEED_25G |
 			ETH_LINK_SPEED_40G |
 			ETH_LINK_SPEED_50G |
-			ETH_LINK_SPEED_56G;
+			ETH_LINK_SPEED_56G |
+			ETH_LINK_SPEED_100G;
 	priv_unlock(priv);
 }
 
diff --git a/drivers/net/nfp/nfp_net.c b/drivers/net/nfp/nfp_net.c
index bdeb21f..4e909e0 100644
--- a/drivers/net/nfp/nfp_net.c
+++ b/drivers/net/nfp/nfp_net.c
@@ -1062,7 +1062,7 @@ nfp_net_infos_get(struct rte_eth_dev *dev, struct rte_eth_dev_info *dev_info)
 	dev_info->reta_size = NFP_NET_CFG_RSS_ITBL_SZ;
 	dev_info->hash_key_size = NFP_NET_CFG_RSS_KEY_SZ;
 
-	dev_info->speed_capa = ETH_LINK_SPEED_50G;
+	dev_info->speed_capa = ETH_LINK_SPEED_50G | ETH_LINK_SPEED_100G;
 }
 
 static const uint32_t *
diff --git a/drivers/net/szedata2/rte_eth_szedata2.c b/drivers/net/szedata2/rte_eth_szedata2.c
index ee97a4e..78c43b0 100644
--- a/drivers/net/szedata2/rte_eth_szedata2.c
+++ b/drivers/net/szedata2/rte_eth_szedata2.c
@@ -1036,6 +1036,7 @@ eth_dev_info(struct rte_eth_dev *dev,
 	dev_info->max_rx_queues = internals->max_rx_queues;
 	dev_info->max_tx_queues = internals->max_tx_queues;
 	dev_info->min_rx_bufsize = 0;
+	dev_info->speed_capa = ETH_LINK_SPEED_100G;
 }
 
 static void
@@ -1155,13 +1156,7 @@ eth_link_update(struct rte_eth_dev *dev,
 		link.link_speed = ETH_SPEED_NUM_40G;
 		break;
 	case SZEDATA2_LINK_SPEED_100G:
-		/*
-		 * TODO
-		 * If link_speed value from rte_eth_link structure
-		 * will be changed to support 100Gbps speed change
-		 * this value to 100G.
-		 */
-		link.link_speed = ETH_SPEED_NUM_10G;
+		link.link_speed = ETH_SPEED_NUM_100G;
 		break;
 	default:
 		link.link_speed = ETH_SPEED_NUM_10G;
diff --git a/lib/librte_ether/rte_ethdev.c b/lib/librte_ether/rte_ethdev.c
index 695b475..fd49b26 100644
--- a/lib/librte_ether/rte_ethdev.c
+++ b/lib/librte_ether/rte_ethdev.c
@@ -892,6 +892,8 @@ rte_eth_speed_bitflag(uint32_t speed, int duplex)
 		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;
 	}
diff --git a/lib/librte_ether/rte_ethdev.h b/lib/librte_ether/rte_ethdev.h
index bb08ead..ef2502a 100644
--- a/lib/librte_ether/rte_ethdev.h
+++ b/lib/librte_ether/rte_ethdev.h
@@ -259,6 +259,7 @@ struct rte_eth_stats {
 #define ETH_LINK_SPEED_40G      (1 << 11)  /**<  40 Gbps */
 #define ETH_LINK_SPEED_50G      (1 << 12)  /**<  50 Gbps */
 #define ETH_LINK_SPEED_56G      (1 << 13)  /**<  56 Gbps */
+#define ETH_LINK_SPEED_100G     (1 << 14)  /**< 100 Gbps */
 
 /**
  * Ethernet numeric link speeds in Mbps
@@ -275,12 +276,13 @@ struct rte_eth_stats {
 #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 */
 
 /**
  * A structure used to retrieve link-level information of an Ethernet port.
  */
 struct rte_eth_link {
-	uint16_t link_speed;        /**< ETH_SPEED_NUM_ */
+	uint32_t link_speed;        /**< ETH_SPEED_NUM_ */
 	uint16_t link_duplex  : 1;  /**< ETH_LINK_[HALF/FULL]_DUPLEX */
 	uint16_t link_autoneg : 1;  /**< ETH_LINK_SPEED_[AUTONEG/FIXED] */
 	uint16_t link_status  : 1;  /**< ETH_LINK_[DOWN/UP] */
-- 
2.7.0

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

* Re: [PATCH v11 0/8] ethdev: 100G and link speed API refactoring
  2016-03-25 15:07                           ` Zhang, Helin
  2016-03-25 15:32                             ` Thomas Monjalon
@ 2016-03-25 20:41                             ` Marc
  2016-03-25 21:30                               ` Marc
  1 sibling, 1 reply; 167+ messages in thread
From: Marc @ 2016-03-25 20:41 UTC (permalink / raw)
  To: Zhang, Helin
  Cc: Thomas Monjalon, Xu, Qian Q, Xing, Beilei, dev, Ananyev,
	Konstantin, Lu, Wenzhuo, Richardson, Bruce, Glynn, Michael J

On 25 March 2016 at 16:07, Zhang, Helin <helin.zhang@intel.com> wrote:

> Hi Thomas
>
> Beilei is investigating that, she will give her findings soon later, and
> possibly a fix after validating that.
> Thanks!
>
>
I will try to reproduce this on my side too with the latest v12. I could
not try latest patchsets, but i40 (XL710) and igb (82540EM) were working on
my side for previous versions. Which exact NICs were used to test the
patchset for igb?

Marc


> Regards,
> Helin
>
> > -----Original Message-----
> > From: Thomas Monjalon [mailto:thomas.monjalon@6wind.com]
> > Sent: Friday, March 25, 2016 5:36 PM
> > To: Xu, Qian Q <qian.q.xu@intel.com>
> > Cc: dev@dpdk.org; Marc <marcdevel@gmail.com>; Ananyev, Konstantin
> > <konstantin.ananyev@intel.com>; Lu, Wenzhuo <wenzhuo.lu@intel.com>;
> > Zhang, Helin <helin.zhang@intel.com>; Richardson, Bruce
> > <bruce.richardson@intel.com>; Glynn, Michael J <
> michael.j.glynn@intel.com>
> > Subject: Re: [dpdk-dev] [PATCH v11 0/8] ethdev: 100G and link speed API
> > refactoring
> >
> > Is there someone investigating the issue?
> > I think it should be simple to fix for someone mastering these Intel
> drivers.
> >
> > 2016-03-25 01:02, Xu, Qian Q:
> > > Marc
> > > #Test1 is just a simple test. Just launch testpmd with these nic port.
> > > ./testpmd –c 0x3 –n 4 -- -i
> > >
> > > Thanks
> > > Qian
> > >
> > > From: marc.sune@gmail.com [mailto:marc.sune@gmail.com] On Behalf Of
> > > Marc
> > > Sent: Thursday, March 24, 2016 3:48 PM
> > > To: Xu, Qian Q
> > > Cc: Thomas Monjalon; Ananyev, Konstantin; Lu, Wenzhuo; Zhang, Helin;
> > > Richardson, Bruce; dev@dpdk.org
> > > Subject: Re: [dpdk-dev] [PATCH v11 0/8] ethdev: 100G and link speed
> > > API refactoring
> > >
> > >
> > >
> > > On 24 March 2016 at 07:21, Xu, Qian Q
> > <qian.q.xu@intel.com<mailto:qian.q.xu@intel.com>> wrote:
> > > Marc
> > > I didn’t quite get your points, I observed that after applying this
> patchset, all
> > intel nic can’t be started, maybe something wrong happened when you check
> > the duplex/autoneg value for different NICs. If we want to merge the
> patchset in
> > RC2, we need fix them. Maybe not an easy job in several days.
> > >
> > > Is this test#1 one of the tests contained in the DPDK repository or is
> it an
> > internal test?
> > >
> > > Marc
> > >
> > >
> > >
> > > Thanks
> > > Qian
> > >
> > > From: marc.sune@gmail.com<mailto:marc.sune@gmail.com>
> > > [mailto:marc.sune@gmail.com<mailto:marc.sune@gmail.com>] On Behalf Of
> > > Marc
> > > Sent: Thursday, March 24, 2016 4:54 AM
> > > To: Xu, Qian Q
> > > Cc: Thomas Monjalon; Ananyev, Konstantin; Lu, Wenzhuo; Zhang, Helin;
> > > Richardson, Bruce; dev@dpdk.org<mailto:dev@dpdk.org>
> > >
> > > Subject: Re: [dpdk-dev] [PATCH v11 0/8] ethdev: 100G and link speed
> > > API refactoring
> > >
> > > Qian,
> > >
> > > On 23 March 2016 at 02:18, Xu, Qian Q
> > <qian.q.xu@intel.com<mailto:qian.q.xu@intel.com>> wrote:
> > > We have tested with intel nic and found port can't be started for all
> > nics:ixgbe/i40e/igb/bonding, see attached mail for more details. Please
> check
> > and fix it.
> > >
> > >
> > > Thanks
> > > Qian
> > >
> > > -----Original Message-----
> > > From: dev [mailto:dev-bounces@dpdk.org<mailto:dev-bounces@dpdk.org>]
> > > On Behalf Of Thomas Monjalon
> > > Sent: Wednesday, March 23, 2016 3:59 AM
> > > To: Ananyev, Konstantin; Lu, Wenzhuo; Zhang, Helin
> > > Cc: marcdevel@gmail.com<mailto:marcdevel@gmail.com>; Richardson,
> > > Bruce; dev@dpdk.org<mailto:dev@dpdk.org>
> > > Subject: Re: [dpdk-dev] [PATCH v11 0/8] ethdev: 100G and link speed
> > > API refactoring
> > >
> > > 2016-03-17 19:08, Thomas Monjalon:
> > > > There are still too few tests and reviews, especially for
> > > > autonegotiation with Intel devices (patch #6).
> > > > I would not be surprised to see some bugs in this rework.
> > >
> > > Any feedback about autoneg in e1000/ixgbe/i40e?
> > > Has it been tested before its integration in RC2?
> > >
> > > > The capabilities must be adapted per device. It can be improved in a
> > > > separate patch.
> > > >
> > > > It will be integrated in 16.04-rc2.
> > > > Please test and review shortly, thanks!
> > >
> > >
> > > ---------- Forwarded message ----------
> > > From: "Xu, Qian Q" <qian.q.xu@intel.com<mailto:qian.q.xu@intel.com>>
> > > To: "Cao, Waterman"
> > > <waterman.cao@intel.com<mailto:waterman.cao@intel.com>>, "Glynn,
> > > Michael J"
> > > <michael.j.glynn@intel.com<mailto:michael.j.glynn@intel.com>>
> > > Cc: "Richardson, Bruce"
> > > <bruce.richardson@intel.com<mailto:bruce.richardson@intel.com>>, "Zhu,
> > > Heqing" <heqing.zhu@intel.com<mailto:heqing.zhu@intel.com>>,
> > > "O'Driscoll, Tim"
> > > <tim.odriscoll@intel.com<mailto:tim.odriscoll@intel.com>>, "Mcnamara,
> > > John" <john.mcnamara@intel.com<mailto:john.mcnamara@intel.com>>, "Xu,
> > > HuilongX" <huilongx.xu@intel.com<mailto:huilongx.xu@intel.com>>, "Fu,
> > > JingguoX" <jingguox.fu@intel.com<mailto:jingguox.fu@intel.com>>, "Xu,
> > > Qian Q" <qian.q.xu@intel.com<mailto:qian.q.xu@intel.com>>, "Zhang,
> > > Helin" <helin.zhang@intel.com<mailto:helin.zhang@intel.com>>
> > > Date: Tue, 22 Mar 2016 06:41:37 +0000
> > > Subject: RE: DPDK link speed with Intel devices Hi, all We have worked
> > > out the basic test cases for the patchset.
> > > 1. Test the link speed on major Intel NICs to see if the speed is
> right.
> > > 2. Test the auto-negoation on major Intel NICs to ensure it's working.
> > > Nic covered: ixgbe, igb, i40e, fm10k, bonding(SW), virtio(SW)
> > >
> > > When we run the Test#1 for all major NICs. We found that all these NIC
> port(igb,
> > ixgbe, i40e, fm10k) can't be started. Pls check, if the patch is
> applied, all INTEL
> > port can't be start, terrible things!
> > >
> > > Interactive-mode selected
> > > Configuring Port 0 (socket 0)
> > > PMD: ixgbe_dev_tx_queue_setup(): sw_ring=0x7f13e99e3440
> > > hw_ring=0x7f13e99e5480 dma_addr=0x8299e5480
> > > PMD: ixgbe_set_tx_function(): Using simple tx code path
> > > PMD: ixgbe_set_tx_function(): Vector tx enabled.
> > > PMD: ixgbe_dev_rx_queue_setup(): sw_ring=0x7f13ffcb8080
> > > sw_sc_ring=0x7f13ffcbaac0 hw_ring=0x7f13e99d3380 dma_addr=0x8299d3380
> > > PMD: ixgbe_dev_start(): Invalid link_speeds for port 0;
> > > autonegotiation disabled Fail to start port 0 Configuring Port 1
> > > (socket 0)
> > > PMD: i40e_set_tx_function_flag(): Vector tx can be enabled on this txq.
> > > PMD: i40e_dev_rx_queue_setup(): Rx Burst Bulk Alloc Preconditions are
> > satisfied. Rx Burst Bulk Alloc function will be used on port=1, queue=0.
> > > PMD: i40e_dev_start(): Invalid link_speeds for port 1; autonegotiation
> > > disabled
> > >
> > >
> > > Just to double-check; is the test#1 adapted to the _new_ API that
> ethdev has
> > to set link speeds? For the output it seems autoneg is disabled => fixed
> speed,
> > hence the new bitmaps have to be used.
> > >
> > > (I am not claiming patchset is bug free; there might be issues still)
> > >
> > > Regards
> > > marc
> > >
> > > Fail to start port 1
> > > Please stop the ports first
> > > Done
> > >
> > > Thanks
> > > Qian
> > >
> > >
> > > -----Original Message-----
> > > From: Cao, Waterman
> > > Sent: Tuesday, March 22, 2016 11:06 AM
> > > To: Glynn, Michael J
> > > Cc: Richardson, Bruce; Zhu, Heqing; O'Driscoll, Tim; Mcnamara, John;
> > > Xu, Qian Q; Cao, Waterman
> > > Subject: RE: DPDK link speed with Intel devices
> > >
> > > Hi Mike,
> > >
> > >         We just knew this patch set last week.
> > >         Since this patch set is required to test with a lot of NIC,
> we need
> > more document from Dev about this patch.
> > >         Currently, Qian is working on with Wenzhuo on it now.
> > >
> > > Waterman
> > >
> > >
> > > -----Original Message-----
> > > From: Glynn, Michael J
> > > Sent: Tuesday, March 22, 2016 1:31 AM
> > > To: Cao, Waterman
> > > <waterman.cao@intel.com<mailto:waterman.cao@intel.com>>
> > > Cc: Richardson, Bruce
> > > <bruce.richardson@intel.com<mailto:bruce.richardson@intel.com>>; Zhu,
> > > Heqing <heqing.zhu@intel.com<mailto:heqing.zhu@intel.com>>;
> > > O'Driscoll, Tim
> > > <tim.odriscoll@intel.com<mailto:tim.odriscoll@intel.com>>; Mcnamara,
> > > John <john.mcnamara@intel.com<mailto:john.mcnamara@intel.com>>
> > > Subject: FW: DPDK link speed with Intel devices
> > > Importance: High
> > >
> > > Hi Waterman, all
> > >
> > > See below - are you aware? And if so where are we with
> testing/resolution?
> > >
> > > Regards
> > > Mike
> > >
> > >
> > >
> > > -----Original Message-----
> > > From: Thomas Monjalon
> > >
> > [mailto:thomas.monjalon@6wind.com<mailto:thomas.monjalon@6wind.com>]
> > > Sent: Monday, March 21, 2016 2:19 PM
> > > To: O'Driscoll, Tim
> > > <tim.odriscoll@intel.com<mailto:tim.odriscoll@intel.com>>; Glynn,
> > > Michael J
> > > <michael.j.glynn@intel.com<mailto:michael.j.glynn@intel.com>>; Zhu,
> > > Heqing <heqing.zhu@intel.com<mailto:heqing.zhu@intel.com>>
> > > Cc: vincent.jardin@6wind.com<mailto:vincent.jardin@6wind.com>
> > > Subject: DPDK link speed with Intel devices
> > >
> > > Hi,
> > >
> > > We are still waiting for test feedbacks for this important patchset:
> > >         ethdev: 100G and link speed API refactoring It is possible
> that it
> > breaks the autonegotiation in e1000/ixgbe/i40e.
> > >
> > > Thanks for taking care.
> > >
> > >
> >
>
>

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

* Re: [PATCH v11 0/8] ethdev: 100G and link speed API refactoring
  2016-03-25 20:41                             ` Marc
@ 2016-03-25 21:30                               ` Marc
  2016-03-26  1:25                                 ` Marc
  2016-03-26  8:08                                 ` Thomas Monjalon
  0 siblings, 2 replies; 167+ messages in thread
From: Marc @ 2016-03-25 21:30 UTC (permalink / raw)
  To: Zhang, Helin
  Cc: Thomas Monjalon, Xu, Qian Q, Xing, Beilei, dev, Ananyev,
	Konstantin, Lu, Wenzhuo, Richardson, Bruce, Glynn, Michael J

On 25 March 2016 at 21:41, Marc <marcdevel@gmail.com> wrote:

>
> On 25 March 2016 at 16:07, Zhang, Helin <helin.zhang@intel.com> wrote:
>
>> Hi Thomas
>>
>> Beilei is investigating that, she will give her findings soon later, and
>> possibly a fix after validating that.
>> Thanks!
>>
>>
> I will try to reproduce this on my side too with the latest v12. I could
> not try latest patchsets, but i40 (XL710) and igb (82540EM) were working on
> my side for previous versions. Which exact NICs were used to test the
> patchset for igb?
>

I am able to reproduce it straight away by applying v12. The problem is
testpmd and in general existing applications have the default value of 0 as
link_speeds for autoneg.

>From v9 to v10 patchset the values ETH_LINK_SPEED_AUTONEG and
ETH_LINK_SPEED_FIXED were flipped. Reverting this makes it work:

marc@Beluga:~/personal/dpdk/tools$ git diff
diff --git a/lib/librte_ether/rte_ethdev.h b/lib/librte_ether/rte_ethdev.h
index ef2502a..fb247a7 100644
--- a/lib/librte_ether/rte_ethdev.h
+++ b/lib/librte_ether/rte_ethdev.h
@@ -244,8 +244,8 @@ struct rte_eth_stats {
 /**
  * Device supported speeds bitmap flags
  */
-#define ETH_LINK_SPEED_FIXED    (0 <<  0)  /**< Disable autoneg (fixed
speed) */
-#define ETH_LINK_SPEED_AUTONEG  (1 <<  0)  /**< Autonegotiate (all speeds)
*/
+#define ETH_LINK_SPEED_AUTONEG  (0 <<  0)  /**< Autonegotiate (all speeds)
*/
+#define ETH_LINK_SPEED_FIXED    (1 <<  0)  /**< Disable autoneg (fixed
speed) */
 #define ETH_LINK_SPEED_10M_HD   (1 <<  1)  /**<  10 Mbps half-duplex */
 #define ETH_LINK_SPEED_10M      (1 <<  2)  /**<  10 Mbps full-duplex */
 #define ETH_LINK_SPEED_100M_HD  (1 <<  3)  /**< 100 Mbps half-duplex */

I think having autoneg == 0 is better. Do you agree Thomas?

With this change my current NIC (I218-LM) is able to initialize:

Option: 27

  Enter hex bitmask of cores to execute testpmd app on
  Example: to execute app on cores 0 to 7, enter 0xff
bitmask: 0x3
Launching app
EAL: Detected lcore 0 as core 0 on socket 0
EAL: Detected lcore 1 as core 0 on socket 0
EAL: Detected lcore 2 as core 1 on socket 0
EAL: Detected lcore 3 as core 1 on socket 0
EAL: Support maximum 128 logical core(s) by configuration.
EAL: Detected 4 lcore(s)
EAL: Probing VFIO support...
EAL: Module /sys/module/vfio_pci not found! error 2 (No such file or
directory)
EAL: VFIO modules not loaded, skipping VFIO support...
EAL: Setting up physically contiguous memory...
EAL: Ask a virtual area of 0x26800000 bytes
EAL: Virtual area found at 0x7f33ef800000 (size = 0x26800000)
EAL: Ask a virtual area of 0x6e00000 bytes
EAL: Virtual area found at 0x7f33e8800000 (size = 0x6e00000)
EAL: Ask a virtual area of 0x800000 bytes
EAL: Virtual area found at 0x7f33e7e00000 (size = 0x800000)
EAL: Ask a virtual area of 0x4400000 bytes
EAL: Virtual area found at 0x7f33e3800000 (size = 0x4400000)
EAL: Ask a virtual area of 0xe00000 bytes
EAL: Virtual area found at 0x7f33e2800000 (size = 0xe00000)
EAL: Ask a virtual area of 0x600000 bytes
EAL: Virtual area found at 0x7f33e2000000 (size = 0x600000)
EAL: Ask a virtual area of 0x200000 bytes
EAL: Virtual area found at 0x7f33e1c00000 (size = 0x200000)
EAL: Ask a virtual area of 0x43600000 bytes
EAL: Virtual area found at 0x7f339e400000 (size = 0x43600000)
EAL: Ask a virtual area of 0x8e00000 bytes
EAL: Virtual area found at 0x7f3395400000 (size = 0x8e00000)
EAL: Ask a virtual area of 0x200000 bytes
EAL: Virtual area found at 0x7f3395000000 (size = 0x200000)
EAL: Ask a virtual area of 0x200000 bytes
EAL: Virtual area found at 0x7f3394c00000 (size = 0x200000)
EAL: Requesting 1024 pages of size 2MB from socket 0
EAL: TSC frequency is ~2593996 KHz
EAL: Master lcore 0 is ready (tid=180078c0;cpuset=[0])
EAL: lcore 1 is ready (tid=94bff700;cpuset=[1])
EAL: PCI device 0000:00:19.0 on NUMA socket -1
EAL:   probe driver: 8086:15a2 rte_em_pmd
EAL:   PCI memory mapped at 0x7f3416000000
EAL:   PCI memory mapped at 0x7f3416020000
PMD: eth_em_dev_init(): port_id 0 vendorID=0x8086 deviceID=0x15a2
Interactive-mode selected
Configuring Port 0 (socket 0)
PMD: eth_em_tx_queue_setup(): sw_ring=0x7f33e210efc0 hw_ring=0x7f33e21110c0
dma_addr=0x745110c0
PMD: eth_em_rx_queue_setup(): sw_ring=0x7f33e20fea80 hw_ring=0x7f33e20fef80
dma_addr=0x744fef80
PMD: eth_em_start(): <<

I am troubleshooting link status reporting, which seems not correct with
l2fwd. I will also double check that fixed speed and autoneg with subset of
speeds work.

@Thomas: once I've fixed this shall I submit v13 or should we wait for more
feedback from the rest of untested NICs? This patchset needs to be tested
by all drivers, at least.

marc


> Marc
>
>
>> Regards,
>> Helin
>>
>> > -----Original Message-----
>> > From: Thomas Monjalon [mailto:thomas.monjalon@6wind.com]
>> > Sent: Friday, March 25, 2016 5:36 PM
>> > To: Xu, Qian Q <qian.q.xu@intel.com>
>> > Cc: dev@dpdk.org; Marc <marcdevel@gmail.com>; Ananyev, Konstantin
>> > <konstantin.ananyev@intel.com>; Lu, Wenzhuo <wenzhuo.lu@intel.com>;
>> > Zhang, Helin <helin.zhang@intel.com>; Richardson, Bruce
>> > <bruce.richardson@intel.com>; Glynn, Michael J <
>> michael.j.glynn@intel.com>
>> > Subject: Re: [dpdk-dev] [PATCH v11 0/8] ethdev: 100G and link speed API
>> > refactoring
>> >
>> > Is there someone investigating the issue?
>> > I think it should be simple to fix for someone mastering these Intel
>> drivers.
>> >
>> > 2016-03-25 01:02, Xu, Qian Q:
>> > > Marc
>> > > #Test1 is just a simple test. Just launch testpmd with these nic port.
>> > > ./testpmd –c 0x3 –n 4 -- -i
>> > >
>> > > Thanks
>> > > Qian
>> > >
>> > > From: marc.sune@gmail.com [mailto:marc.sune@gmail.com] On Behalf Of
>> > > Marc
>> > > Sent: Thursday, March 24, 2016 3:48 PM
>> > > To: Xu, Qian Q
>> > > Cc: Thomas Monjalon; Ananyev, Konstantin; Lu, Wenzhuo; Zhang, Helin;
>> > > Richardson, Bruce; dev@dpdk.org
>> > > Subject: Re: [dpdk-dev] [PATCH v11 0/8] ethdev: 100G and link speed
>> > > API refactoring
>> > >
>> > >
>> > >
>> > > On 24 March 2016 at 07:21, Xu, Qian Q
>> > <qian.q.xu@intel.com<mailto:qian.q.xu@intel.com>> wrote:
>> > > Marc
>> > > I didn’t quite get your points, I observed that after applying this
>> patchset, all
>> > intel nic can’t be started, maybe something wrong happened when you
>> check
>> > the duplex/autoneg value for different NICs. If we want to merge the
>> patchset in
>> > RC2, we need fix them. Maybe not an easy job in several days.
>> > >
>> > > Is this test#1 one of the tests contained in the DPDK repository or
>> is it an
>> > internal test?
>> > >
>> > > Marc
>> > >
>> > >
>> > >
>> > > Thanks
>> > > Qian
>> > >
>> > > From: marc.sune@gmail.com<mailto:marc.sune@gmail.com>
>> > > [mailto:marc.sune@gmail.com<mailto:marc.sune@gmail.com>] On Behalf Of
>> > > Marc
>> > > Sent: Thursday, March 24, 2016 4:54 AM
>> > > To: Xu, Qian Q
>> > > Cc: Thomas Monjalon; Ananyev, Konstantin; Lu, Wenzhuo; Zhang, Helin;
>> > > Richardson, Bruce; dev@dpdk.org<mailto:dev@dpdk.org>
>> > >
>> > > Subject: Re: [dpdk-dev] [PATCH v11 0/8] ethdev: 100G and link speed
>> > > API refactoring
>> > >
>> > > Qian,
>> > >
>> > > On 23 March 2016 at 02:18, Xu, Qian Q
>> > <qian.q.xu@intel.com<mailto:qian.q.xu@intel.com>> wrote:
>> > > We have tested with intel nic and found port can't be started for all
>> > nics:ixgbe/i40e/igb/bonding, see attached mail for more details. Please
>> check
>> > and fix it.
>> > >
>> > >
>> > > Thanks
>> > > Qian
>> > >
>> > > -----Original Message-----
>> > > From: dev [mailto:dev-bounces@dpdk.org<mailto:dev-bounces@dpdk.org>]
>> > > On Behalf Of Thomas Monjalon
>> > > Sent: Wednesday, March 23, 2016 3:59 AM
>> > > To: Ananyev, Konstantin; Lu, Wenzhuo; Zhang, Helin
>> > > Cc: marcdevel@gmail.com<mailto:marcdevel@gmail.com>; Richardson,
>> > > Bruce; dev@dpdk.org<mailto:dev@dpdk.org>
>> > > Subject: Re: [dpdk-dev] [PATCH v11 0/8] ethdev: 100G and link speed
>> > > API refactoring
>> > >
>> > > 2016-03-17 19:08, Thomas Monjalon:
>> > > > There are still too few tests and reviews, especially for
>> > > > autonegotiation with Intel devices (patch #6).
>> > > > I would not be surprised to see some bugs in this rework.
>> > >
>> > > Any feedback about autoneg in e1000/ixgbe/i40e?
>> > > Has it been tested before its integration in RC2?
>> > >
>> > > > The capabilities must be adapted per device. It can be improved in a
>> > > > separate patch.
>> > > >
>> > > > It will be integrated in 16.04-rc2.
>> > > > Please test and review shortly, thanks!
>> > >
>> > >
>> > > ---------- Forwarded message ----------
>> > > From: "Xu, Qian Q" <qian.q.xu@intel.com<mailto:qian.q.xu@intel.com>>
>> > > To: "Cao, Waterman"
>> > > <waterman.cao@intel.com<mailto:waterman.cao@intel.com>>, "Glynn,
>> > > Michael J"
>> > > <michael.j.glynn@intel.com<mailto:michael.j.glynn@intel.com>>
>> > > Cc: "Richardson, Bruce"
>> > > <bruce.richardson@intel.com<mailto:bruce.richardson@intel.com>>,
>> "Zhu,
>> > > Heqing" <heqing.zhu@intel.com<mailto:heqing.zhu@intel.com>>,
>> > > "O'Driscoll, Tim"
>> > > <tim.odriscoll@intel.com<mailto:tim.odriscoll@intel.com>>, "Mcnamara,
>> > > John" <john.mcnamara@intel.com<mailto:john.mcnamara@intel.com>>, "Xu,
>> > > HuilongX" <huilongx.xu@intel.com<mailto:huilongx.xu@intel.com>>, "Fu,
>> > > JingguoX" <jingguox.fu@intel.com<mailto:jingguox.fu@intel.com>>, "Xu,
>> > > Qian Q" <qian.q.xu@intel.com<mailto:qian.q.xu@intel.com>>, "Zhang,
>> > > Helin" <helin.zhang@intel.com<mailto:helin.zhang@intel.com>>
>> > > Date: Tue, 22 Mar 2016 06:41:37 +0000
>> > > Subject: RE: DPDK link speed with Intel devices Hi, all We have worked
>> > > out the basic test cases for the patchset.
>> > > 1. Test the link speed on major Intel NICs to see if the speed is
>> right.
>> > > 2. Test the auto-negoation on major Intel NICs to ensure it's working.
>> > > Nic covered: ixgbe, igb, i40e, fm10k, bonding(SW), virtio(SW)
>> > >
>> > > When we run the Test#1 for all major NICs. We found that all these
>> NIC port(igb,
>> > ixgbe, i40e, fm10k) can't be started. Pls check, if the patch is
>> applied, all INTEL
>> > port can't be start, terrible things!
>> > >
>> > > Interactive-mode selected
>> > > Configuring Port 0 (socket 0)
>> > > PMD: ixgbe_dev_tx_queue_setup(): sw_ring=0x7f13e99e3440
>> > > hw_ring=0x7f13e99e5480 dma_addr=0x8299e5480
>> > > PMD: ixgbe_set_tx_function(): Using simple tx code path
>> > > PMD: ixgbe_set_tx_function(): Vector tx enabled.
>> > > PMD: ixgbe_dev_rx_queue_setup(): sw_ring=0x7f13ffcb8080
>> > > sw_sc_ring=0x7f13ffcbaac0 hw_ring=0x7f13e99d3380 dma_addr=0x8299d3380
>> > > PMD: ixgbe_dev_start(): Invalid link_speeds for port 0;
>> > > autonegotiation disabled Fail to start port 0 Configuring Port 1
>> > > (socket 0)
>> > > PMD: i40e_set_tx_function_flag(): Vector tx can be enabled on this
>> txq.
>> > > PMD: i40e_dev_rx_queue_setup(): Rx Burst Bulk Alloc Preconditions are
>> > satisfied. Rx Burst Bulk Alloc function will be used on port=1, queue=0.
>> > > PMD: i40e_dev_start(): Invalid link_speeds for port 1; autonegotiation
>> > > disabled
>> > >
>> > >
>> > > Just to double-check; is the test#1 adapted to the _new_ API that
>> ethdev has
>> > to set link speeds? For the output it seems autoneg is disabled =>
>> fixed speed,
>> > hence the new bitmaps have to be used.
>> > >
>> > > (I am not claiming patchset is bug free; there might be issues still)
>> > >
>> > > Regards
>> > > marc
>> > >
>> > > Fail to start port 1
>> > > Please stop the ports first
>> > > Done
>> > >
>> > > Thanks
>> > > Qian
>> > >
>> > >
>> > > -----Original Message-----
>> > > From: Cao, Waterman
>> > > Sent: Tuesday, March 22, 2016 11:06 AM
>> > > To: Glynn, Michael J
>> > > Cc: Richardson, Bruce; Zhu, Heqing; O'Driscoll, Tim; Mcnamara, John;
>> > > Xu, Qian Q; Cao, Waterman
>> > > Subject: RE: DPDK link speed with Intel devices
>> > >
>> > > Hi Mike,
>> > >
>> > >         We just knew this patch set last week.
>> > >         Since this patch set is required to test with a lot of NIC,
>> we need
>> > more document from Dev about this patch.
>> > >         Currently, Qian is working on with Wenzhuo on it now.
>> > >
>> > > Waterman
>> > >
>> > >
>> > > -----Original Message-----
>> > > From: Glynn, Michael J
>> > > Sent: Tuesday, March 22, 2016 1:31 AM
>> > > To: Cao, Waterman
>> > > <waterman.cao@intel.com<mailto:waterman.cao@intel.com>>
>> > > Cc: Richardson, Bruce
>> > > <bruce.richardson@intel.com<mailto:bruce.richardson@intel.com>>; Zhu,
>> > > Heqing <heqing.zhu@intel.com<mailto:heqing.zhu@intel.com>>;
>> > > O'Driscoll, Tim
>> > > <tim.odriscoll@intel.com<mailto:tim.odriscoll@intel.com>>; Mcnamara,
>> > > John <john.mcnamara@intel.com<mailto:john.mcnamara@intel.com>>
>> > > Subject: FW: DPDK link speed with Intel devices
>> > > Importance: High
>> > >
>> > > Hi Waterman, all
>> > >
>> > > See below - are you aware? And if so where are we with
>> testing/resolution?
>> > >
>> > > Regards
>> > > Mike
>> > >
>> > >
>> > >
>> > > -----Original Message-----
>> > > From: Thomas Monjalon
>> > >
>> > [mailto:thomas.monjalon@6wind.com<mailto:thomas.monjalon@6wind.com>]
>> > > Sent: Monday, March 21, 2016 2:19 PM
>> > > To: O'Driscoll, Tim
>> > > <tim.odriscoll@intel.com<mailto:tim.odriscoll@intel.com>>; Glynn,
>> > > Michael J
>> > > <michael.j.glynn@intel.com<mailto:michael.j.glynn@intel.com>>; Zhu,
>> > > Heqing <heqing.zhu@intel.com<mailto:heqing.zhu@intel.com>>
>> > > Cc: vincent.jardin@6wind.com<mailto:vincent.jardin@6wind.com>
>> > > Subject: DPDK link speed with Intel devices
>> > >
>> > > Hi,
>> > >
>> > > We are still waiting for test feedbacks for this important patchset:
>> > >         ethdev: 100G and link speed API refactoring It is possible
>> that it
>> > breaks the autonegotiation in e1000/ixgbe/i40e.
>> > >
>> > > Thanks for taking care.
>> > >
>> > >
>> >
>>
>>
>

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

* Re: [PATCH v11 0/8] ethdev: 100G and link speed API refactoring
  2016-03-25 21:30                               ` Marc
@ 2016-03-26  1:25                                 ` Marc
  2016-03-26  8:08                                 ` Thomas Monjalon
  1 sibling, 0 replies; 167+ messages in thread
From: Marc @ 2016-03-26  1:25 UTC (permalink / raw)
  To: Zhang, Helin
  Cc: Thomas Monjalon, Xu, Qian Q, Xing, Beilei, dev, Ananyev,
	Konstantin, Lu, Wenzhuo, Richardson, Bruce, Glynn, Michael J

On 25 March 2016 at 22:30, Marc <marcdevel@gmail.com> wrote:

>
>
> On 25 March 2016 at 21:41, Marc <marcdevel@gmail.com> wrote:
>
>>
>> On 25 March 2016 at 16:07, Zhang, Helin <helin.zhang@intel.com> wrote:
>>
>>> Hi Thomas
>>>
>>> Beilei is investigating that, she will give her findings soon later, and
>>> possibly a fix after validating that.
>>> Thanks!
>>>
>>>
>> I will try to reproduce this on my side too with the latest v12. I could
>> not try latest patchsets, but i40 (XL710) and igb (82540EM) were working on
>> my side for previous versions. Which exact NICs were used to test the
>> patchset for igb?
>>
>
> I am able to reproduce it straight away by applying v12. The problem is
> testpmd and in general existing applications have the default value of 0 as
> link_speeds for autoneg.
>
> From v9 to v10 patchset the values ETH_LINK_SPEED_AUTONEG and
> ETH_LINK_SPEED_FIXED were flipped. Reverting this makes it work:
>
> marc@Beluga:~/personal/dpdk/tools$ git diff
> diff --git a/lib/librte_ether/rte_ethdev.h b/lib/librte_ether/rte_ethdev.h
> index ef2502a..fb247a7 100644
> --- a/lib/librte_ether/rte_ethdev.h
> +++ b/lib/librte_ether/rte_ethdev.h
> @@ -244,8 +244,8 @@ struct rte_eth_stats {
>  /**
>   * Device supported speeds bitmap flags
>   */
> -#define ETH_LINK_SPEED_FIXED    (0 <<  0)  /**< Disable autoneg (fixed
> speed) */
> -#define ETH_LINK_SPEED_AUTONEG  (1 <<  0)  /**< Autonegotiate (all
> speeds) */
> +#define ETH_LINK_SPEED_AUTONEG  (0 <<  0)  /**< Autonegotiate (all
> speeds) */
> +#define ETH_LINK_SPEED_FIXED    (1 <<  0)  /**< Disable autoneg (fixed
> speed) */
>  #define ETH_LINK_SPEED_10M_HD   (1 <<  1)  /**<  10 Mbps half-duplex */
>  #define ETH_LINK_SPEED_10M      (1 <<  2)  /**<  10 Mbps full-duplex */
>  #define ETH_LINK_SPEED_100M_HD  (1 <<  3)  /**< 100 Mbps half-duplex */
>
> I think having autoneg == 0 is better. Do you agree Thomas?
>
> With this change my current NIC (I218-LM) is able to initialize:
>
> Option: 27
>
>   Enter hex bitmask of cores to execute testpmd app on
>   Example: to execute app on cores 0 to 7, enter 0xff
> bitmask: 0x3
> Launching app
> EAL: Detected lcore 0 as core 0 on socket 0
> EAL: Detected lcore 1 as core 0 on socket 0
> EAL: Detected lcore 2 as core 1 on socket 0
> EAL: Detected lcore 3 as core 1 on socket 0
> EAL: Support maximum 128 logical core(s) by configuration.
> EAL: Detected 4 lcore(s)
> EAL: Probing VFIO support...
> EAL: Module /sys/module/vfio_pci not found! error 2 (No such file or
> directory)
> EAL: VFIO modules not loaded, skipping VFIO support...
> EAL: Setting up physically contiguous memory...
> EAL: Ask a virtual area of 0x26800000 bytes
> EAL: Virtual area found at 0x7f33ef800000 (size = 0x26800000)
> EAL: Ask a virtual area of 0x6e00000 bytes
> EAL: Virtual area found at 0x7f33e8800000 (size = 0x6e00000)
> EAL: Ask a virtual area of 0x800000 bytes
> EAL: Virtual area found at 0x7f33e7e00000 (size = 0x800000)
> EAL: Ask a virtual area of 0x4400000 bytes
> EAL: Virtual area found at 0x7f33e3800000 (size = 0x4400000)
> EAL: Ask a virtual area of 0xe00000 bytes
> EAL: Virtual area found at 0x7f33e2800000 (size = 0xe00000)
> EAL: Ask a virtual area of 0x600000 bytes
> EAL: Virtual area found at 0x7f33e2000000 (size = 0x600000)
> EAL: Ask a virtual area of 0x200000 bytes
> EAL: Virtual area found at 0x7f33e1c00000 (size = 0x200000)
> EAL: Ask a virtual area of 0x43600000 bytes
> EAL: Virtual area found at 0x7f339e400000 (size = 0x43600000)
> EAL: Ask a virtual area of 0x8e00000 bytes
> EAL: Virtual area found at 0x7f3395400000 (size = 0x8e00000)
> EAL: Ask a virtual area of 0x200000 bytes
> EAL: Virtual area found at 0x7f3395000000 (size = 0x200000)
> EAL: Ask a virtual area of 0x200000 bytes
> EAL: Virtual area found at 0x7f3394c00000 (size = 0x200000)
> EAL: Requesting 1024 pages of size 2MB from socket 0
> EAL: TSC frequency is ~2593996 KHz
> EAL: Master lcore 0 is ready (tid=180078c0;cpuset=[0])
> EAL: lcore 1 is ready (tid=94bff700;cpuset=[1])
> EAL: PCI device 0000:00:19.0 on NUMA socket -1
> EAL:   probe driver: 8086:15a2 rte_em_pmd
> EAL:   PCI memory mapped at 0x7f3416000000
> EAL:   PCI memory mapped at 0x7f3416020000
> PMD: eth_em_dev_init(): port_id 0 vendorID=0x8086 deviceID=0x15a2
> Interactive-mode selected
> Configuring Port 0 (socket 0)
> PMD: eth_em_tx_queue_setup(): sw_ring=0x7f33e210efc0
> hw_ring=0x7f33e21110c0 dma_addr=0x745110c0
> PMD: eth_em_rx_queue_setup(): sw_ring=0x7f33e20fea80
> hw_ring=0x7f33e20fef80 dma_addr=0x744fef80
> PMD: eth_em_start(): <<
>
> I am troubleshooting link status reporting, which seems not correct with
> l2fwd. I will also double check that fixed speed and autoneg with subset of
> speeds work.
>

Fixed and tested (with I218-LM only) for autoneg (all speeds and subset),
fixed speed and link reporting:

* (unrelated) I found what appears to be a bug in the e1000 base driver,
not reporting changes on link negociation when it is triggered by the peer
(randomly). The behaviour is the same as current master HEAD, so I will
report it separately.

* (unrelated) l2fwd, also in current HEAD, shows a misleading trace "Port
down" at startup, when actually the port is not yet started (or ready).

* From v9 to v10 patchset the values ETH_LINK_SPEED_AUTONEG and
ETH_LINK_SPEED_FIXED were flipped. Reverting this makes it work.

* Setting link to fixed speed was not working after flipping back values
_AUTONEG and _FIXED, since conditions were modified from v9 -> v10
accordingly. Also link reading autoneg flag was incorrect after that. Fixed
for all drivers => NEEDS TESTING, specially for Intel NICs ixgbe and i40e.

* Found two existing bugs in the patchset for e1000 (igb and em), both
fixed:
  - Link reading was always reporting Full duplex.
  - Setting a fixed speed was incorrectly accepting more than 1 speed in
the bitmap.

Attached the set of changes over v12 that will be merged in patch #6 of the
series in v13, for easier reviewing.

Marc

marc@Beluga:~/personal/dpdk$ git diff
328addc166c7217134858fc65febebbd8ddffe7d > v12_fixes.patch
marc@Beluga:~/personal/dpdk$ cat v12_fixes.patch
diff --git a/drivers/net/bnx2x/bnx2x_ethdev.c
b/drivers/net/bnx2x/bnx2x_ethdev.c
index af84175..071b44f 100644
--- a/drivers/net/bnx2x/bnx2x_ethdev.c
+++ b/drivers/net/bnx2x/bnx2x_ethdev.c
@@ -45,8 +45,8 @@ bnx2x_link_update(struct rte_eth_dev *dev)
  dev->data->dev_link.link_duplex = ETH_LINK_HALF_DUPLEX;
  break;
  }
- dev->data->dev_link.link_autoneg = (dev->data->dev_conf.link_speeds &
- ETH_LINK_SPEED_AUTONEG);
+ dev->data->dev_link.link_autoneg = !(dev->data->dev_conf.link_speeds &
+ ETH_LINK_SPEED_FIXED);
  dev->data->dev_link.link_status = sc->link_vars.link_up;
 }

diff --git a/drivers/net/e1000/em_ethdev.c b/drivers/net/e1000/em_ethdev.c
index 3e26ab0..9fb59a2 100644
--- a/drivers/net/e1000/em_ethdev.c
+++ b/drivers/net/e1000/em_ethdev.c
@@ -620,14 +620,14 @@ eth_em_start(struct rte_eth_dev *dev)
  hw->phy.autoneg_advertised = E1000_ALL_SPEED_DUPLEX;
  } else {
  num_speeds = 0;
- autoneg = (*speeds & ETH_LINK_SPEED_AUTONEG);
+ autoneg = (*speeds & ETH_LINK_SPEED_FIXED) == 0;

  /* Reset */
  hw->phy.autoneg_advertised = 0;

  if (*speeds & ~(ETH_LINK_SPEED_10M_HD | ETH_LINK_SPEED_10M |
  ETH_LINK_SPEED_100M_HD | ETH_LINK_SPEED_100M |
- ETH_LINK_SPEED_1G)) {
+ ETH_LINK_SPEED_1G | ETH_LINK_SPEED_FIXED)) {
  num_speeds = -1;
  goto error_invalid_config;
  }
@@ -651,7 +651,7 @@ eth_em_start(struct rte_eth_dev *dev)
  hw->phy.autoneg_advertised |= ADVERTISE_1000_FULL;
  num_speeds++;
  }
- if (num_speeds == 0 || (!autoneg && (num_speeds > 2)))
+ if (num_speeds == 0 || (!autoneg && (num_speeds > 1)))
  goto error_invalid_config;
  }

@@ -1100,14 +1100,18 @@ eth_em_link_update(struct rte_eth_dev *dev, int
wait_to_complete)
  if (link_check && (link.link_status == ETH_LINK_DOWN)) {
  uint16_t duplex, speed;
  hw->mac.ops.get_link_up_info(hw, &speed, &duplex);
- link.link_duplex = duplex ? ETH_LINK_FULL_DUPLEX :
+ link.link_duplex = (duplex == FULL_DUPLEX) ?
+ ETH_LINK_FULL_DUPLEX :
  ETH_LINK_HALF_DUPLEX;
  link.link_speed = speed;
  link.link_status = ETH_LINK_UP;
+ link.link_autoneg = !(dev->data->dev_conf.link_speeds &
+ ETH_LINK_SPEED_FIXED);
  } else if (!link_check && (link.link_status == ETH_LINK_UP)) {
  link.link_speed = 0;
  link.link_duplex = ETH_LINK_HALF_DUPLEX;
  link.link_status = ETH_LINK_DOWN;
+ link.link_autoneg = ETH_LINK_SPEED_FIXED;
  }
  rte_em_dev_atomic_write_link_status(dev, &link);

diff --git a/drivers/net/e1000/igb_ethdev.c b/drivers/net/e1000/igb_ethdev.c
index ced864c..e0053fe 100644
--- a/drivers/net/e1000/igb_ethdev.c
+++ b/drivers/net/e1000/igb_ethdev.c
@@ -1241,14 +1241,14 @@ eth_igb_start(struct rte_eth_dev *dev)
  hw->phy.autoneg_advertised = E1000_ALL_SPEED_DUPLEX;
  } else {
  num_speeds = 0;
- autoneg = (*speeds & ETH_LINK_SPEED_AUTONEG);
+ autoneg = (*speeds & ETH_LINK_SPEED_FIXED) == 0;

  /* Reset */
  hw->phy.autoneg_advertised = 0;

  if (*speeds & ~(ETH_LINK_SPEED_10M_HD | ETH_LINK_SPEED_10M |
  ETH_LINK_SPEED_100M_HD | ETH_LINK_SPEED_100M |
- ETH_LINK_SPEED_1G)) {
+ ETH_LINK_SPEED_1G | ETH_LINK_SPEED_FIXED)) {
  num_speeds = -1;
  goto error_invalid_config;
  }
@@ -1272,7 +1272,7 @@ eth_igb_start(struct rte_eth_dev *dev)
  hw->phy.autoneg_advertised |= ADVERTISE_1000_FULL;
  num_speeds++;
  }
- if (num_speeds == 0 || (!autoneg && (num_speeds > 2)))
+ if (num_speeds == 0 || (!autoneg && (num_speeds > 1)))
  goto error_invalid_config;
  }

@@ -2063,12 +2063,13 @@ eth_igb_link_update(struct rte_eth_dev *dev, int
wait_to_complete)
  if (link_check) {
  uint16_t duplex, speed;
  hw->mac.ops.get_link_up_info(hw, &speed, &duplex);
- link.link_duplex = duplex ? ETH_LINK_FULL_DUPLEX :
+ link.link_duplex = (duplex == FULL_DUPLEX) ?
+ ETH_LINK_FULL_DUPLEX :
  ETH_LINK_HALF_DUPLEX;
  link.link_speed = speed;
  link.link_status = ETH_LINK_UP;
- link.link_autoneg = (dev->data->dev_conf.link_speeds &
- ETH_LINK_SPEED_AUTONEG);
+ link.link_autoneg = !(dev->data->dev_conf.link_speeds &
+ ETH_LINK_SPEED_FIXED);
  } else if (!link_check) {
  link.link_speed = 0;
  link.link_duplex = ETH_LINK_HALF_DUPLEX;
diff --git a/drivers/net/i40e/i40e_ethdev.c b/drivers/net/i40e/i40e_ethdev.c
index 87bc767..c9ef417 100644
--- a/drivers/net/i40e/i40e_ethdev.c
+++ b/drivers/net/i40e/i40e_ethdev.c
@@ -1422,7 +1422,7 @@ i40e_apply_link_speed(struct rte_eth_dev *dev)

  speed = i40e_parse_link_speeds(conf->link_speeds);
  abilities |= I40E_AQ_PHY_ENABLE_ATOMIC_LINK;
- if (conf->link_speeds & ETH_LINK_SPEED_AUTONEG)
+ if (!(conf->link_speeds & ETH_LINK_SPEED_FIXED))
  abilities |= I40E_AQ_PHY_AN_ENABLED;
  else
  abilities |= I40E_AQ_PHY_LINK_ENABLED;
@@ -1442,7 +1442,7 @@ i40e_dev_start(struct rte_eth_dev *dev)

  hw->adapter_stopped = 0;

- if (!(dev->data->dev_conf.link_speeds & ETH_LINK_SPEED_AUTONEG)) {
+ if (dev->data->dev_conf.link_speeds & ETH_LINK_SPEED_FIXED) {
  PMD_INIT_LOG(ERR, "Invalid link_speeds for port %hhu; autonegotiation
disabled",
      dev->data->port_id);
  return -EINVAL;
@@ -1806,8 +1806,8 @@ i40e_dev_link_update(struct rte_eth_dev *dev,
  break;
  }

- link.link_autoneg = (dev->data->dev_conf.link_speeds &
- ETH_LINK_SPEED_AUTONEG);
+ link.link_autoneg = !(dev->data->dev_conf.link_speeds &
+ ETH_LINK_SPEED_FIXED);

 out:
  rte_i40e_dev_atomic_write_link_status(dev, &link);
diff --git a/drivers/net/ixgbe/ixgbe_ethdev.c
b/drivers/net/ixgbe/ixgbe_ethdev.c
index ff23d7d..6cc2da0 100644
--- a/drivers/net/ixgbe/ixgbe_ethdev.c
+++ b/drivers/net/ixgbe/ixgbe_ethdev.c
@@ -2098,9 +2098,12 @@ ixgbe_dev_start(struct rte_eth_dev *dev)

  PMD_INIT_FUNC_TRACE();

- /* IXGBE devices don't support half duplex */
- if (!(dev->data->dev_conf.link_speeds & ETH_LINK_SPEED_AUTONEG)) {
- PMD_INIT_LOG(ERR, "Invalid link_speeds for port %hhu; autonegotiation
disabled",
+ /* IXGBE devices don't support:
+ *    - half duplex (checked afterwards for valid speeds)
+ *    - fixed speed: TODO implement
+ */
+ if (dev->data->dev_conf.link_speeds & ETH_LINK_SPEED_FIXED) {
+ PMD_INIT_LOG(ERR, "Invalid link_speeds for port %hhu; fix speed not
supported",
      dev->data->port_id);
  return -EINVAL;
  }
diff --git a/drivers/net/mlx4/mlx4.c b/drivers/net/mlx4/mlx4.c
index 43ac763..81528c9 100644
--- a/drivers/net/mlx4/mlx4.c
+++ b/drivers/net/mlx4/mlx4.c
@@ -4721,8 +4721,8 @@ mlx4_link_update_unlocked(struct rte_eth_dev *dev,
int wait_to_complete)
  dev_link.link_speed = link_speed;
  dev_link.link_duplex = ((edata.duplex == DUPLEX_HALF) ?
  ETH_LINK_HALF_DUPLEX : ETH_LINK_FULL_DUPLEX);
- dev_link.link_autoneg = (dev->data->dev_conf.link_speeds &
- ETH_LINK_SPEED_AUTONEG);
+ dev_link.link_autoneg = !(dev->data->dev_conf.link_speeds &
+ ETH_LINK_SPEED_FIXED);
  if (memcmp(&dev_link, &dev->data->dev_link, sizeof(dev_link))) {
  /* Link status changed. */
  dev->data->dev_link = dev_link;
diff --git a/drivers/net/mlx5/mlx5_ethdev.c b/drivers/net/mlx5/mlx5_ethdev.c
index 477939f..36b369e 100644
--- a/drivers/net/mlx5/mlx5_ethdev.c
+++ b/drivers/net/mlx5/mlx5_ethdev.c
@@ -630,6 +630,8 @@ mlx5_link_update_unlocked(struct rte_eth_dev *dev, int
wait_to_complete)
  dev_link.link_speed = link_speed;
  dev_link.link_duplex = ((edata.duplex == DUPLEX_HALF) ?
  ETH_LINK_HALF_DUPLEX : ETH_LINK_FULL_DUPLEX);
+ dev_link.link_autoneg = !(dev->data->dev_conf.link_speeds &
+ ETH_LINK_SPEED_FIXED);
  if (memcmp(&dev_link, &dev->data->dev_link, sizeof(dev_link))) {
  /* Link status changed. */
  dev->data->dev_link = dev_link;
diff --git a/lib/librte_ether/rte_ethdev.h b/lib/librte_ether/rte_ethdev.h
index ef2502a..fb247a7 100644
--- a/lib/librte_ether/rte_ethdev.h
+++ b/lib/librte_ether/rte_ethdev.h
@@ -244,8 +244,8 @@ struct rte_eth_stats {
 /**
  * Device supported speeds bitmap flags
  */
-#define ETH_LINK_SPEED_FIXED    (0 <<  0)  /**< Disable autoneg (fixed
speed) */
-#define ETH_LINK_SPEED_AUTONEG  (1 <<  0)  /**< Autonegotiate (all speeds)
*/
+#define ETH_LINK_SPEED_AUTONEG  (0 <<  0)  /**< Autonegotiate (all speeds)
*/
+#define ETH_LINK_SPEED_FIXED    (1 <<  0)  /**< Disable autoneg (fixed
speed) */
 #define ETH_LINK_SPEED_10M_HD   (1 <<  1)  /**<  10 Mbps half-duplex */
 #define ETH_LINK_SPEED_10M      (1 <<  2)  /**<  10 Mbps full-duplex */
 #define ETH_LINK_SPEED_100M_HD  (1 <<  3)  /**< 100 Mbps half-duplex */



>
> @Thomas: once I've fixed this shall I submit v13 or should we wait for
> more feedback from the rest of untested NICs? This patchset needs to be
> tested by all drivers, at least.
>
> marc
>
>
>> Marc
>>
>>
>>> Regards,
>>> Helin
>>>
>>> > -----Original Message-----
>>> > From: Thomas Monjalon [mailto:thomas.monjalon@6wind.com]
>>> > Sent: Friday, March 25, 2016 5:36 PM
>>> > To: Xu, Qian Q <qian.q.xu@intel.com>
>>> > Cc: dev@dpdk.org; Marc <marcdevel@gmail.com>; Ananyev, Konstantin
>>> > <konstantin.ananyev@intel.com>; Lu, Wenzhuo <wenzhuo.lu@intel.com>;
>>> > Zhang, Helin <helin.zhang@intel.com>; Richardson, Bruce
>>> > <bruce.richardson@intel.com>; Glynn, Michael J <
>>> michael.j.glynn@intel.com>
>>> > Subject: Re: [dpdk-dev] [PATCH v11 0/8] ethdev: 100G and link speed API
>>> > refactoring
>>> >
>>> > Is there someone investigating the issue?
>>> > I think it should be simple to fix for someone mastering these Intel
>>> drivers.
>>> >
>>> > 2016-03-25 01:02, Xu, Qian Q:
>>> > > Marc
>>> > > #Test1 is just a simple test. Just launch testpmd with these nic
>>> port.
>>> > > ./testpmd –c 0x3 –n 4 -- -i
>>> > >
>>> > > Thanks
>>> > > Qian
>>> > >
>>> > > From: marc.sune@gmail.com [mailto:marc.sune@gmail.com] On Behalf Of
>>> > > Marc
>>> > > Sent: Thursday, March 24, 2016 3:48 PM
>>> > > To: Xu, Qian Q
>>> > > Cc: Thomas Monjalon; Ananyev, Konstantin; Lu, Wenzhuo; Zhang, Helin;
>>> > > Richardson, Bruce; dev@dpdk.org
>>> > > Subject: Re: [dpdk-dev] [PATCH v11 0/8] ethdev: 100G and link speed
>>> > > API refactoring
>>> > >
>>> > >
>>> > >
>>> > > On 24 March 2016 at 07:21, Xu, Qian Q
>>> > <qian.q.xu@intel.com<mailto:qian.q.xu@intel.com>> wrote:
>>> > > Marc
>>> > > I didn’t quite get your points, I observed that after applying this
>>> patchset, all
>>> > intel nic can’t be started, maybe something wrong happened when you
>>> check
>>> > the duplex/autoneg value for different NICs. If we want to merge the
>>> patchset in
>>> > RC2, we need fix them. Maybe not an easy job in several days.
>>> > >
>>> > > Is this test#1 one of the tests contained in the DPDK repository or
>>> is it an
>>> > internal test?
>>> > >
>>> > > Marc
>>> > >
>>> > >
>>> > >
>>> > > Thanks
>>> > > Qian
>>> > >
>>> > > From: marc.sune@gmail.com<mailto:marc.sune@gmail.com>
>>> > > [mailto:marc.sune@gmail.com<mailto:marc.sune@gmail.com>] On Behalf
>>> Of
>>> > > Marc
>>> > > Sent: Thursday, March 24, 2016 4:54 AM
>>> > > To: Xu, Qian Q
>>> > > Cc: Thomas Monjalon; Ananyev, Konstantin; Lu, Wenzhuo; Zhang, Helin;
>>> > > Richardson, Bruce; dev@dpdk.org<mailto:dev@dpdk.org>
>>> > >
>>> > > Subject: Re: [dpdk-dev] [PATCH v11 0/8] ethdev: 100G and link speed
>>> > > API refactoring
>>> > >
>>> > > Qian,
>>> > >
>>> > > On 23 March 2016 at 02:18, Xu, Qian Q
>>> > <qian.q.xu@intel.com<mailto:qian.q.xu@intel.com>> wrote:
>>> > > We have tested with intel nic and found port can't be started for all
>>> > nics:ixgbe/i40e/igb/bonding, see attached mail for more details.
>>> Please check
>>> > and fix it.
>>> > >
>>> > >
>>> > > Thanks
>>> > > Qian
>>> > >
>>> > > -----Original Message-----
>>> > > From: dev [mailto:dev-bounces@dpdk.org<mailto:dev-bounces@dpdk.org>]
>>> > > On Behalf Of Thomas Monjalon
>>> > > Sent: Wednesday, March 23, 2016 3:59 AM
>>> > > To: Ananyev, Konstantin; Lu, Wenzhuo; Zhang, Helin
>>> > > Cc: marcdevel@gmail.com<mailto:marcdevel@gmail.com>; Richardson,
>>> > > Bruce; dev@dpdk.org<mailto:dev@dpdk.org>
>>> > > Subject: Re: [dpdk-dev] [PATCH v11 0/8] ethdev: 100G and link speed
>>> > > API refactoring
>>> > >
>>> > > 2016-03-17 19:08, Thomas Monjalon:
>>> > > > There are still too few tests and reviews, especially for
>>> > > > autonegotiation with Intel devices (patch #6).
>>> > > > I would not be surprised to see some bugs in this rework.
>>> > >
>>> > > Any feedback about autoneg in e1000/ixgbe/i40e?
>>> > > Has it been tested before its integration in RC2?
>>> > >
>>> > > > The capabilities must be adapted per device. It can be improved in
>>> a
>>> > > > separate patch.
>>> > > >
>>> > > > It will be integrated in 16.04-rc2.
>>> > > > Please test and review shortly, thanks!
>>> > >
>>> > >
>>> > > ---------- Forwarded message ----------
>>> > > From: "Xu, Qian Q" <qian.q.xu@intel.com<mailto:qian.q.xu@intel.com>>
>>> > > To: "Cao, Waterman"
>>> > > <waterman.cao@intel.com<mailto:waterman.cao@intel.com>>, "Glynn,
>>> > > Michael J"
>>> > > <michael.j.glynn@intel.com<mailto:michael.j.glynn@intel.com>>
>>> > > Cc: "Richardson, Bruce"
>>> > > <bruce.richardson@intel.com<mailto:bruce.richardson@intel.com>>,
>>> "Zhu,
>>> > > Heqing" <heqing.zhu@intel.com<mailto:heqing.zhu@intel.com>>,
>>> > > "O'Driscoll, Tim"
>>> > > <tim.odriscoll@intel.com<mailto:tim.odriscoll@intel.com>>,
>>> "Mcnamara,
>>> > > John" <john.mcnamara@intel.com<mailto:john.mcnamara@intel.com>>,
>>> "Xu,
>>> > > HuilongX" <huilongx.xu@intel.com<mailto:huilongx.xu@intel.com>>,
>>> "Fu,
>>> > > JingguoX" <jingguox.fu@intel.com<mailto:jingguox.fu@intel.com>>,
>>> "Xu,
>>> > > Qian Q" <qian.q.xu@intel.com<mailto:qian.q.xu@intel.com>>, "Zhang,
>>> > > Helin" <helin.zhang@intel.com<mailto:helin.zhang@intel.com>>
>>> > > Date: Tue, 22 Mar 2016 06:41:37 +0000
>>> > > Subject: RE: DPDK link speed with Intel devices Hi, all We have
>>> worked
>>> > > out the basic test cases for the patchset.
>>> > > 1. Test the link speed on major Intel NICs to see if the speed is
>>> right.
>>> > > 2. Test the auto-negoation on major Intel NICs to ensure it's
>>> working.
>>> > > Nic covered: ixgbe, igb, i40e, fm10k, bonding(SW), virtio(SW)
>>> > >
>>> > > When we run the Test#1 for all major NICs. We found that all these
>>> NIC port(igb,
>>> > ixgbe, i40e, fm10k) can't be started. Pls check, if the patch is
>>> applied, all INTEL
>>> > port can't be start, terrible things!
>>> > >
>>> > > Interactive-mode selected
>>> > > Configuring Port 0 (socket 0)
>>> > > PMD: ixgbe_dev_tx_queue_setup(): sw_ring=0x7f13e99e3440
>>> > > hw_ring=0x7f13e99e5480 dma_addr=0x8299e5480
>>> > > PMD: ixgbe_set_tx_function(): Using simple tx code path
>>> > > PMD: ixgbe_set_tx_function(): Vector tx enabled.
>>> > > PMD: ixgbe_dev_rx_queue_setup(): sw_ring=0x7f13ffcb8080
>>> > > sw_sc_ring=0x7f13ffcbaac0 hw_ring=0x7f13e99d3380 dma_addr=0x8299d3380
>>> > > PMD: ixgbe_dev_start(): Invalid link_speeds for port 0;
>>> > > autonegotiation disabled Fail to start port 0 Configuring Port 1
>>> > > (socket 0)
>>> > > PMD: i40e_set_tx_function_flag(): Vector tx can be enabled on this
>>> txq.
>>> > > PMD: i40e_dev_rx_queue_setup(): Rx Burst Bulk Alloc Preconditions are
>>> > satisfied. Rx Burst Bulk Alloc function will be used on port=1,
>>> queue=0.
>>> > > PMD: i40e_dev_start(): Invalid link_speeds for port 1;
>>> autonegotiation
>>> > > disabled
>>> > >
>>> > >
>>> > > Just to double-check; is the test#1 adapted to the _new_ API that
>>> ethdev has
>>> > to set link speeds? For the output it seems autoneg is disabled =>
>>> fixed speed,
>>> > hence the new bitmaps have to be used.
>>> > >
>>> > > (I am not claiming patchset is bug free; there might be issues still)
>>> > >
>>> > > Regards
>>> > > marc
>>> > >
>>> > > Fail to start port 1
>>> > > Please stop the ports first
>>> > > Done
>>> > >
>>> > > Thanks
>>> > > Qian
>>> > >
>>> > >
>>> > > -----Original Message-----
>>> > > From: Cao, Waterman
>>> > > Sent: Tuesday, March 22, 2016 11:06 AM
>>> > > To: Glynn, Michael J
>>> > > Cc: Richardson, Bruce; Zhu, Heqing; O'Driscoll, Tim; Mcnamara, John;
>>> > > Xu, Qian Q; Cao, Waterman
>>> > > Subject: RE: DPDK link speed with Intel devices
>>> > >
>>> > > Hi Mike,
>>> > >
>>> > >         We just knew this patch set last week.
>>> > >         Since this patch set is required to test with a lot of NIC,
>>> we need
>>> > more document from Dev about this patch.
>>> > >         Currently, Qian is working on with Wenzhuo on it now.
>>> > >
>>> > > Waterman
>>> > >
>>> > >
>>> > > -----Original Message-----
>>> > > From: Glynn, Michael J
>>> > > Sent: Tuesday, March 22, 2016 1:31 AM
>>> > > To: Cao, Waterman
>>> > > <waterman.cao@intel.com<mailto:waterman.cao@intel.com>>
>>> > > Cc: Richardson, Bruce
>>> > > <bruce.richardson@intel.com<mailto:bruce.richardson@intel.com>>;
>>> Zhu,
>>> > > Heqing <heqing.zhu@intel.com<mailto:heqing.zhu@intel.com>>;
>>> > > O'Driscoll, Tim
>>> > > <tim.odriscoll@intel.com<mailto:tim.odriscoll@intel.com>>; Mcnamara,
>>> > > John <john.mcnamara@intel.com<mailto:john.mcnamara@intel.com>>
>>> > > Subject: FW: DPDK link speed with Intel devices
>>> > > Importance: High
>>> > >
>>> > > Hi Waterman, all
>>> > >
>>> > > See below - are you aware? And if so where are we with
>>> testing/resolution?
>>> > >
>>> > > Regards
>>> > > Mike
>>> > >
>>> > >
>>> > >
>>> > > -----Original Message-----
>>> > > From: Thomas Monjalon
>>> > >
>>> > [mailto:thomas.monjalon@6wind.com<mailto:thomas.monjalon@6wind.com>]
>>> > > Sent: Monday, March 21, 2016 2:19 PM
>>> > > To: O'Driscoll, Tim
>>> > > <tim.odriscoll@intel.com<mailto:tim.odriscoll@intel.com>>; Glynn,
>>> > > Michael J
>>> > > <michael.j.glynn@intel.com<mailto:michael.j.glynn@intel.com>>; Zhu,
>>> > > Heqing <heqing.zhu@intel.com<mailto:heqing.zhu@intel.com>>
>>> > > Cc: vincent.jardin@6wind.com<mailto:vincent.jardin@6wind.com>
>>> > > Subject: DPDK link speed with Intel devices
>>> > >
>>> > > Hi,
>>> > >
>>> > > We are still waiting for test feedbacks for this important patchset:
>>> > >         ethdev: 100G and link speed API refactoring It is possible
>>> that it
>>> > breaks the autonegotiation in e1000/ixgbe/i40e.
>>> > >
>>> > > Thanks for taking care.
>>> > >
>>> > >
>>> >
>>>
>>>
>>
>

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

* [PATCH v13 0/8] ethdev: 100G and link speed API refactoring
  2016-03-25 19:42             ` [PATCH v12 " Thomas Monjalon
                                 ` (7 preceding siblings ...)
  2016-03-25 19:42               ` [PATCH v12 8/8] ethdev: add 100G link speed Thomas Monjalon
@ 2016-03-26  1:27               ` Marc Sune
  2016-03-26  1:27                 ` [PATCH v13 1/8] ethdev: use constants for link state Marc Sune
                                   ` (10 more replies)
  8 siblings, 11 replies; 167+ messages in thread
From: Marc Sune @ 2016-03-26  1:27 UTC (permalink / raw)
  To: Thomas Monjalon, Xu, Qian Q, Xing, Beilei, dev, Ananyev,
	Konstantin, Lu, Wenzhuo, Richardson, Bruce, Glynn, Michael J
  Cc: Marc Sune

There are still too few tests and reviews, especially for
autonegotiation with Intel devices (patch #6).
I would not be surprised to see some bugs in this rework.

The capabilities must be adapted per device. It can be
improved in a separate patch.

It will be integrated in 16.04-rc3.
Please test and review shortly, thanks!

--------

This series of patches adds the following capabilities:

* speed_capa bitmap in rte_eth_dev_info, which is filled by the PMDs
  according to the physical device capabilities.
* refactors link API in ethdev to allow the definition of the advertised
  link speeds, fix speed (no auto-negociation) or advertise all supported
  speeds (default).

--------

v13:
    - Fix startup regression; revert flip of ETH_LINK_SPEED_FIXED and
      ETH_LINK_SPEED_AUTONEG values. ETH_LINK_SPEED_AUTONEG is now 0.
    - Fix incorrect duplex link reporting for e1000.
    - Do not allow more than one speed in the bitmap when
      ETH_LINK_SPEED_FIXED is used for e1000.

v12:
    - rebase on 16.04-rc2
    - fix mlx capabilities
    - update ENA driver

v11:
    - rebase on 16.04-rc1
    - replace on more link status value in e1000 driver
    - merge szedata2 patches
    - remove szedata2 temporary comments in code and doc

v10:
    - rebase
    - rework release notes
    - rearrange patch splitting
    - fix doxygen comments
    - fix typos
    - removed log format of link.link_speed as %d (keep %u)
    - complete ETH_LINK_[DOWN/UP] replacement from 0/1
    - change ETH_LINK_SPEED_AUTONEG to 1
    - replace ETH_LINK_SPEED_NEG by ETH_LINK_SPEED_AUTONEG (1)
    - replace ETH_LINK_SPEED_NO_AUTONEG by ETH_LINK_SPEED_FIXED (0)
    - rework rte_eth_speed_to_bm_flag to rte_eth_speed_bitflag
    - complete 100G support in testpmd

v9: rebased to current HEAD. Reverted numeric speed to 32 bit in struct
    rte_eth_link (no atomic link get > 64bit). Fixed mlx5 driver compilation
    and link speeds. Moved documentation to release_16_04.rst and fixed several
    issues. Upgrade NIC notes with speed capabilities.

v8: Rebased to current HEAD. Modified em driver impl. to not touch base files.
    Merged patch 5 into 3 (map file). Changed numeric speed to a 64 bit value.
    Filled-in speed capabilities for drivers bnx2x, cxgbe, mlx5 and nfp in
    addition to the ones of previous patch sets.

v7: Rebased to current HEAD. Moved documentation to v2.3. Still needs testing
    from PMD maintainers.

v6: Move link_duplex to be part of bitfield. Fixed i40 autoneg flag link
    update code. Added rte_eth_speed_to_bm_flag() to .map file. Fixed other
    spelling issues. Rebased to current HEAD.

v5: revert to v2 speed capabilities patch. Fixed MLX4 speed capabilities
    (thanks N. Laranjeiro). Refactored link speed API to allow setting
    advertised speeds (3/4). Added NO_AUTONEG option to explicitely disable
    auto-negociation. Updated 2.2 rel. notes (4/4). Rebased to current HEAD.

v4: fixed errata in the documentation of field speeds of rte_eth_conf, and
    commit 1/2 message. rebased to v2.1.0. v3 was incorrectly based on
    ~2.1.0-rc1.

v3: rebase to v2.1. unified ETH_LINK_SPEED and ETH_SPEED_CAP into ETH_SPEED.
    Converted field speed in struct rte_eth_conf to speed, to allow a bitmap
    for defining the announced speeds, as suggested M. Brorup. Fixed spelling
    issues.

v2: rebase, converted speed_capa into 32 bits bitmap, fixed alignment
    (checkpatch).


Marc Sune (6):
  ethdev: use constants for link duplex
  app/testpmd: move speed and duplex parsing in a function
  ethdev: rename link speed constants
  ethdev: add speed capabilities
  ethdev: redesign link speed config
  ethdev: convert speed number to bitmap flag

Thomas Monjalon (2):
  ethdev: use constants for link state
  ethdev: add 100G link speed

 app/test-pipeline/init.c                           |   2 +-
 app/test-pmd/cmdline.c                             | 125 ++++++++++-----------
 app/test-pmd/testpmd.c                             |   2 +-
 app/test/test_pmd_perf.c                           |   2 +-
 app/test/virtual_pmd.c                             |   8 +-
 doc/guides/nics/overview.rst                       |   1 +
 doc/guides/nics/szedata2.rst                       |   6 -
 doc/guides/rel_notes/deprecation.rst               |   3 -
 doc/guides/rel_notes/release_16_04.rst             |  22 ++++
 doc/guides/testpmd_app_ug/testpmd_funcs.rst        |   2 +-
 drivers/net/af_packet/rte_eth_af_packet.c          |   9 +-
 drivers/net/bnx2x/bnx2x_ethdev.c                   |   7 +-
 drivers/net/bnx2x/elink.c                          |   2 +-
 drivers/net/bonding/rte_eth_bond_8023ad.c          |  14 +--
 drivers/net/bonding/rte_eth_bond_api.c             |   4 +-
 drivers/net/bonding/rte_eth_bond_pmd.c             |  12 +-
 drivers/net/cxgbe/base/t4_hw.c                     |   8 +-
 drivers/net/cxgbe/cxgbe_ethdev.c                   |   1 +
 drivers/net/e1000/em_ethdev.c                      | 117 +++++++++----------
 drivers/net/e1000/igb_ethdev.c                     | 105 +++++++++--------
 drivers/net/ena/ena_ethdev.c                       |  12 +-
 drivers/net/fm10k/fm10k_ethdev.c                   |   6 +-
 drivers/net/i40e/i40e_ethdev.c                     |  76 +++++++------
 drivers/net/i40e/i40e_ethdev_vf.c                  |  11 +-
 drivers/net/ixgbe/ixgbe_ethdev.c                   |  81 +++++++------
 drivers/net/mlx4/mlx4.c                            |   8 ++
 drivers/net/mlx5/mlx5_ethdev.c                     |  11 ++
 drivers/net/mpipe/mpipe_tilegx.c                   |  18 +--
 drivers/net/nfp/nfp_net.c                          |   6 +-
 drivers/net/null/rte_eth_null.c                    |   9 +-
 drivers/net/pcap/rte_eth_pcap.c                    |   9 +-
 drivers/net/ring/rte_eth_ring.c                    |  13 ++-
 drivers/net/szedata2/rte_eth_szedata2.c            |  19 ++--
 drivers/net/vhost/rte_eth_vhost.c                  |   6 +-
 drivers/net/virtio/virtio_ethdev.c                 |   8 +-
 drivers/net/virtio/virtio_ethdev.h                 |   2 -
 drivers/net/vmxnet3/vmxnet3_ethdev.c               |   5 +-
 drivers/net/xenvirt/rte_eth_xenvirt.c              |   9 +-
 examples/exception_path/main.c                     |   2 +-
 examples/ip_fragmentation/main.c                   |   2 +-
 examples/ip_pipeline/config_parse.c                |   3 +-
 examples/ip_pipeline/init.c                        |   2 +-
 examples/ip_reassembly/main.c                      |   2 +-
 examples/ipsec-secgw/ipsec-secgw.c                 |   2 +-
 examples/ipv4_multicast/main.c                     |   2 +-
 examples/kni/main.c                                |   2 +-
 examples/l2fwd-crypto/main.c                       |   2 +-
 examples/l2fwd-ivshmem/host/host.c                 |   2 +-
 examples/l2fwd-jobstats/main.c                     |   2 +-
 examples/l2fwd-keepalive/main.c                    |   2 +-
 examples/l2fwd/main.c                              |   2 +-
 examples/l3fwd-acl/main.c                          |   2 +-
 examples/l3fwd-power/main.c                        |   2 +-
 examples/l3fwd/main.c                              |   2 +-
 examples/link_status_interrupt/main.c              |   2 +-
 examples/load_balancer/init.c                      |   2 +-
 .../client_server_mp/mp_server/init.c              |   2 +-
 examples/multi_process/l2fwd_fork/main.c           |   2 +-
 examples/multi_process/symmetric_mp/main.c         |   2 +-
 examples/performance-thread/l3fwd-thread/main.c    |   2 +-
 lib/librte_ether/rte_ethdev.c                      |  33 ++++++
 lib/librte_ether/rte_ethdev.h                      |  91 +++++++++++----
 lib/librte_ether/rte_ether_version.map             |   1 +
 63 files changed, 543 insertions(+), 388 deletions(-)

-- 
2.1.4

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

* [PATCH v13 1/8] ethdev: use constants for link state
  2016-03-26  1:27               ` [PATCH v13 0/8] ethdev: 100G and link speed API refactoring Marc Sune
@ 2016-03-26  1:27                 ` Marc Sune
  2016-03-26  1:27                 ` [PATCH v13 2/8] ethdev: use constants for link duplex Marc Sune
                                   ` (9 subsequent siblings)
  10 siblings, 0 replies; 167+ messages in thread
From: Marc Sune @ 2016-03-26  1:27 UTC (permalink / raw)
  To: Thomas Monjalon, Xu, Qian Q, Xing, Beilei, dev, Ananyev,
	Konstantin, Lu, Wenzhuo, Richardson, Bruce, Glynn, Michael J
  Cc: Marc Sune

From: Thomas Monjalon <thomas.monjalon@6wind.com>

Define and use ETH_LINK_UP and ETH_LINK_DOWN where appropriate.

Signed-off-by: Marc Sune <marcdevel@gmail.com>
Signed-off-by: Thomas Monjalon <thomas.monjalon@6wind.com>
---
 app/test-pipeline/init.c                                 |  2 +-
 app/test-pmd/testpmd.c                                   |  2 +-
 app/test/test_pmd_perf.c                                 |  2 +-
 app/test/virtual_pmd.c                                   |  6 +++---
 drivers/net/af_packet/rte_eth_af_packet.c                |  6 +++---
 drivers/net/bnx2x/bnx2x_ethdev.c                         |  2 +-
 drivers/net/bnx2x/elink.c                                |  2 +-
 drivers/net/bonding/rte_eth_bond_api.c                   |  4 ++--
 drivers/net/bonding/rte_eth_bond_pmd.c                   | 12 ++++++------
 drivers/net/e1000/em_ethdev.c                            |  8 ++++----
 drivers/net/e1000/igb_ethdev.c                           |  4 ++--
 drivers/net/fm10k/fm10k_ethdev.c                         |  2 +-
 drivers/net/i40e/i40e_ethdev_vf.c                        |  2 +-
 drivers/net/ixgbe/ixgbe_ethdev.c                         |  4 ++--
 drivers/net/mpipe/mpipe_tilegx.c                         | 12 ++++++------
 drivers/net/nfp/nfp_net.c                                |  2 +-
 drivers/net/null/rte_eth_null.c                          |  6 +++---
 drivers/net/pcap/rte_eth_pcap.c                          |  6 +++---
 drivers/net/ring/rte_eth_ring.c                          | 10 +++++-----
 drivers/net/szedata2/rte_eth_szedata2.c                  |  2 +-
 drivers/net/vhost/rte_eth_vhost.c                        |  6 +++---
 drivers/net/virtio/virtio_ethdev.c                       |  6 +++---
 drivers/net/vmxnet3/vmxnet3_ethdev.c                     |  2 +-
 drivers/net/xenvirt/rte_eth_xenvirt.c                    |  6 +++---
 examples/exception_path/main.c                           |  2 +-
 examples/ip_fragmentation/main.c                         |  2 +-
 examples/ip_pipeline/init.c                              |  2 +-
 examples/ip_reassembly/main.c                            |  2 +-
 examples/ipsec-secgw/ipsec-secgw.c                       |  2 +-
 examples/ipv4_multicast/main.c                           |  2 +-
 examples/kni/main.c                                      |  2 +-
 examples/l2fwd-crypto/main.c                             |  2 +-
 examples/l2fwd-ivshmem/host/host.c                       |  2 +-
 examples/l2fwd-jobstats/main.c                           |  2 +-
 examples/l2fwd-keepalive/main.c                          |  2 +-
 examples/l2fwd/main.c                                    |  2 +-
 examples/l3fwd-acl/main.c                                |  2 +-
 examples/l3fwd-power/main.c                              |  2 +-
 examples/l3fwd/main.c                                    |  2 +-
 examples/link_status_interrupt/main.c                    |  2 +-
 examples/load_balancer/init.c                            |  2 +-
 examples/multi_process/client_server_mp/mp_server/init.c |  2 +-
 examples/multi_process/l2fwd_fork/main.c                 |  2 +-
 examples/multi_process/symmetric_mp/main.c               |  2 +-
 examples/performance-thread/l3fwd-thread/main.c          |  2 +-
 lib/librte_ether/rte_ethdev.h                            |  5 ++++-
 46 files changed, 83 insertions(+), 80 deletions(-)

diff --git a/app/test-pipeline/init.c b/app/test-pipeline/init.c
index db2196b..aef082f 100644
--- a/app/test-pipeline/init.c
+++ b/app/test-pipeline/init.c
@@ -205,7 +205,7 @@ app_ports_check_link(void)
 			link.link_speed / 1000,
 			link.link_status ? "UP" : "DOWN");
 
-		if (link.link_status == 0)
+		if (link.link_status == ETH_LINK_DOWN)
 			all_ports_up = 0;
 	}
 
diff --git a/app/test-pmd/testpmd.c b/app/test-pmd/testpmd.c
index 8605e62..1398c6c 100644
--- a/app/test-pmd/testpmd.c
+++ b/app/test-pmd/testpmd.c
@@ -1641,7 +1641,7 @@ check_all_ports_link_status(uint32_t port_mask)
 				continue;
 			}
 			/* clear all_ports_up flag if any link down */
-			if (link.link_status == 0) {
+			if (link.link_status == ETH_LINK_DOWN) {
 				all_ports_up = 0;
 				break;
 			}
diff --git a/app/test/test_pmd_perf.c b/app/test/test_pmd_perf.c
index 48e16c9..59803f7 100644
--- a/app/test/test_pmd_perf.c
+++ b/app/test/test_pmd_perf.c
@@ -192,7 +192,7 @@ check_all_ports_link_status(uint8_t port_num, uint32_t port_mask)
 				continue;
 			}
 			/* clear all_ports_up flag if any link down */
-			if (link.link_status == 0) {
+			if (link.link_status == ETH_LINK_DOWN) {
 				all_ports_up = 0;
 				break;
 			}
diff --git a/app/test/virtual_pmd.c b/app/test/virtual_pmd.c
index a538c8a..b1d40d7 100644
--- a/app/test/virtual_pmd.c
+++ b/app/test/virtual_pmd.c
@@ -79,7 +79,7 @@ static void  virtual_ethdev_stop(struct rte_eth_dev *eth_dev __rte_unused)
 	void *pkt = NULL;
 	struct virtual_ethdev_private *prv = eth_dev->data->dev_private;
 
-	eth_dev->data->dev_link.link_status = 0;
+	eth_dev->data->dev_link.link_status = ETH_LINK_DOWN;
 	eth_dev->data->dev_started = 0;
 	while (rte_ring_dequeue(prv->rx_queue, &pkt) != -ENOENT)
 		rte_pktmbuf_free(pkt);
@@ -199,7 +199,7 @@ virtual_ethdev_link_update_success(struct rte_eth_dev *bonded_eth_dev,
 		int wait_to_complete __rte_unused)
 {
 	if (!bonded_eth_dev->data->dev_started)
-		bonded_eth_dev->data->dev_link.link_status = 0;
+		bonded_eth_dev->data->dev_link.link_status = ETH_LINK_DOWN;
 
 	return 0;
 }
@@ -603,7 +603,7 @@ virtual_ethdev_create(const char *name, struct ether_addr *mac_addr,
 
 	TAILQ_INIT(&(eth_dev->link_intr_cbs));
 
-	eth_dev->data->dev_link.link_status = 0;
+	eth_dev->data->dev_link.link_status = ETH_LINK_DOWN;
 	eth_dev->data->dev_link.link_speed = ETH_LINK_SPEED_10000;
 	eth_dev->data->dev_link.link_duplex = ETH_LINK_FULL_DUPLEX;
 
diff --git a/drivers/net/af_packet/rte_eth_af_packet.c b/drivers/net/af_packet/rte_eth_af_packet.c
index 5544528..dee7b59 100644
--- a/drivers/net/af_packet/rte_eth_af_packet.c
+++ b/drivers/net/af_packet/rte_eth_af_packet.c
@@ -118,7 +118,7 @@ static const char *drivername = "AF_PACKET PMD";
 static struct rte_eth_link pmd_link = {
 	.link_speed = 10000,
 	.link_duplex = ETH_LINK_FULL_DUPLEX,
-	.link_status = 0
+	.link_status = ETH_LINK_DOWN,
 };
 
 static uint16_t
@@ -234,7 +234,7 @@ eth_af_packet_tx(void *queue, struct rte_mbuf **bufs, uint16_t nb_pkts)
 static int
 eth_dev_start(struct rte_eth_dev *dev)
 {
-	dev->data->dev_link.link_status = 1;
+	dev->data->dev_link.link_status = ETH_LINK_UP;
 	return 0;
 }
 
@@ -257,7 +257,7 @@ eth_dev_stop(struct rte_eth_dev *dev)
 			close(sockfd);
 	}
 
-	dev->data->dev_link.link_status = 0;
+	dev->data->dev_link.link_status = ETH_LINK_DOWN;
 }
 
 static int
diff --git a/drivers/net/bnx2x/bnx2x_ethdev.c b/drivers/net/bnx2x/bnx2x_ethdev.c
index 7e5be08..a3c6c01 100644
--- a/drivers/net/bnx2x/bnx2x_ethdev.c
+++ b/drivers/net/bnx2x/bnx2x_ethdev.c
@@ -266,7 +266,7 @@ bnx2xvf_dev_link_update(struct rte_eth_dev *dev, __rte_unused int wait_to_comple
 	if (sc->old_bulletin.valid_bitmap & (1 << CHANNEL_DOWN)) {
 		PMD_DRV_LOG(ERR, "PF indicated channel is down."
 				"VF device is no longer operational");
-		dev->data->dev_link.link_status = 0;
+		dev->data->dev_link.link_status = ETH_LINK_DOWN;
 	}
 
 	return old_link_status == dev->data->dev_link.link_status ? -1 : 0;
diff --git a/drivers/net/bnx2x/elink.c b/drivers/net/bnx2x/elink.c
index da2366e..b9149b8 100644
--- a/drivers/net/bnx2x/elink.c
+++ b/drivers/net/bnx2x/elink.c
@@ -6312,7 +6312,7 @@ elink_status_t elink_link_update(struct elink_params * params,
 	for (phy_index = ELINK_INT_PHY; phy_index < params->num_phys;
 	     phy_index++) {
 		phy_vars[phy_index].flow_ctrl = 0;
-		phy_vars[phy_index].link_status = 0;
+		phy_vars[phy_index].link_status = ETH_LINK_DOWN;
 		phy_vars[phy_index].line_speed = 0;
 		phy_vars[phy_index].duplex = DUPLEX_FULL;
 		phy_vars[phy_index].phy_link_up = 0;
diff --git a/drivers/net/bonding/rte_eth_bond_api.c b/drivers/net/bonding/rte_eth_bond_api.c
index d473ac2..e9247b5 100644
--- a/drivers/net/bonding/rte_eth_bond_api.c
+++ b/drivers/net/bonding/rte_eth_bond_api.c
@@ -205,7 +205,7 @@ rte_eth_bond_create(const char *name, uint8_t mode, uint8_t socket_id)
 
 	TAILQ_INIT(&(eth_dev->link_intr_cbs));
 
-	eth_dev->data->dev_link.link_status = 0;
+	eth_dev->data->dev_link.link_status = ETH_LINK_DOWN;
 
 	eth_dev->data->mac_addrs = rte_zmalloc_socket(name, ETHER_ADDR_LEN, 0,
 			socket_id);
@@ -420,7 +420,7 @@ __eth_bond_slave_add_lock_free(uint8_t bonded_port_id, uint8_t slave_port_id)
 	if (bonded_eth_dev->data->dev_started) {
 		rte_eth_link_get_nowait(slave_port_id, &link_props);
 
-		 if (link_props.link_status == 1) {
+		 if (link_props.link_status == ETH_LINK_UP) {
 			if (internals->active_slave_count == 0 &&
 			    !internals->user_defined_primary_port)
 				bond_ethdev_primary_set(internals,
diff --git a/drivers/net/bonding/rte_eth_bond_pmd.c b/drivers/net/bonding/rte_eth_bond_pmd.c
index fb26d35..684f285 100644
--- a/drivers/net/bonding/rte_eth_bond_pmd.c
+++ b/drivers/net/bonding/rte_eth_bond_pmd.c
@@ -1506,7 +1506,7 @@ bond_ethdev_start(struct rte_eth_dev *eth_dev)
 		return -1;
 	}
 
-	eth_dev->data->dev_link.link_status = 0;
+	eth_dev->data->dev_link.link_status = ETH_LINK_DOWN;
 	eth_dev->data->dev_started = 1;
 
 	internals = eth_dev->data->dev_private;
@@ -1623,7 +1623,7 @@ bond_ethdev_stop(struct rte_eth_dev *eth_dev)
 	internals->active_slave_count = 0;
 	internals->link_status_polling_enabled = 0;
 
-	eth_dev->data->dev_link.link_status = 0;
+	eth_dev->data->dev_link.link_status = ETH_LINK_DOWN;
 	eth_dev->data->dev_started = 0;
 }
 
@@ -1789,7 +1789,7 @@ bond_ethdev_link_update(struct rte_eth_dev *bonded_eth_dev,
 
 	if (!bonded_eth_dev->data->dev_started ||
 		internals->active_slave_count == 0) {
-		bonded_eth_dev->data->dev_link.link_status = 0;
+		bonded_eth_dev->data->dev_link.link_status = ETH_LINK_DOWN;
 		return 0;
 	} else {
 		struct rte_eth_dev *slave_eth_dev;
@@ -1800,7 +1800,7 @@ bond_ethdev_link_update(struct rte_eth_dev *bonded_eth_dev,
 
 			(*slave_eth_dev->dev_ops->link_update)(slave_eth_dev,
 					wait_to_complete);
-			if (slave_eth_dev->data->dev_link.link_status == 1) {
+			if (slave_eth_dev->data->dev_link.link_status == ETH_LINK_UP) {
 				link_up = 1;
 				break;
 			}
@@ -1969,7 +1969,7 @@ bond_ethdev_lsc_event_callback(uint8_t port_id, enum rte_eth_event_type type,
 		/* if no active slave ports then set this port to be primary port */
 		if (internals->active_slave_count < 1) {
 			/* If first active slave, then change link status */
-			bonded_eth_dev->data->dev_link.link_status = 1;
+			bonded_eth_dev->data->dev_link.link_status = ETH_LINK_UP;
 			internals->current_primary_port = port_id;
 			lsc_flag = 1;
 
@@ -1997,7 +1997,7 @@ bond_ethdev_lsc_event_callback(uint8_t port_id, enum rte_eth_event_type type,
 		 * link properties */
 		if (internals->active_slave_count < 1) {
 			lsc_flag = 1;
-			bonded_eth_dev->data->dev_link.link_status = 0;
+			bonded_eth_dev->data->dev_link.link_status = ETH_LINK_DOWN;
 
 			link_properties_reset(bonded_eth_dev);
 		}
diff --git a/drivers/net/e1000/em_ethdev.c b/drivers/net/e1000/em_ethdev.c
index 1f0a7f4..dc9ed38 100644
--- a/drivers/net/e1000/em_ethdev.c
+++ b/drivers/net/e1000/em_ethdev.c
@@ -1101,14 +1101,14 @@ eth_em_link_update(struct rte_eth_dev *dev, int wait_to_complete)
 	old = link;
 
 	/* Now we check if a transition has happened */
-	if (link_check && (link.link_status == 0)) {
+	if (link_check && (link.link_status == ETH_LINK_DOWN)) {
 		hw->mac.ops.get_link_up_info(hw, &link.link_speed,
 			&link.link_duplex);
-		link.link_status = 1;
-	} else if (!link_check && (link.link_status == 1)) {
+		link.link_status = ETH_LINK_UP;
+	} else if (!link_check && (link.link_status == ETH_LINK_UP)) {
 		link.link_speed = 0;
 		link.link_duplex = 0;
-		link.link_status = 0;
+		link.link_status = ETH_LINK_DOWN;
 	}
 	rte_em_dev_atomic_write_link_status(dev, &link);
 
diff --git a/drivers/net/e1000/igb_ethdev.c b/drivers/net/e1000/igb_ethdev.c
index bd0ae26..045fc63 100644
--- a/drivers/net/e1000/igb_ethdev.c
+++ b/drivers/net/e1000/igb_ethdev.c
@@ -2059,11 +2059,11 @@ eth_igb_link_update(struct rte_eth_dev *dev, int wait_to_complete)
 	if (link_check) {
 		hw->mac.ops.get_link_up_info(hw, &link.link_speed,
 					  &link.link_duplex);
-		link.link_status = 1;
+		link.link_status = ETH_LINK_UP;
 	} else if (!link_check) {
 		link.link_speed = 0;
 		link.link_duplex = 0;
-		link.link_status = 0;
+		link.link_status = ETH_LINK_DOWN;
 	}
 	rte_igb_dev_atomic_write_link_status(dev, &link);
 
diff --git a/drivers/net/fm10k/fm10k_ethdev.c b/drivers/net/fm10k/fm10k_ethdev.c
index b510487..53aa1bb 100644
--- a/drivers/net/fm10k/fm10k_ethdev.c
+++ b/drivers/net/fm10k/fm10k_ethdev.c
@@ -1249,7 +1249,7 @@ fm10k_link_update(struct rte_eth_dev *dev,
 	 * is no 50Gbps Ethernet. */
 	dev->data->dev_link.link_speed  = 0;
 	dev->data->dev_link.link_duplex = ETH_LINK_FULL_DUPLEX;
-	dev->data->dev_link.link_status = 1;
+	dev->data->dev_link.link_status = ETH_LINK_UP;
 
 	return 0;
 }
diff --git a/drivers/net/i40e/i40e_ethdev_vf.c b/drivers/net/i40e/i40e_ethdev_vf.c
index a13d9cc..91df13b 100644
--- a/drivers/net/i40e/i40e_ethdev_vf.c
+++ b/drivers/net/i40e/i40e_ethdev_vf.c
@@ -2127,7 +2127,7 @@ i40evf_dev_link_update(struct rte_eth_dev *dev,
 		/* Always assume it's up, for Linux driver PF host */
 		new_link.link_duplex = ETH_LINK_AUTONEG_DUPLEX;
 		new_link.link_speed  = ETH_LINK_SPEED_10000;
-		new_link.link_status = 1;
+		new_link.link_status = ETH_LINK_UP;
 	}
 	i40evf_dev_atomic_write_link_status(dev, &new_link);
 
diff --git a/drivers/net/ixgbe/ixgbe_ethdev.c b/drivers/net/ixgbe/ixgbe_ethdev.c
index 5812d10..129f36a 100644
--- a/drivers/net/ixgbe/ixgbe_ethdev.c
+++ b/drivers/net/ixgbe/ixgbe_ethdev.c
@@ -3059,7 +3059,7 @@ ixgbe_dev_link_update(struct rte_eth_dev *dev, int wait_to_complete)
 	int link_up;
 	int diag;
 
-	link.link_status = 0;
+	link.link_status = ETH_LINK_DOWN;
 	link.link_speed = 0;
 	link.link_duplex = 0;
 	memset(&old, 0, sizeof(old));
@@ -3088,7 +3088,7 @@ ixgbe_dev_link_update(struct rte_eth_dev *dev, int wait_to_complete)
 			return -1;
 		return 0;
 	}
-	link.link_status = 1;
+	link.link_status = ETH_LINK_UP;
 	link.link_duplex = ETH_LINK_FULL_DUPLEX;
 
 	switch (link_speed) {
diff --git a/drivers/net/mpipe/mpipe_tilegx.c b/drivers/net/mpipe/mpipe_tilegx.c
index 7180e5a..d93ab7e 100644
--- a/drivers/net/mpipe/mpipe_tilegx.c
+++ b/drivers/net/mpipe/mpipe_tilegx.c
@@ -397,11 +397,11 @@ mpipe_link_update(struct rte_eth_dev *dev, int wait_to_complete)
 		if (speed == GXIO_MPIPE_LINK_1G) {
 			new.link_speed = ETH_LINK_SPEED_1000;
 			new.link_duplex = ETH_LINK_FULL_DUPLEX;
-			new.link_status = 1;
+			new.link_status = ETH_LINK_UP;
 		} else if (speed == GXIO_MPIPE_LINK_10G) {
 			new.link_speed = ETH_LINK_SPEED_10000;
 			new.link_duplex = ETH_LINK_FULL_DUPLEX;
-			new.link_status = 1;
+			new.link_status = ETH_LINK_UP;
 		}
 
 		rc = mpipe_link_compare(&old, &new);
@@ -848,9 +848,9 @@ mpipe_start(struct rte_eth_dev *dev)
 
 	/* Start xmit/recv on queues. */
 	for (queue = 0; queue < priv->nb_tx_queues; queue++)
-		mpipe_tx_queue(priv, queue)->q.link_status = 1;
+		mpipe_tx_queue(priv, queue)->q.link_status = ETH_LINK_UP;
 	for (queue = 0; queue < priv->nb_rx_queues; queue++)
-		mpipe_rx_queue(priv, queue)->q.link_status = 1;
+		mpipe_rx_queue(priv, queue)->q.link_status = ETH_LINK_UP;
 	priv->running = 1;
 
 	return 0;
@@ -865,9 +865,9 @@ mpipe_stop(struct rte_eth_dev *dev)
 	int rc;
 
 	for (queue = 0; queue < priv->nb_tx_queues; queue++)
-		mpipe_tx_queue(priv, queue)->q.link_status = 0;
+		mpipe_tx_queue(priv, queue)->q.link_status = ETH_LINK_DOWN;
 	for (queue = 0; queue < priv->nb_rx_queues; queue++)
-		mpipe_rx_queue(priv, queue)->q.link_status = 0;
+		mpipe_rx_queue(priv, queue)->q.link_status = ETH_LINK_DOWN;
 
 	/* Make sure the link_status writes land. */
 	rte_wmb();
diff --git a/drivers/net/nfp/nfp_net.c b/drivers/net/nfp/nfp_net.c
index 92ae48a..80dda85 100644
--- a/drivers/net/nfp/nfp_net.c
+++ b/drivers/net/nfp/nfp_net.c
@@ -817,7 +817,7 @@ nfp_net_link_update(struct rte_eth_dev *dev, __rte_unused int wait_to_complete)
 	memset(&link, 0, sizeof(struct rte_eth_link));
 
 	if (nn_link_status & NFP_NET_CFG_STS_LINK)
-		link.link_status = 1;
+		link.link_status = ETH_LINK_UP;
 
 	link.link_duplex = ETH_LINK_FULL_DUPLEX;
 	/* Other cards can limit the tx and rx rate per VF */
diff --git a/drivers/net/null/rte_eth_null.c b/drivers/net/null/rte_eth_null.c
index 1c354ad..6adea91 100644
--- a/drivers/net/null/rte_eth_null.c
+++ b/drivers/net/null/rte_eth_null.c
@@ -91,7 +91,7 @@ static const char *drivername = "Null PMD";
 static struct rte_eth_link pmd_link = {
 	.link_speed = 10000,
 	.link_duplex = ETH_LINK_FULL_DUPLEX,
-	.link_status = 0
+	.link_status = ETH_LINK_DOWN,
 };
 
 static uint16_t
@@ -199,7 +199,7 @@ eth_dev_start(struct rte_eth_dev *dev)
 	if (dev == NULL)
 		return -EINVAL;
 
-	dev->data->dev_link.link_status = 1;
+	dev->data->dev_link.link_status = ETH_LINK_UP;
 	return 0;
 }
 
@@ -209,7 +209,7 @@ eth_dev_stop(struct rte_eth_dev *dev)
 	if (dev == NULL)
 		return;
 
-	dev->data->dev_link.link_status = 0;
+	dev->data->dev_link.link_status = ETH_LINK_DOWN;
 }
 
 static int
diff --git a/drivers/net/pcap/rte_eth_pcap.c b/drivers/net/pcap/rte_eth_pcap.c
index 5202086..b90c725 100644
--- a/drivers/net/pcap/rte_eth_pcap.c
+++ b/drivers/net/pcap/rte_eth_pcap.c
@@ -125,7 +125,7 @@ static const char *drivername = "Pcap PMD";
 static struct rte_eth_link pmd_link = {
 		.link_speed = 10000,
 		.link_duplex = ETH_LINK_FULL_DUPLEX,
-		.link_status = 0
+		.link_status = ETH_LINK_DOWN,
 };
 
 static int
@@ -428,7 +428,7 @@ eth_dev_start(struct rte_eth_dev *dev)
 
 status_up:
 
-	dev->data->dev_link.link_status = 1;
+	dev->data->dev_link.link_status = ETH_LINK_UP;
 	return 0;
 }
 
@@ -479,7 +479,7 @@ eth_dev_stop(struct rte_eth_dev *dev)
 	}
 
 status_down:
-	dev->data->dev_link.link_status = 0;
+	dev->data->dev_link.link_status = ETH_LINK_DOWN;
 }
 
 static int
diff --git a/drivers/net/ring/rte_eth_ring.c b/drivers/net/ring/rte_eth_ring.c
index ba19cd7..4335c6a 100644
--- a/drivers/net/ring/rte_eth_ring.c
+++ b/drivers/net/ring/rte_eth_ring.c
@@ -79,7 +79,7 @@ static const char *drivername = "Rings PMD";
 static struct rte_eth_link pmd_link = {
 		.link_speed = 10000,
 		.link_duplex = ETH_LINK_FULL_DUPLEX,
-		.link_status = 0
+		.link_status = ETH_LINK_DOWN,
 };
 
 static uint16_t
@@ -119,27 +119,27 @@ eth_dev_configure(struct rte_eth_dev *dev __rte_unused) { return 0; }
 static int
 eth_dev_start(struct rte_eth_dev *dev)
 {
-	dev->data->dev_link.link_status = 1;
+	dev->data->dev_link.link_status = ETH_LINK_UP;
 	return 0;
 }
 
 static void
 eth_dev_stop(struct rte_eth_dev *dev)
 {
-	dev->data->dev_link.link_status = 0;
+	dev->data->dev_link.link_status = ETH_LINK_DOWN;
 }
 
 static int
 eth_dev_set_link_down(struct rte_eth_dev *dev)
 {
-	dev->data->dev_link.link_status = 0;
+	dev->data->dev_link.link_status = ETH_LINK_DOWN;
 	return 0;
 }
 
 static int
 eth_dev_set_link_up(struct rte_eth_dev *dev)
 {
-	dev->data->dev_link.link_status = 1;
+	dev->data->dev_link.link_status = ETH_LINK_UP;
 	return 0;
 }
 
diff --git a/drivers/net/szedata2/rte_eth_szedata2.c b/drivers/net/szedata2/rte_eth_szedata2.c
index 1d6a600..47aa7e3 100644
--- a/drivers/net/szedata2/rte_eth_szedata2.c
+++ b/drivers/net/szedata2/rte_eth_szedata2.c
@@ -1172,7 +1172,7 @@ eth_link_update(struct rte_eth_dev *dev,
 	link.link_duplex = ETH_LINK_FULL_DUPLEX;
 
 	link.link_status = (cgmii_ibuf_is_enabled(ibuf) &&
-			cgmii_ibuf_is_link_up(ibuf)) ? 1 : 0;
+			cgmii_ibuf_is_link_up(ibuf)) ? ETH_LINK_UP : ETH_LINK_DOWN;
 
 	rte_atomic64_cmpset((uint64_t *)dev_link, *(uint64_t *)dev_link,
 			*(uint64_t *)link_ptr);
diff --git a/drivers/net/vhost/rte_eth_vhost.c b/drivers/net/vhost/rte_eth_vhost.c
index ec19c22..4cc6bec 100644
--- a/drivers/net/vhost/rte_eth_vhost.c
+++ b/drivers/net/vhost/rte_eth_vhost.c
@@ -110,7 +110,7 @@ static pthread_t session_th;
 static struct rte_eth_link pmd_link = {
 		.link_speed = 10000,
 		.link_duplex = ETH_LINK_FULL_DUPLEX,
-		.link_status = 0
+		.link_status = ETH_LINK_DOWN
 };
 
 struct rte_vhost_vring_state {
@@ -265,7 +265,7 @@ new_device(struct virtio_net *dev)
 
 	dev->flags |= VIRTIO_DEV_RUNNING;
 	dev->priv = eth_dev;
-	eth_dev->data->dev_link.link_status = 1;
+	eth_dev->data->dev_link.link_status = ETH_LINK_UP;
 
 	for (i = 0; i < eth_dev->data->nb_rx_queues; i++) {
 		vq = eth_dev->data->rx_queues[i];
@@ -323,7 +323,7 @@ destroy_device(volatile struct virtio_net *dev)
 			rte_pause();
 	}
 
-	eth_dev->data->dev_link.link_status = 0;
+	eth_dev->data->dev_link.link_status = ETH_LINK_DOWN;
 
 	dev->priv = NULL;
 	dev->flags &= ~VIRTIO_DEV_RUNNING;
diff --git a/drivers/net/virtio/virtio_ethdev.c b/drivers/net/virtio/virtio_ethdev.c
index 86c96c9..3ebc221 100644
--- a/drivers/net/virtio/virtio_ethdev.c
+++ b/drivers/net/virtio/virtio_ethdev.c
@@ -1410,16 +1410,16 @@ virtio_dev_link_update(struct rte_eth_dev *dev, __rte_unused int wait_to_complet
 				offsetof(struct virtio_net_config, status),
 				&status, sizeof(status));
 		if ((status & VIRTIO_NET_S_LINK_UP) == 0) {
-			link.link_status = 0;
+			link.link_status = ETH_LINK_DOWN;
 			PMD_INIT_LOG(DEBUG, "Port %d is down",
 				     dev->data->port_id);
 		} else {
-			link.link_status = 1;
+			link.link_status = ETH_LINK_UP;
 			PMD_INIT_LOG(DEBUG, "Port %d is up",
 				     dev->data->port_id);
 		}
 	} else {
-		link.link_status = 1;   /* Link up */
+		link.link_status = ETH_LINK_UP;
 	}
 	virtio_dev_atomic_write_link_status(dev, &link);
 
diff --git a/drivers/net/vmxnet3/vmxnet3_ethdev.c b/drivers/net/vmxnet3/vmxnet3_ethdev.c
index f2b6b92..3f26217 100644
--- a/drivers/net/vmxnet3/vmxnet3_ethdev.c
+++ b/drivers/net/vmxnet3/vmxnet3_ethdev.c
@@ -777,7 +777,7 @@ vmxnet3_dev_link_update(struct rte_eth_dev *dev, __attribute__((unused)) int wai
 	ret = VMXNET3_READ_BAR1_REG(hw, VMXNET3_REG_CMD);
 
 	if (ret & 0x1) {
-		link.link_status = 1;
+		link.link_status = ETH_LINK_UP;
 		link.link_duplex = ETH_LINK_FULL_DUPLEX;
 		link.link_speed = ETH_LINK_SPEED_10000;
 	}
diff --git a/drivers/net/xenvirt/rte_eth_xenvirt.c b/drivers/net/xenvirt/rte_eth_xenvirt.c
index 3f31806..9453a06 100644
--- a/drivers/net/xenvirt/rte_eth_xenvirt.c
+++ b/drivers/net/xenvirt/rte_eth_xenvirt.c
@@ -72,7 +72,7 @@ static const char *drivername = "xen virtio PMD";
 static struct rte_eth_link pmd_link = {
 		.link_speed = 10000,
 		.link_duplex = ETH_LINK_FULL_DUPLEX,
-		.link_status = 0
+		.link_status = ETH_LINK_DOWN,
 };
 
 static void
@@ -290,7 +290,7 @@ eth_dev_start(struct rte_eth_dev *dev)
 	struct pmd_internals *pi = (struct pmd_internals *)dev->data->dev_private;
 	int rv;
 
-	dev->data->dev_link.link_status = 1;
+	dev->data->dev_link.link_status = ETH_LINK_UP;
 	while (!virtqueue_full(rxvq)) {
 		m = rte_rxmbuf_alloc(rxvq->mpool);
 		if (m == NULL)
@@ -318,7 +318,7 @@ eth_dev_stop(struct rte_eth_dev *dev)
 {
 	struct pmd_internals *pi = (struct pmd_internals *)dev->data->dev_private;
 
-	dev->data->dev_link.link_status = 0;
+	dev->data->dev_link.link_status = ETH_LINK_DOWN;
 	dev_stop_notify(pi->virtio_idx);
 }
 
diff --git a/examples/exception_path/main.c b/examples/exception_path/main.c
index b3fe170..bec9804 100644
--- a/examples/exception_path/main.c
+++ b/examples/exception_path/main.c
@@ -485,7 +485,7 @@ check_all_ports_link_status(uint8_t port_num, uint32_t port_mask)
 				continue;
 			}
 			/* clear all_ports_up flag if any link down */
-			if (link.link_status == 0) {
+			if (link.link_status == ETH_LINK_DOWN) {
 				all_ports_up = 0;
 				break;
 			}
diff --git a/examples/ip_fragmentation/main.c b/examples/ip_fragmentation/main.c
index 8021702..81a4918 100644
--- a/examples/ip_fragmentation/main.c
+++ b/examples/ip_fragmentation/main.c
@@ -631,7 +631,7 @@ check_all_ports_link_status(uint8_t port_num, uint32_t port_mask)
 				continue;
 			}
 			/* clear all_ports_up flag if any link down */
-			if (link.link_status == 0) {
+			if (link.link_status == ETH_LINK_DOWN) {
 				all_ports_up = 0;
 				break;
 			}
diff --git a/examples/ip_pipeline/init.c b/examples/ip_pipeline/init.c
index e59a6b4..83422e8 100644
--- a/examples/ip_pipeline/init.c
+++ b/examples/ip_pipeline/init.c
@@ -856,7 +856,7 @@ app_check_link(struct app_params *app)
 			link_params.link_speed / 1000,
 			link_params.link_status ? "UP" : "DOWN");
 
-		if (link_params.link_status == 0)
+		if (link_params.link_status == ETH_LINK_DOWN)
 			all_links_up = 0;
 	}
 
diff --git a/examples/ip_reassembly/main.c b/examples/ip_reassembly/main.c
index 19ec46c..c27e735 100644
--- a/examples/ip_reassembly/main.c
+++ b/examples/ip_reassembly/main.c
@@ -763,7 +763,7 @@ check_all_ports_link_status(uint8_t port_num, uint32_t port_mask)
 				continue;
 			}
 			/* clear all_ports_up flag if any link down */
-			if (link.link_status == 0) {
+			if (link.link_status == ETH_LINK_DOWN) {
 				all_ports_up = 0;
 				break;
 			}
diff --git a/examples/ipsec-secgw/ipsec-secgw.c b/examples/ipsec-secgw/ipsec-secgw.c
index d6c9a5d..393f9bd 100644
--- a/examples/ipsec-secgw/ipsec-secgw.c
+++ b/examples/ipsec-secgw/ipsec-secgw.c
@@ -945,7 +945,7 @@ check_all_ports_link_status(uint8_t port_num, uint32_t port_mask)
 				continue;
 			}
 			/* clear all_ports_up flag if any link down */
-			if (link.link_status == 0) {
+			if (link.link_status == ETH_LINK_DOWN) {
 				all_ports_up = 0;
 				break;
 			}
diff --git a/examples/ipv4_multicast/main.c b/examples/ipv4_multicast/main.c
index 5dbea1a..96b4157 100644
--- a/examples/ipv4_multicast/main.c
+++ b/examples/ipv4_multicast/main.c
@@ -642,7 +642,7 @@ check_all_ports_link_status(uint8_t port_num, uint32_t port_mask)
 				continue;
 			}
 			/* clear all_ports_up flag if any link down */
-			if (link.link_status == 0) {
+			if (link.link_status == ETH_LINK_DOWN) {
 				all_ports_up = 0;
 				break;
 			}
diff --git a/examples/kni/main.c b/examples/kni/main.c
index 6d434ad..a5297f2 100644
--- a/examples/kni/main.c
+++ b/examples/kni/main.c
@@ -670,7 +670,7 @@ check_all_ports_link_status(uint8_t port_num, uint32_t port_mask)
 				continue;
 			}
 			/* clear all_ports_up flag if any link down */
-			if (link.link_status == 0) {
+			if (link.link_status == ETH_LINK_DOWN) {
 				all_ports_up = 0;
 				break;
 			}
diff --git a/examples/l2fwd-crypto/main.c b/examples/l2fwd-crypto/main.c
index 5fd4ff1..1c3aaa0 100644
--- a/examples/l2fwd-crypto/main.c
+++ b/examples/l2fwd-crypto/main.c
@@ -1277,7 +1277,7 @@ check_all_ports_link_status(uint8_t port_num, uint32_t port_mask)
 				continue;
 			}
 			/* clear all_ports_up flag if any link down */
-			if (link.link_status == 0) {
+			if (link.link_status == ETH_LINK_DOWN) {
 				all_ports_up = 0;
 				break;
 			}
diff --git a/examples/l2fwd-ivshmem/host/host.c b/examples/l2fwd-ivshmem/host/host.c
index 6e6ed5e..4bd7c41 100644
--- a/examples/l2fwd-ivshmem/host/host.c
+++ b/examples/l2fwd-ivshmem/host/host.c
@@ -371,7 +371,7 @@ check_all_ports_link_status(uint8_t port_num, uint32_t port_mask)
 				continue;
 			}
 			/* clear all_ports_up flag if any link down */
-			if (link.link_status == 0) {
+			if (link.link_status == ETH_LINK_DOWN) {
 				all_ports_up = 0;
 				break;
 			}
diff --git a/examples/l2fwd-jobstats/main.c b/examples/l2fwd-jobstats/main.c
index d1e9bf7..9f3a77d 100644
--- a/examples/l2fwd-jobstats/main.c
+++ b/examples/l2fwd-jobstats/main.c
@@ -746,7 +746,7 @@ check_all_ports_link_status(uint8_t port_num, uint32_t port_mask)
 				continue;
 			}
 			/* clear all_ports_up flag if any link down */
-			if (link.link_status == 0) {
+			if (link.link_status == ETH_LINK_DOWN) {
 				all_ports_up = 0;
 				break;
 			}
diff --git a/examples/l2fwd-keepalive/main.c b/examples/l2fwd-keepalive/main.c
index 94b8677..8da89aa 100644
--- a/examples/l2fwd-keepalive/main.c
+++ b/examples/l2fwd-keepalive/main.c
@@ -499,7 +499,7 @@ check_all_ports_link_status(uint8_t port_num, uint32_t port_mask)
 				continue;
 			}
 			/* clear all_ports_up flag if any link down */
-			if (link.link_status == 0) {
+			if (link.link_status == ETH_LINK_DOWN) {
 				all_ports_up = 0;
 				break;
 			}
diff --git a/examples/l2fwd/main.c b/examples/l2fwd/main.c
index e175681..1ad9488 100644
--- a/examples/l2fwd/main.c
+++ b/examples/l2fwd/main.c
@@ -480,7 +480,7 @@ check_all_ports_link_status(uint8_t port_num, uint32_t port_mask)
 				continue;
 			}
 			/* clear all_ports_up flag if any link down */
-			if (link.link_status == 0) {
+			if (link.link_status == ETH_LINK_DOWN) {
 				all_ports_up = 0;
 				break;
 			}
diff --git a/examples/l3fwd-acl/main.c b/examples/l3fwd-acl/main.c
index 3a895b7..621872f 100644
--- a/examples/l3fwd-acl/main.c
+++ b/examples/l3fwd-acl/main.c
@@ -1858,7 +1858,7 @@ check_all_ports_link_status(uint8_t port_num, uint32_t port_mask)
 				continue;
 			}
 			/* clear all_ports_up flag if any link down */
-			if (link.link_status == 0) {
+			if (link.link_status == ETH_LINK_DOWN) {
 				all_ports_up = 0;
 				break;
 			}
diff --git a/examples/l3fwd-power/main.c b/examples/l3fwd-power/main.c
index e7ebe30..5934efe 100644
--- a/examples/l3fwd-power/main.c
+++ b/examples/l3fwd-power/main.c
@@ -1509,7 +1509,7 @@ check_all_ports_link_status(uint8_t port_num, uint32_t port_mask)
 				continue;
 			}
 			/* clear all_ports_up flag if any link down */
-			if (link.link_status == 0) {
+			if (link.link_status == ETH_LINK_DOWN) {
 				all_ports_up = 0;
 				break;
 			}
diff --git a/examples/l3fwd/main.c b/examples/l3fwd/main.c
index e10dab9..5c627e5 100644
--- a/examples/l3fwd/main.c
+++ b/examples/l3fwd/main.c
@@ -769,7 +769,7 @@ check_all_ports_link_status(uint8_t port_num, uint32_t port_mask)
 				continue;
 			}
 			/* clear all_ports_up flag if any link down */
-			if (link.link_status == 0) {
+			if (link.link_status == ETH_LINK_DOWN) {
 				all_ports_up = 0;
 				break;
 			}
diff --git a/examples/link_status_interrupt/main.c b/examples/link_status_interrupt/main.c
index cbc29bc..9981598 100644
--- a/examples/link_status_interrupt/main.c
+++ b/examples/link_status_interrupt/main.c
@@ -523,7 +523,7 @@ check_all_ports_link_status(uint8_t port_num, uint32_t port_mask)
 				continue;
 			}
 			/* clear all_ports_up flag if any link down */
-			if (link.link_status == 0) {
+			if (link.link_status == ETH_LINK_DOWN) {
 				all_ports_up = 0;
 				break;
 			}
diff --git a/examples/load_balancer/init.c b/examples/load_balancer/init.c
index a96d778..e07850b 100644
--- a/examples/load_balancer/init.c
+++ b/examples/load_balancer/init.c
@@ -395,7 +395,7 @@ check_all_ports_link_status(uint8_t port_num, uint32_t port_mask)
 				continue;
 			}
 			/* clear all_ports_up flag if any link down */
-			if (link.link_status == 0) {
+			if (link.link_status == ETH_LINK_DOWN) {
 				all_ports_up = 0;
 				break;
 			}
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 1078ffd..ecb61c6 100644
--- a/examples/multi_process/client_server_mp/mp_server/init.c
+++ b/examples/multi_process/client_server_mp/mp_server/init.c
@@ -226,7 +226,7 @@ check_all_ports_link_status(uint8_t port_num, uint32_t port_mask)
 				continue;
 			}
 			/* clear all_ports_up flag if any link down */
-			if (link.link_status == 0) {
+			if (link.link_status == ETH_LINK_DOWN) {
 				all_ports_up = 0;
 				break;
 			}
diff --git a/examples/multi_process/l2fwd_fork/main.c b/examples/multi_process/l2fwd_fork/main.c
index aebf531..2dc8b82 100644
--- a/examples/multi_process/l2fwd_fork/main.c
+++ b/examples/multi_process/l2fwd_fork/main.c
@@ -900,7 +900,7 @@ check_all_ports_link_status(uint8_t port_num, uint32_t port_mask)
 				continue;
 			}
 			/* clear all_ports_up flag if any link down */
-			if (link.link_status == 0) {
+			if (link.link_status == ETH_LINK_DOWN) {
 				all_ports_up = 0;
 				break;
 			}
diff --git a/examples/multi_process/symmetric_mp/main.c b/examples/multi_process/symmetric_mp/main.c
index 72bad54..6bbff07 100644
--- a/examples/multi_process/symmetric_mp/main.c
+++ b/examples/multi_process/symmetric_mp/main.c
@@ -388,7 +388,7 @@ check_all_ports_link_status(uint8_t port_num, uint32_t port_mask)
 				continue;
 			}
 			/* clear all_ports_up flag if any link down */
-			if (link.link_status == 0) {
+			if (link.link_status == ETH_LINK_DOWN) {
 				all_ports_up = 0;
 				break;
 			}
diff --git a/examples/performance-thread/l3fwd-thread/main.c b/examples/performance-thread/l3fwd-thread/main.c
index 61c023e..15c0a4d 100644
--- a/examples/performance-thread/l3fwd-thread/main.c
+++ b/examples/performance-thread/l3fwd-thread/main.c
@@ -3408,7 +3408,7 @@ check_all_ports_link_status(uint8_t port_num, uint32_t port_mask)
 				continue;
 			}
 			/* clear all_ports_up flag if any link down */
-			if (link.link_status == 0) {
+			if (link.link_status == ETH_LINK_DOWN) {
 				all_ports_up = 0;
 				break;
 			}
diff --git a/lib/librte_ether/rte_ethdev.h b/lib/librte_ether/rte_ethdev.h
index e7de34a..c5a215a 100644
--- a/lib/librte_ether/rte_ethdev.h
+++ b/lib/librte_ether/rte_ethdev.h
@@ -247,7 +247,7 @@ struct rte_eth_stats {
 struct rte_eth_link {
 	uint16_t link_speed;      /**< ETH_LINK_SPEED_[10, 100, 1000, 10000] */
 	uint16_t link_duplex;     /**< ETH_LINK_[HALF_DUPLEX, FULL_DUPLEX] */
-	uint8_t  link_status : 1; /**< 1 -> link up, 0 -> link down */
+	uint8_t  link_status : 1; /**< ETH_LINK_[DOWN/UP] */
 }__attribute__((aligned(8)));     /**< aligned for atomic64 read/write */
 
 #define ETH_LINK_SPEED_AUTONEG  0       /**< Auto-negotiate link speed. */
@@ -259,9 +259,12 @@ struct rte_eth_link {
 #define ETH_LINK_SPEED_20G      20000   /**< 20 gigabits/second. */
 #define ETH_LINK_SPEED_40G      40000   /**< 40 gigabits/second. */
 
+/* Utility constants */
 #define ETH_LINK_AUTONEG_DUPLEX 0       /**< Auto-negotiate duplex. */
 #define ETH_LINK_HALF_DUPLEX    1       /**< Half-duplex connection. */
 #define ETH_LINK_FULL_DUPLEX    2       /**< Full-duplex connection. */
+#define ETH_LINK_DOWN           0 /**< Link is down. */
+#define ETH_LINK_UP             1 /**< Link is up. */
 
 /**
  * A structure used to configure the ring threshold registers of an RX/TX
-- 
2.1.4

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

* [PATCH v13 2/8] ethdev: use constants for link duplex
  2016-03-26  1:27               ` [PATCH v13 0/8] ethdev: 100G and link speed API refactoring Marc Sune
  2016-03-26  1:27                 ` [PATCH v13 1/8] ethdev: use constants for link state Marc Sune
@ 2016-03-26  1:27                 ` Marc Sune
  2016-03-26  1:27                 ` [PATCH v13 3/8] app/testpmd: move speed and duplex parsing in a function Marc Sune
                                   ` (8 subsequent siblings)
  10 siblings, 0 replies; 167+ messages in thread
From: Marc Sune @ 2016-03-26  1:27 UTC (permalink / raw)
  To: Thomas Monjalon, Xu, Qian Q, Xing, Beilei, dev, Ananyev,
	Konstantin, Lu, Wenzhuo, Richardson, Bruce, Glynn, Michael J
  Cc: Marc Sune

Some duplex values are replaced from 0 to half-duplex when link is down.

Some drivers are still using their own constants for duplex modes.

Signed-off-by: Marc Sune <marcdevel@gmail.com>
---
 drivers/net/e1000/em_ethdev.c      | 2 +-
 drivers/net/e1000/igb_ethdev.c     | 2 +-
 drivers/net/ixgbe/ixgbe_ethdev.c   | 2 +-
 drivers/net/virtio/virtio_ethdev.c | 2 +-
 drivers/net/virtio/virtio_ethdev.h | 2 --
 lib/librte_ether/rte_ethdev.h      | 2 +-
 6 files changed, 5 insertions(+), 7 deletions(-)

diff --git a/drivers/net/e1000/em_ethdev.c b/drivers/net/e1000/em_ethdev.c
index dc9ed38..fad8f2f 100644
--- a/drivers/net/e1000/em_ethdev.c
+++ b/drivers/net/e1000/em_ethdev.c
@@ -1107,7 +1107,7 @@ eth_em_link_update(struct rte_eth_dev *dev, int wait_to_complete)
 		link.link_status = ETH_LINK_UP;
 	} else if (!link_check && (link.link_status == ETH_LINK_UP)) {
 		link.link_speed = 0;
-		link.link_duplex = 0;
+		link.link_duplex = ETH_LINK_HALF_DUPLEX;
 		link.link_status = ETH_LINK_DOWN;
 	}
 	rte_em_dev_atomic_write_link_status(dev, &link);
diff --git a/drivers/net/e1000/igb_ethdev.c b/drivers/net/e1000/igb_ethdev.c
index 045fc63..4dfa7e3 100644
--- a/drivers/net/e1000/igb_ethdev.c
+++ b/drivers/net/e1000/igb_ethdev.c
@@ -2062,7 +2062,7 @@ eth_igb_link_update(struct rte_eth_dev *dev, int wait_to_complete)
 		link.link_status = ETH_LINK_UP;
 	} else if (!link_check) {
 		link.link_speed = 0;
-		link.link_duplex = 0;
+		link.link_duplex = ETH_LINK_HALF_DUPLEX;
 		link.link_status = ETH_LINK_DOWN;
 	}
 	rte_igb_dev_atomic_write_link_status(dev, &link);
diff --git a/drivers/net/ixgbe/ixgbe_ethdev.c b/drivers/net/ixgbe/ixgbe_ethdev.c
index 129f36a..21a3b8c 100644
--- a/drivers/net/ixgbe/ixgbe_ethdev.c
+++ b/drivers/net/ixgbe/ixgbe_ethdev.c
@@ -3061,7 +3061,7 @@ ixgbe_dev_link_update(struct rte_eth_dev *dev, int wait_to_complete)
 
 	link.link_status = ETH_LINK_DOWN;
 	link.link_speed = 0;
-	link.link_duplex = 0;
+	link.link_duplex = ETH_LINK_HALF_DUPLEX;
 	memset(&old, 0, sizeof(old));
 	rte_ixgbe_dev_atomic_read_link_status(dev, &old);
 
diff --git a/drivers/net/virtio/virtio_ethdev.c b/drivers/net/virtio/virtio_ethdev.c
index 3ebc221..63a368a 100644
--- a/drivers/net/virtio/virtio_ethdev.c
+++ b/drivers/net/virtio/virtio_ethdev.c
@@ -1401,7 +1401,7 @@ virtio_dev_link_update(struct rte_eth_dev *dev, __rte_unused int wait_to_complet
 	memset(&link, 0, sizeof(link));
 	virtio_dev_atomic_read_link_status(dev, &link);
 	old = link;
-	link.link_duplex = FULL_DUPLEX;
+	link.link_duplex = ETH_LINK_FULL_DUPLEX;
 	link.link_speed  = SPEED_10G;
 
 	if (vtpci_with_feature(hw, VIRTIO_NET_F_STATUS)) {
diff --git a/drivers/net/virtio/virtio_ethdev.h b/drivers/net/virtio/virtio_ethdev.h
index fed9571..66423a0 100644
--- a/drivers/net/virtio/virtio_ethdev.h
+++ b/drivers/net/virtio/virtio_ethdev.h
@@ -42,8 +42,6 @@
 #define SPEED_100	100
 #define SPEED_1000	1000
 #define SPEED_10G	10000
-#define HALF_DUPLEX	1
-#define FULL_DUPLEX	2
 
 #ifndef PAGE_SIZE
 #define PAGE_SIZE 4096
diff --git a/lib/librte_ether/rte_ethdev.h b/lib/librte_ether/rte_ethdev.h
index c5a215a..2d13f92 100644
--- a/lib/librte_ether/rte_ethdev.h
+++ b/lib/librte_ether/rte_ethdev.h
@@ -246,7 +246,7 @@ struct rte_eth_stats {
  */
 struct rte_eth_link {
 	uint16_t link_speed;      /**< ETH_LINK_SPEED_[10, 100, 1000, 10000] */
-	uint16_t link_duplex;     /**< ETH_LINK_[HALF_DUPLEX, FULL_DUPLEX] */
+	uint16_t link_duplex;     /**< ETH_LINK_[HALF/FULL]_DUPLEX */
 	uint8_t  link_status : 1; /**< ETH_LINK_[DOWN/UP] */
 }__attribute__((aligned(8)));     /**< aligned for atomic64 read/write */
 
-- 
2.1.4

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

* [PATCH v13 3/8] app/testpmd: move speed and duplex parsing in a function
  2016-03-26  1:27               ` [PATCH v13 0/8] ethdev: 100G and link speed API refactoring Marc Sune
  2016-03-26  1:27                 ` [PATCH v13 1/8] ethdev: use constants for link state Marc Sune
  2016-03-26  1:27                 ` [PATCH v13 2/8] ethdev: use constants for link duplex Marc Sune
@ 2016-03-26  1:27                 ` Marc Sune
  2016-03-26  1:27                 ` [PATCH v13 4/8] ethdev: rename link speed constants Marc Sune
                                   ` (7 subsequent siblings)
  10 siblings, 0 replies; 167+ messages in thread
From: Marc Sune @ 2016-03-26  1:27 UTC (permalink / raw)
  To: Thomas Monjalon, Xu, Qian Q, Xing, Beilei, dev, Ananyev,
	Konstantin, Lu, Wenzhuo, Richardson, Bruce, Glynn, Michael J
  Cc: Marc Sune

The code for checking and parsing speed/duplex was duplicated.
The new function is also checking the speed/duplex combination.

Signed-off-by: Marc Sune <marcdevel@gmail.com>
---
 app/test-pmd/cmdline.c | 99 ++++++++++++++++++++++++--------------------------
 1 file changed, 47 insertions(+), 52 deletions(-)

diff --git a/app/test-pmd/cmdline.c b/app/test-pmd/cmdline.c
index 93203f4..eb7bbb4 100644
--- a/app/test-pmd/cmdline.c
+++ b/app/test-pmd/cmdline.c
@@ -988,6 +988,49 @@ struct cmd_config_speed_all {
 	cmdline_fixed_string_t value2;
 };
 
+static int
+parse_and_check_speed_duplex(char *speedstr, char *duplexstr, uint16_t *speed)
+{
+
+	int duplex;
+
+	if (!strcmp(duplexstr, "half")) {
+		duplex = ETH_LINK_HALF_DUPLEX;
+	} else if (!strcmp(duplexstr, "full")) {
+		duplex = ETH_LINK_FULL_DUPLEX;
+	} else if (!strcmp(duplexstr, "auto")) {
+		duplex = ETH_LINK_FULL_DUPLEX;
+	} else {
+		printf("Unknown duplex parameter\n");
+		return -1;
+	}
+
+	if (!strcmp(speedstr, "10")) {
+		*speed = ETH_LINK_SPEED_10;
+	} else if (!strcmp(speedstr, "100")) {
+		*speed = ETH_LINK_SPEED_100;
+	} else {
+		if (duplex != ETH_LINK_FULL_DUPLEX) {
+			printf("Invalid speed/duplex parameters\n");
+			return -1;
+		}
+		if (!strcmp(speedstr, "1000")) {
+			*speed = ETH_LINK_SPEED_1000;
+		} else if (!strcmp(speedstr, "10000")) {
+			*speed = ETH_LINK_SPEED_10G;
+		} else if (!strcmp(speedstr, "40000")) {
+			*speed = ETH_LINK_SPEED_40G;
+		} else if (!strcmp(speedstr, "auto")) {
+			*speed = ETH_LINK_SPEED_AUTONEG;
+		} else {
+			printf("Unknown speed parameter\n");
+			return -1;
+		}
+	}
+
+	return 0;
+}
+
 static void
 cmd_config_speed_all_parsed(void *parsed_result,
 			__attribute__((unused)) struct cmdline *cl,
@@ -1003,33 +1046,9 @@ cmd_config_speed_all_parsed(void *parsed_result,
 		return;
 	}
 
-	if (!strcmp(res->value1, "10"))
-		link_speed = ETH_LINK_SPEED_10;
-	else if (!strcmp(res->value1, "100"))
-		link_speed = ETH_LINK_SPEED_100;
-	else if (!strcmp(res->value1, "1000"))
-		link_speed = ETH_LINK_SPEED_1000;
-	else if (!strcmp(res->value1, "10000"))
-		link_speed = ETH_LINK_SPEED_10G;
-	else if (!strcmp(res->value1, "40000"))
-		link_speed = ETH_LINK_SPEED_40G;
-	else if (!strcmp(res->value1, "auto"))
-		link_speed = ETH_LINK_SPEED_AUTONEG;
-	else {
-		printf("Unknown parameter\n");
+	if (parse_and_check_speed_duplex(res->value1, res->value2,
+			&link_speed) < 0)
 		return;
-	}
-
-	if (!strcmp(res->value2, "half"))
-		link_duplex = ETH_LINK_HALF_DUPLEX;
-	else if (!strcmp(res->value2, "full"))
-		link_duplex = ETH_LINK_FULL_DUPLEX;
-	else if (!strcmp(res->value2, "auto"))
-		link_duplex = ETH_LINK_AUTONEG_DUPLEX;
-	else {
-		printf("Unknown parameter\n");
-		return;
-	}
 
 	FOREACH_PORT(pid, ports) {
 		ports[pid].dev_conf.link_speed = link_speed;
@@ -1102,33 +1121,9 @@ cmd_config_speed_specific_parsed(void *parsed_result,
 	if (port_id_is_invalid(res->id, ENABLED_WARN))
 		return;
 
-	if (!strcmp(res->value1, "10"))
-		link_speed = ETH_LINK_SPEED_10;
-	else if (!strcmp(res->value1, "100"))
-		link_speed = ETH_LINK_SPEED_100;
-	else if (!strcmp(res->value1, "1000"))
-		link_speed = ETH_LINK_SPEED_1000;
-	else if (!strcmp(res->value1, "10000"))
-		link_speed = ETH_LINK_SPEED_10000;
-	else if (!strcmp(res->value1, "40000"))
-		link_speed = ETH_LINK_SPEED_40G;
-	else if (!strcmp(res->value1, "auto"))
-		link_speed = ETH_LINK_SPEED_AUTONEG;
-	else {
-		printf("Unknown parameter\n");
-		return;
-	}
-
-	if (!strcmp(res->value2, "half"))
-		link_duplex = ETH_LINK_HALF_DUPLEX;
-	else if (!strcmp(res->value2, "full"))
-		link_duplex = ETH_LINK_FULL_DUPLEX;
-	else if (!strcmp(res->value2, "auto"))
-		link_duplex = ETH_LINK_AUTONEG_DUPLEX;
-	else {
-		printf("Unknown parameter\n");
+	if (parse_and_check_speed_duplex(res->value1, res->value2,
+			&link_speed) < 0)
 		return;
-	}
 
 	ports[res->id].dev_conf.link_speed = link_speed;
 	ports[res->id].dev_conf.link_duplex = link_duplex;
-- 
2.1.4

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

* [PATCH v13 4/8] ethdev: rename link speed constants
  2016-03-26  1:27               ` [PATCH v13 0/8] ethdev: 100G and link speed API refactoring Marc Sune
                                   ` (2 preceding siblings ...)
  2016-03-26  1:27                 ` [PATCH v13 3/8] app/testpmd: move speed and duplex parsing in a function Marc Sune
@ 2016-03-26  1:27                 ` Marc Sune
  2016-04-06  8:34                   ` Weglicki, MichalX
  2016-03-26  1:27                 ` [PATCH v13 5/8] ethdev: add speed capabilities Marc Sune
                                   ` (6 subsequent siblings)
  10 siblings, 1 reply; 167+ messages in thread
From: Marc Sune @ 2016-03-26  1:27 UTC (permalink / raw)
  To: Thomas Monjalon, Xu, Qian Q, Xing, Beilei, dev, Ananyev,
	Konstantin, Lu, Wenzhuo, Richardson, Bruce, Glynn, Michael J
  Cc: Marc Sune

The speed numbers ETH_LINK_SPEED_ are renamed ETH_SPEED_NUM_.
The prefix ETH_LINK_SPEED_ is kept for AUTONEG and will be used
for bit flags in next patch.

Signed-off-by: Marc Sune <marcdevel@gmail.com>
---
 app/test-pmd/cmdline.c                    | 10 +++++-----
 app/test/virtual_pmd.c                    |  2 +-
 drivers/net/af_packet/rte_eth_af_packet.c |  2 +-
 drivers/net/bonding/rte_eth_bond_8023ad.c | 12 ++++++------
 drivers/net/cxgbe/base/t4_hw.c            |  8 ++++----
 drivers/net/e1000/em_ethdev.c             |  8 ++++----
 drivers/net/e1000/igb_ethdev.c            |  8 ++++----
 drivers/net/ena/ena_ethdev.c              |  2 +-
 drivers/net/i40e/i40e_ethdev.c            | 30 +++++++++++++++---------------
 drivers/net/i40e/i40e_ethdev_vf.c         |  2 +-
 drivers/net/ixgbe/ixgbe_ethdev.c          | 22 +++++++++++-----------
 drivers/net/mpipe/mpipe_tilegx.c          |  4 ++--
 drivers/net/nfp/nfp_net.c                 |  2 +-
 drivers/net/null/rte_eth_null.c           |  2 +-
 drivers/net/pcap/rte_eth_pcap.c           |  2 +-
 drivers/net/ring/rte_eth_ring.c           |  2 +-
 drivers/net/szedata2/rte_eth_szedata2.c   |  8 ++++----
 drivers/net/vmxnet3/vmxnet3_ethdev.c      |  2 +-
 drivers/net/xenvirt/rte_eth_xenvirt.c     |  2 +-
 lib/librte_ether/rte_ethdev.h             | 29 ++++++++++++++++++-----------
 20 files changed, 83 insertions(+), 76 deletions(-)

diff --git a/app/test-pmd/cmdline.c b/app/test-pmd/cmdline.c
index eb7bbb4..815b53b 100644
--- a/app/test-pmd/cmdline.c
+++ b/app/test-pmd/cmdline.c
@@ -1006,20 +1006,20 @@ parse_and_check_speed_duplex(char *speedstr, char *duplexstr, uint16_t *speed)
 	}
 
 	if (!strcmp(speedstr, "10")) {
-		*speed = ETH_LINK_SPEED_10;
+		*speed = ETH_SPEED_NUM_10M;
 	} else if (!strcmp(speedstr, "100")) {
-		*speed = ETH_LINK_SPEED_100;
+		*speed = ETH_SPEED_NUM_100M;
 	} else {
 		if (duplex != ETH_LINK_FULL_DUPLEX) {
 			printf("Invalid speed/duplex parameters\n");
 			return -1;
 		}
 		if (!strcmp(speedstr, "1000")) {
-			*speed = ETH_LINK_SPEED_1000;
+			*speed = ETH_SPEED_NUM_1G;
 		} else if (!strcmp(speedstr, "10000")) {
-			*speed = ETH_LINK_SPEED_10G;
+			*speed = ETH_SPEED_NUM_10G;
 		} else if (!strcmp(speedstr, "40000")) {
-			*speed = ETH_LINK_SPEED_40G;
+			*speed = ETH_SPEED_NUM_40G;
 		} else if (!strcmp(speedstr, "auto")) {
 			*speed = ETH_LINK_SPEED_AUTONEG;
 		} else {
diff --git a/app/test/virtual_pmd.c b/app/test/virtual_pmd.c
index b1d40d7..b4bd2f2 100644
--- a/app/test/virtual_pmd.c
+++ b/app/test/virtual_pmd.c
@@ -604,7 +604,7 @@ virtual_ethdev_create(const char *name, struct ether_addr *mac_addr,
 	TAILQ_INIT(&(eth_dev->link_intr_cbs));
 
 	eth_dev->data->dev_link.link_status = ETH_LINK_DOWN;
-	eth_dev->data->dev_link.link_speed = ETH_LINK_SPEED_10000;
+	eth_dev->data->dev_link.link_speed = ETH_SPEED_NUM_10G;
 	eth_dev->data->dev_link.link_duplex = ETH_LINK_FULL_DUPLEX;
 
 	eth_dev->data->mac_addrs = rte_zmalloc(name, ETHER_ADDR_LEN, 0);
diff --git a/drivers/net/af_packet/rte_eth_af_packet.c b/drivers/net/af_packet/rte_eth_af_packet.c
index dee7b59..641f849 100644
--- a/drivers/net/af_packet/rte_eth_af_packet.c
+++ b/drivers/net/af_packet/rte_eth_af_packet.c
@@ -116,7 +116,7 @@ static const char *valid_arguments[] = {
 static const char *drivername = "AF_PACKET PMD";
 
 static struct rte_eth_link pmd_link = {
-	.link_speed = 10000,
+	.link_speed = ETH_SPEED_NUM_10G,
 	.link_duplex = ETH_LINK_FULL_DUPLEX,
 	.link_status = ETH_LINK_DOWN,
 };
diff --git a/drivers/net/bonding/rte_eth_bond_8023ad.c b/drivers/net/bonding/rte_eth_bond_8023ad.c
index 1b7e93a..ac8306f 100644
--- a/drivers/net/bonding/rte_eth_bond_8023ad.c
+++ b/drivers/net/bonding/rte_eth_bond_8023ad.c
@@ -711,22 +711,22 @@ link_speed_key(uint16_t speed) {
 	case ETH_LINK_SPEED_AUTONEG:
 		key_speed = 0x00;
 		break;
-	case ETH_LINK_SPEED_10:
+	case ETH_SPEED_NUM_10M:
 		key_speed = BOND_LINK_SPEED_KEY_10M;
 		break;
-	case ETH_LINK_SPEED_100:
+	case ETH_SPEED_NUM_100M:
 		key_speed = BOND_LINK_SPEED_KEY_100M;
 		break;
-	case ETH_LINK_SPEED_1000:
+	case ETH_SPEED_NUM_1G:
 		key_speed = BOND_LINK_SPEED_KEY_1000M;
 		break;
-	case ETH_LINK_SPEED_10G:
+	case ETH_SPEED_NUM_10G:
 		key_speed = BOND_LINK_SPEED_KEY_10G;
 		break;
-	case ETH_LINK_SPEED_20G:
+	case ETH_SPEED_NUM_20G:
 		key_speed = BOND_LINK_SPEED_KEY_20G;
 		break;
-	case ETH_LINK_SPEED_40G:
+	case ETH_SPEED_NUM_40G:
 		key_speed = BOND_LINK_SPEED_KEY_40G;
 		break;
 	default:
diff --git a/drivers/net/cxgbe/base/t4_hw.c b/drivers/net/cxgbe/base/t4_hw.c
index 884d2cf..79af806 100644
--- a/drivers/net/cxgbe/base/t4_hw.c
+++ b/drivers/net/cxgbe/base/t4_hw.c
@@ -2159,13 +2159,13 @@ int t4_handle_fw_rpl(struct adapter *adap, const __be64 *rpl)
 		if (stat & F_FW_PORT_CMD_TXPAUSE)
 			fc |= PAUSE_TX;
 		if (stat & V_FW_PORT_CMD_LSPEED(FW_PORT_CAP_SPEED_100M))
-			speed = ETH_LINK_SPEED_100;
+			speed = ETH_SPEED_NUM_100M;
 		else if (stat & V_FW_PORT_CMD_LSPEED(FW_PORT_CAP_SPEED_1G))
-			speed = ETH_LINK_SPEED_1000;
+			speed = ETH_SPEED_NUM_1G;
 		else if (stat & V_FW_PORT_CMD_LSPEED(FW_PORT_CAP_SPEED_10G))
-			speed = ETH_LINK_SPEED_10000;
+			speed = ETH_SPEED_NUM_10G;
 		else if (stat & V_FW_PORT_CMD_LSPEED(FW_PORT_CAP_SPEED_40G))
-			speed = ETH_LINK_SPEED_40G;
+			speed = ETH_SPEED_NUM_40G;
 
 		for_each_port(adap, i) {
 			pi = adap2pinfo(adap, i);
diff --git a/drivers/net/e1000/em_ethdev.c b/drivers/net/e1000/em_ethdev.c
index fad8f2f..473d77f 100644
--- a/drivers/net/e1000/em_ethdev.c
+++ b/drivers/net/e1000/em_ethdev.c
@@ -625,7 +625,7 @@ eth_em_start(struct rte_eth_dev *dev)
 		else
 			goto error_invalid_config;
 		break;
-	case ETH_LINK_SPEED_10:
+	case ETH_SPEED_NUM_10M:
 		if (dev->data->dev_conf.link_duplex == ETH_LINK_AUTONEG_DUPLEX)
 			hw->phy.autoneg_advertised = E1000_ALL_10_SPEED;
 		else if (dev->data->dev_conf.link_duplex ==
@@ -637,7 +637,7 @@ eth_em_start(struct rte_eth_dev *dev)
 		else
 			goto error_invalid_config;
 		break;
-	case ETH_LINK_SPEED_100:
+	case ETH_SPEED_NUM_100M:
 		if (dev->data->dev_conf.link_duplex == ETH_LINK_AUTONEG_DUPLEX)
 			hw->phy.autoneg_advertised = E1000_ALL_100_SPEED;
 		else if (dev->data->dev_conf.link_duplex ==
@@ -649,7 +649,7 @@ eth_em_start(struct rte_eth_dev *dev)
 		else
 			goto error_invalid_config;
 		break;
-	case ETH_LINK_SPEED_1000:
+	case ETH_SPEED_NUM_1G:
 		if ((dev->data->dev_conf.link_duplex ==
 				ETH_LINK_AUTONEG_DUPLEX) ||
 			(dev->data->dev_conf.link_duplex ==
@@ -658,7 +658,7 @@ eth_em_start(struct rte_eth_dev *dev)
 		else
 			goto error_invalid_config;
 		break;
-	case ETH_LINK_SPEED_10000:
+	case ETH_SPEED_NUM_10G:
 	default:
 		goto error_invalid_config;
 	}
diff --git a/drivers/net/e1000/igb_ethdev.c b/drivers/net/e1000/igb_ethdev.c
index 4dfa7e3..86f25f6 100644
--- a/drivers/net/e1000/igb_ethdev.c
+++ b/drivers/net/e1000/igb_ethdev.c
@@ -1244,7 +1244,7 @@ eth_igb_start(struct rte_eth_dev *dev)
 		else
 			goto error_invalid_config;
 		break;
-	case ETH_LINK_SPEED_10:
+	case ETH_SPEED_NUM_10M:
 		if (dev->data->dev_conf.link_duplex == ETH_LINK_AUTONEG_DUPLEX)
 			hw->phy.autoneg_advertised = E1000_ALL_10_SPEED;
 		else if (dev->data->dev_conf.link_duplex == ETH_LINK_HALF_DUPLEX)
@@ -1254,7 +1254,7 @@ eth_igb_start(struct rte_eth_dev *dev)
 		else
 			goto error_invalid_config;
 		break;
-	case ETH_LINK_SPEED_100:
+	case ETH_SPEED_NUM_100M:
 		if (dev->data->dev_conf.link_duplex == ETH_LINK_AUTONEG_DUPLEX)
 			hw->phy.autoneg_advertised = E1000_ALL_100_SPEED;
 		else if (dev->data->dev_conf.link_duplex == ETH_LINK_HALF_DUPLEX)
@@ -1264,14 +1264,14 @@ eth_igb_start(struct rte_eth_dev *dev)
 		else
 			goto error_invalid_config;
 		break;
-	case ETH_LINK_SPEED_1000:
+	case ETH_SPEED_NUM_1G:
 		if ((dev->data->dev_conf.link_duplex == ETH_LINK_AUTONEG_DUPLEX) ||
 				(dev->data->dev_conf.link_duplex == ETH_LINK_FULL_DUPLEX))
 			hw->phy.autoneg_advertised = ADVERTISE_1000_FULL;
 		else
 			goto error_invalid_config;
 		break;
-	case ETH_LINK_SPEED_10000:
+	case ETH_SPEED_NUM_10G:
 	default:
 		goto error_invalid_config;
 	}
diff --git a/drivers/net/ena/ena_ethdev.c b/drivers/net/ena/ena_ethdev.c
index 325c513..1046286 100644
--- a/drivers/net/ena/ena_ethdev.c
+++ b/drivers/net/ena/ena_ethdev.c
@@ -504,7 +504,7 @@ static int ena_link_update(struct rte_eth_dev *dev,
 	struct rte_eth_link *link = &dev->data->dev_link;
 
 	link->link_status = 1;
-	link->link_speed = ETH_LINK_SPEED_10G;
+	link->link_speed = ETH_SPEED_NUM_10G;
 	link->link_duplex = ETH_LINK_FULL_DUPLEX;
 
 	return 0;
diff --git a/drivers/net/i40e/i40e_ethdev.c b/drivers/net/i40e/i40e_ethdev.c
index 05126e8..cce9e6f 100644
--- a/drivers/net/i40e/i40e_ethdev.c
+++ b/drivers/net/i40e/i40e_ethdev.c
@@ -1386,19 +1386,19 @@ i40e_parse_link_speed(uint16_t eth_link_speed)
 	uint8_t link_speed = I40E_LINK_SPEED_UNKNOWN;
 
 	switch (eth_link_speed) {
-	case ETH_LINK_SPEED_40G:
+	case ETH_SPEED_NUM_40G:
 		link_speed = I40E_LINK_SPEED_40GB;
 		break;
-	case ETH_LINK_SPEED_20G:
+	case ETH_SPEED_NUM_20G:
 		link_speed = I40E_LINK_SPEED_20GB;
 		break;
-	case ETH_LINK_SPEED_10G:
+	case ETH_SPEED_NUM_10G:
 		link_speed = I40E_LINK_SPEED_10GB;
 		break;
-	case ETH_LINK_SPEED_1000:
+	case ETH_SPEED_NUM_1G:
 		link_speed = I40E_LINK_SPEED_1GB;
 		break;
-	case ETH_LINK_SPEED_100:
+	case ETH_SPEED_NUM_100M:
 		link_speed = I40E_LINK_SPEED_100MB;
 		break;
 	}
@@ -1768,7 +1768,7 @@ i40e_dev_link_update(struct rte_eth_dev *dev,
 		/* Get link status information from hardware */
 		status = i40e_aq_get_link_info(hw, false, &link_status, NULL);
 		if (status != I40E_SUCCESS) {
-			link.link_speed = ETH_LINK_SPEED_100;
+			link.link_speed = ETH_SPEED_NUM_100M;
 			link.link_duplex = ETH_LINK_FULL_DUPLEX;
 			PMD_DRV_LOG(ERR, "Failed to get link info");
 			goto out;
@@ -1790,22 +1790,22 @@ i40e_dev_link_update(struct rte_eth_dev *dev,
 	/* Parse the link status */
 	switch (link_status.link_speed) {
 	case I40E_LINK_SPEED_100MB:
-		link.link_speed = ETH_LINK_SPEED_100;
+		link.link_speed = ETH_SPEED_NUM_100M;
 		break;
 	case I40E_LINK_SPEED_1GB:
-		link.link_speed = ETH_LINK_SPEED_1000;
+		link.link_speed = ETH_SPEED_NUM_1G;
 		break;
 	case I40E_LINK_SPEED_10GB:
-		link.link_speed = ETH_LINK_SPEED_10G;
+		link.link_speed = ETH_SPEED_NUM_10G;
 		break;
 	case I40E_LINK_SPEED_20GB:
-		link.link_speed = ETH_LINK_SPEED_20G;
+		link.link_speed = ETH_SPEED_NUM_20G;
 		break;
 	case I40E_LINK_SPEED_40GB:
-		link.link_speed = ETH_LINK_SPEED_40G;
+		link.link_speed = ETH_SPEED_NUM_40G;
 		break;
 	default:
-		link.link_speed = ETH_LINK_SPEED_100;
+		link.link_speed = ETH_SPEED_NUM_100M;
 		break;
 	}
 
@@ -8158,15 +8158,15 @@ i40e_start_timecounters(struct rte_eth_dev *dev)
 	rte_i40e_dev_atomic_read_link_status(dev, &link);
 
 	switch (link.link_speed) {
-	case ETH_LINK_SPEED_40G:
+	case ETH_SPEED_NUM_40G:
 		tsync_inc_l = I40E_PTP_40GB_INCVAL & 0xFFFFFFFF;
 		tsync_inc_h = I40E_PTP_40GB_INCVAL >> 32;
 		break;
-	case ETH_LINK_SPEED_10G:
+	case ETH_SPEED_NUM_10G:
 		tsync_inc_l = I40E_PTP_10GB_INCVAL & 0xFFFFFFFF;
 		tsync_inc_h = I40E_PTP_10GB_INCVAL >> 32;
 		break;
-	case ETH_LINK_SPEED_1000:
+	case ETH_SPEED_NUM_1G:
 		tsync_inc_l = I40E_PTP_1GB_INCVAL & 0xFFFFFFFF;
 		tsync_inc_h = I40E_PTP_1GB_INCVAL >> 32;
 		break;
diff --git a/drivers/net/i40e/i40e_ethdev_vf.c b/drivers/net/i40e/i40e_ethdev_vf.c
index 91df13b..295dcd2 100644
--- a/drivers/net/i40e/i40e_ethdev_vf.c
+++ b/drivers/net/i40e/i40e_ethdev_vf.c
@@ -2126,7 +2126,7 @@ i40evf_dev_link_update(struct rte_eth_dev *dev,
 	else {
 		/* Always assume it's up, for Linux driver PF host */
 		new_link.link_duplex = ETH_LINK_AUTONEG_DUPLEX;
-		new_link.link_speed  = ETH_LINK_SPEED_10000;
+		new_link.link_speed  = ETH_SPEED_NUM_10G;
 		new_link.link_status = ETH_LINK_UP;
 	}
 	i40evf_dev_atomic_write_link_status(dev, &new_link);
diff --git a/drivers/net/ixgbe/ixgbe_ethdev.c b/drivers/net/ixgbe/ixgbe_ethdev.c
index 21a3b8c..a0179d2 100644
--- a/drivers/net/ixgbe/ixgbe_ethdev.c
+++ b/drivers/net/ixgbe/ixgbe_ethdev.c
@@ -2199,17 +2199,17 @@ ixgbe_dev_start(struct rte_eth_dev *dev)
 				IXGBE_LINK_SPEED_82599_AUTONEG :
 				IXGBE_LINK_SPEED_82598_AUTONEG;
 		break;
-	case ETH_LINK_SPEED_100:
+	case ETH_SPEED_NUM_100M:
 		/*
 		 * Invalid for 82598 but error will be detected by
 		 * ixgbe_setup_link()
 		 */
 		speed = IXGBE_LINK_SPEED_100_FULL;
 		break;
-	case ETH_LINK_SPEED_1000:
+	case ETH_SPEED_NUM_1G:
 		speed = IXGBE_LINK_SPEED_1GB_FULL;
 		break;
-	case ETH_LINK_SPEED_10000:
+	case ETH_SPEED_NUM_10G:
 		speed = IXGBE_LINK_SPEED_10GB_FULL;
 		break;
 	default:
@@ -3074,7 +3074,7 @@ ixgbe_dev_link_update(struct rte_eth_dev *dev, int wait_to_complete)
 		diag = ixgbe_check_link(hw, &link_speed, &link_up, 1);
 
 	if (diag != 0) {
-		link.link_speed = ETH_LINK_SPEED_100;
+		link.link_speed = ETH_SPEED_NUM_100M;
 		link.link_duplex = ETH_LINK_HALF_DUPLEX;
 		rte_ixgbe_dev_atomic_write_link_status(dev, &link);
 		if (link.link_status == old.link_status)
@@ -3095,19 +3095,19 @@ ixgbe_dev_link_update(struct rte_eth_dev *dev, int wait_to_complete)
 	default:
 	case IXGBE_LINK_SPEED_UNKNOWN:
 		link.link_duplex = ETH_LINK_HALF_DUPLEX;
-		link.link_speed = ETH_LINK_SPEED_100;
+		link.link_speed = ETH_SPEED_NUM_100M;
 		break;
 
 	case IXGBE_LINK_SPEED_100_FULL:
-		link.link_speed = ETH_LINK_SPEED_100;
+		link.link_speed = ETH_SPEED_NUM_100M;
 		break;
 
 	case IXGBE_LINK_SPEED_1GB_FULL:
-		link.link_speed = ETH_LINK_SPEED_1000;
+		link.link_speed = ETH_SPEED_NUM_1G;
 		break;
 
 	case IXGBE_LINK_SPEED_10GB_FULL:
-		link.link_speed = ETH_LINK_SPEED_10000;
+		link.link_speed = ETH_SPEED_NUM_10G;
 		break;
 	}
 	rte_ixgbe_dev_atomic_write_link_status(dev, &link);
@@ -5909,15 +5909,15 @@ ixgbe_start_timecounters(struct rte_eth_dev *dev)
 	rte_ixgbe_dev_atomic_read_link_status(dev, &link);
 
 	switch (link.link_speed) {
-	case ETH_LINK_SPEED_100:
+	case ETH_SPEED_NUM_100M:
 		incval = IXGBE_INCVAL_100;
 		shift = IXGBE_INCVAL_SHIFT_100;
 		break;
-	case ETH_LINK_SPEED_1000:
+	case ETH_SPEED_NUM_1G:
 		incval = IXGBE_INCVAL_1GB;
 		shift = IXGBE_INCVAL_SHIFT_1GB;
 		break;
-	case ETH_LINK_SPEED_10000:
+	case ETH_SPEED_NUM_10G:
 	default:
 		incval = IXGBE_INCVAL_10GB;
 		shift = IXGBE_INCVAL_SHIFT_10GB;
diff --git a/drivers/net/mpipe/mpipe_tilegx.c b/drivers/net/mpipe/mpipe_tilegx.c
index d93ab7e..1a77c7a 100644
--- a/drivers/net/mpipe/mpipe_tilegx.c
+++ b/drivers/net/mpipe/mpipe_tilegx.c
@@ -395,11 +395,11 @@ mpipe_link_update(struct rte_eth_dev *dev, int wait_to_complete)
 		speed = state & GXIO_MPIPE_LINK_SPEED_MASK;
 
 		if (speed == GXIO_MPIPE_LINK_1G) {
-			new.link_speed = ETH_LINK_SPEED_1000;
+			new.link_speed = ETH_SPEED_NUM_1G;
 			new.link_duplex = ETH_LINK_FULL_DUPLEX;
 			new.link_status = ETH_LINK_UP;
 		} else if (speed == GXIO_MPIPE_LINK_10G) {
-			new.link_speed = ETH_LINK_SPEED_10000;
+			new.link_speed = ETH_SPEED_NUM_10G;
 			new.link_duplex = ETH_LINK_FULL_DUPLEX;
 			new.link_status = ETH_LINK_UP;
 		}
diff --git a/drivers/net/nfp/nfp_net.c b/drivers/net/nfp/nfp_net.c
index 80dda85..18ea0f4 100644
--- a/drivers/net/nfp/nfp_net.c
+++ b/drivers/net/nfp/nfp_net.c
@@ -821,7 +821,7 @@ nfp_net_link_update(struct rte_eth_dev *dev, __rte_unused int wait_to_complete)
 
 	link.link_duplex = ETH_LINK_FULL_DUPLEX;
 	/* Other cards can limit the tx and rx rate per VF */
-	link.link_speed = ETH_LINK_SPEED_40G;
+	link.link_speed = ETH_SPEED_NUM_40G;
 
 	if (old.link_status != link.link_status) {
 		nfp_net_dev_atomic_write_link_status(dev, &link);
diff --git a/drivers/net/null/rte_eth_null.c b/drivers/net/null/rte_eth_null.c
index 6adea91..5640585 100644
--- a/drivers/net/null/rte_eth_null.c
+++ b/drivers/net/null/rte_eth_null.c
@@ -89,7 +89,7 @@ struct pmd_internals {
 static struct ether_addr eth_addr = { .addr_bytes = {0} };
 static const char *drivername = "Null PMD";
 static struct rte_eth_link pmd_link = {
-	.link_speed = 10000,
+	.link_speed = ETH_SPEED_NUM_10G,
 	.link_duplex = ETH_LINK_FULL_DUPLEX,
 	.link_status = ETH_LINK_DOWN,
 };
diff --git a/drivers/net/pcap/rte_eth_pcap.c b/drivers/net/pcap/rte_eth_pcap.c
index b90c725..c657951 100644
--- a/drivers/net/pcap/rte_eth_pcap.c
+++ b/drivers/net/pcap/rte_eth_pcap.c
@@ -123,7 +123,7 @@ static int open_single_iface(const char *iface, pcap_t **pcap);
 static struct ether_addr eth_addr = { .addr_bytes = { 0, 0, 0, 0x1, 0x2, 0x3 } };
 static const char *drivername = "Pcap PMD";
 static struct rte_eth_link pmd_link = {
-		.link_speed = 10000,
+		.link_speed = ETH_SPEED_NUM_10G,
 		.link_duplex = ETH_LINK_FULL_DUPLEX,
 		.link_status = ETH_LINK_DOWN,
 };
diff --git a/drivers/net/ring/rte_eth_ring.c b/drivers/net/ring/rte_eth_ring.c
index 4335c6a..58685e9 100644
--- a/drivers/net/ring/rte_eth_ring.c
+++ b/drivers/net/ring/rte_eth_ring.c
@@ -77,7 +77,7 @@ struct pmd_internals {
 
 static const char *drivername = "Rings PMD";
 static struct rte_eth_link pmd_link = {
-		.link_speed = 10000,
+		.link_speed = ETH_SPEED_NUM_10G,
 		.link_duplex = ETH_LINK_FULL_DUPLEX,
 		.link_status = ETH_LINK_DOWN,
 };
diff --git a/drivers/net/szedata2/rte_eth_szedata2.c b/drivers/net/szedata2/rte_eth_szedata2.c
index 47aa7e3..dd1ae9e 100644
--- a/drivers/net/szedata2/rte_eth_szedata2.c
+++ b/drivers/net/szedata2/rte_eth_szedata2.c
@@ -1149,10 +1149,10 @@ eth_link_update(struct rte_eth_dev *dev,
 
 	switch (cgmii_link_speed(ibuf)) {
 	case SZEDATA2_LINK_SPEED_10G:
-		link.link_speed = ETH_LINK_SPEED_10G;
+		link.link_speed = ETH_SPEED_NUM_10G;
 		break;
 	case SZEDATA2_LINK_SPEED_40G:
-		link.link_speed = ETH_LINK_SPEED_40G;
+		link.link_speed = ETH_SPEED_NUM_40G;
 		break;
 	case SZEDATA2_LINK_SPEED_100G:
 		/*
@@ -1161,10 +1161,10 @@ eth_link_update(struct rte_eth_dev *dev,
 		 * will be changed to support 100Gbps speed change
 		 * this value to 100G.
 		 */
-		link.link_speed = ETH_LINK_SPEED_10G;
+		link.link_speed = ETH_SPEED_NUM_10G;
 		break;
 	default:
-		link.link_speed = ETH_LINK_SPEED_10G;
+		link.link_speed = ETH_SPEED_NUM_10G;
 		break;
 	}
 
diff --git a/drivers/net/vmxnet3/vmxnet3_ethdev.c b/drivers/net/vmxnet3/vmxnet3_ethdev.c
index 3f26217..6afa14e 100644
--- a/drivers/net/vmxnet3/vmxnet3_ethdev.c
+++ b/drivers/net/vmxnet3/vmxnet3_ethdev.c
@@ -779,7 +779,7 @@ vmxnet3_dev_link_update(struct rte_eth_dev *dev, __attribute__((unused)) int wai
 	if (ret & 0x1) {
 		link.link_status = ETH_LINK_UP;
 		link.link_duplex = ETH_LINK_FULL_DUPLEX;
-		link.link_speed = ETH_LINK_SPEED_10000;
+		link.link_speed = ETH_SPEED_NUM_10G;
 	}
 
 	vmxnet3_dev_atomic_write_link_status(dev, &link);
diff --git a/drivers/net/xenvirt/rte_eth_xenvirt.c b/drivers/net/xenvirt/rte_eth_xenvirt.c
index 9453a06..77d3ba1 100644
--- a/drivers/net/xenvirt/rte_eth_xenvirt.c
+++ b/drivers/net/xenvirt/rte_eth_xenvirt.c
@@ -70,7 +70,7 @@ static int virtio_idx = 0;
 static const char *drivername = "xen virtio PMD";
 
 static struct rte_eth_link pmd_link = {
-		.link_speed = 10000,
+		.link_speed = ETH_SPEED_NUM_10G,
 		.link_duplex = ETH_LINK_FULL_DUPLEX,
 		.link_status = ETH_LINK_DOWN,
 };
diff --git a/lib/librte_ether/rte_ethdev.h b/lib/librte_ether/rte_ethdev.h
index 2d13f92..bc7d607 100644
--- a/lib/librte_ether/rte_ethdev.h
+++ b/lib/librte_ether/rte_ethdev.h
@@ -242,23 +242,30 @@ struct rte_eth_stats {
 };
 
 /**
+ * Ethernet numeric link speeds in Mbps
+ */
+#define ETH_LINK_SPEED_AUTONEG     0 /**< Auto-negotiate link speed. */
+#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 */
+
+/**
  * A structure used to retrieve link-level information of an Ethernet port.
  */
 struct rte_eth_link {
-	uint16_t link_speed;      /**< ETH_LINK_SPEED_[10, 100, 1000, 10000] */
+	uint16_t link_speed;      /**< ETH_SPEED_NUM_ */
 	uint16_t link_duplex;     /**< ETH_LINK_[HALF/FULL]_DUPLEX */
 	uint8_t  link_status : 1; /**< ETH_LINK_[DOWN/UP] */
 }__attribute__((aligned(8)));     /**< aligned for atomic64 read/write */
 
-#define ETH_LINK_SPEED_AUTONEG  0       /**< Auto-negotiate link speed. */
-#define ETH_LINK_SPEED_10       10      /**< 10 megabits/second. */
-#define ETH_LINK_SPEED_100      100     /**< 100 megabits/second. */
-#define ETH_LINK_SPEED_1000     1000    /**< 1 gigabits/second. */
-#define ETH_LINK_SPEED_10000    10000   /**< 10 gigabits/second. */
-#define ETH_LINK_SPEED_10G      10000   /**< alias of 10 gigabits/second. */
-#define ETH_LINK_SPEED_20G      20000   /**< 20 gigabits/second. */
-#define ETH_LINK_SPEED_40G      40000   /**< 40 gigabits/second. */
-
 /* Utility constants */
 #define ETH_LINK_AUTONEG_DUPLEX 0       /**< Auto-negotiate duplex. */
 #define ETH_LINK_HALF_DUPLEX    1       /**< Half-duplex connection. */
@@ -779,7 +786,7 @@ struct rte_intr_conf {
  */
 struct rte_eth_conf {
 	uint16_t link_speed;
-	/**< ETH_LINK_SPEED_10[0|00|000], or 0 for autonegotation */
+	/**< ETH_SPEED_NUM_ or 0 for autonegotiation */
 	uint16_t link_duplex;
 	/**< ETH_LINK_[HALF_DUPLEX|FULL_DUPLEX], or 0 for autonegotation */
 	struct rte_eth_rxmode rxmode; /**< Port RX configuration. */
-- 
2.1.4

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

* [PATCH v13 5/8] ethdev: add speed capabilities
  2016-03-26  1:27               ` [PATCH v13 0/8] ethdev: 100G and link speed API refactoring Marc Sune
                                   ` (3 preceding siblings ...)
  2016-03-26  1:27                 ` [PATCH v13 4/8] ethdev: rename link speed constants Marc Sune
@ 2016-03-26  1:27                 ` Marc Sune
  2016-03-29 13:31                   ` Alejandro Lucero
  2016-03-26  1:27                 ` [PATCH v13 6/8] ethdev: redesign link speed config Marc Sune
                                   ` (5 subsequent siblings)
  10 siblings, 1 reply; 167+ messages in thread
From: Marc Sune @ 2016-03-26  1:27 UTC (permalink / raw)
  To: Thomas Monjalon, Xu, Qian Q, Xing, Beilei, dev, Ananyev,
	Konstantin, Lu, Wenzhuo, Richardson, Bruce, Glynn, Michael J
  Cc: Marc Sune

The speed capabilities of a device can be retrieved with
rte_eth_dev_info_get().

The new field speed_capa is initialized in the drivers without
taking care of device characteristics in this patch.
When the capabilities of a driver are accurate, the table in
overview.rst must be filled.

Signed-off-by: Marc Sune <marcdevel@gmail.com>
---
 doc/guides/nics/overview.rst           |  1 +
 doc/guides/rel_notes/release_16_04.rst |  8 ++++++++
 drivers/net/bnx2x/bnx2x_ethdev.c       |  1 +
 drivers/net/cxgbe/cxgbe_ethdev.c       |  1 +
 drivers/net/e1000/em_ethdev.c          |  4 ++++
 drivers/net/e1000/igb_ethdev.c         |  4 ++++
 drivers/net/ena/ena_ethdev.c           |  9 +++++++++
 drivers/net/fm10k/fm10k_ethdev.c       |  4 ++++
 drivers/net/i40e/i40e_ethdev.c         |  8 ++++++++
 drivers/net/ixgbe/ixgbe_ethdev.c       |  8 ++++++++
 drivers/net/mlx4/mlx4.c                |  6 ++++++
 drivers/net/mlx5/mlx5_ethdev.c         |  8 ++++++++
 drivers/net/nfp/nfp_net.c              |  2 ++
 lib/librte_ether/rte_ethdev.h          | 21 +++++++++++++++++++++
 14 files changed, 85 insertions(+)

diff --git a/doc/guides/nics/overview.rst b/doc/guides/nics/overview.rst
index 542479a..62f1868 100644
--- a/doc/guides/nics/overview.rst
+++ b/doc/guides/nics/overview.rst
@@ -86,6 +86,7 @@ Most of these differences are summarized below.
                                           e   e       e   e   e                     e
                                           c   c       c   c   c                     c
    ==================== = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
+   speed capabilities
    link status                  X       X X                                   X X
    link status event                    X X                                     X
    queue status event                                                           X
diff --git a/doc/guides/rel_notes/release_16_04.rst b/doc/guides/rel_notes/release_16_04.rst
index 79d76e1..9e7b0b7 100644
--- a/doc/guides/rel_notes/release_16_04.rst
+++ b/doc/guides/rel_notes/release_16_04.rst
@@ -47,6 +47,11 @@ This section should contain new features added in this release. Sample format:
   A new function ``rte_pktmbuf_alloc_bulk()`` has been added to allow the user
   to allocate a bulk of mbufs.
 
+* **Added device link speed capabilities.**
+
+  The structure ``rte_eth_dev_info`` has now a ``speed_capa`` bitmap, which
+  allows the application to know the supported speeds of each device.
+
 * **Added new poll-mode driver for Amazon Elastic Network Adapters (ENA).**
 
   The driver operates variety of ENA adapters through feature negotiation
@@ -456,6 +461,9 @@ This section should contain API changes. Sample format:
   All drivers are now counting the missed packets only once, i.e. drivers will
   not increment ierrors anymore for missed packets.
 
+* The ethdev structure ``rte_eth_dev_info`` was changed to support device
+  speed capabilities.
+
 * The functions ``rte_eth_dev_udp_tunnel_add`` and ``rte_eth_dev_udp_tunnel_delete``
   have been renamed into ``rte_eth_dev_udp_tunnel_port_add`` and
   ``rte_eth_dev_udp_tunnel_port_delete``.
diff --git a/drivers/net/bnx2x/bnx2x_ethdev.c b/drivers/net/bnx2x/bnx2x_ethdev.c
index a3c6c01..897081f 100644
--- a/drivers/net/bnx2x/bnx2x_ethdev.c
+++ b/drivers/net/bnx2x/bnx2x_ethdev.c
@@ -327,6 +327,7 @@ bnx2x_dev_infos_get(struct rte_eth_dev *dev, __rte_unused struct rte_eth_dev_inf
 	dev_info->min_rx_bufsize = BNX2X_MIN_RX_BUF_SIZE;
 	dev_info->max_rx_pktlen  = BNX2X_MAX_RX_PKT_LEN;
 	dev_info->max_mac_addrs  = BNX2X_MAX_MAC_ADDRS;
+	dev_info->speed_capa = ETH_LINK_SPEED_10G | ETH_LINK_SPEED_20G;
 }
 
 static void
diff --git a/drivers/net/cxgbe/cxgbe_ethdev.c b/drivers/net/cxgbe/cxgbe_ethdev.c
index 8845c76..bb134e5 100644
--- a/drivers/net/cxgbe/cxgbe_ethdev.c
+++ b/drivers/net/cxgbe/cxgbe_ethdev.c
@@ -171,6 +171,7 @@ static void cxgbe_dev_info_get(struct rte_eth_dev *eth_dev,
 
 	device_info->rx_desc_lim = cxgbe_desc_lim;
 	device_info->tx_desc_lim = cxgbe_desc_lim;
+	device_info->speed_capa = ETH_LINK_SPEED_10G | ETH_LINK_SPEED_40G;
 }
 
 static void cxgbe_dev_promiscuous_enable(struct rte_eth_dev *eth_dev)
diff --git a/drivers/net/e1000/em_ethdev.c b/drivers/net/e1000/em_ethdev.c
index 473d77f..d5f8c7f 100644
--- a/drivers/net/e1000/em_ethdev.c
+++ b/drivers/net/e1000/em_ethdev.c
@@ -1054,6 +1054,10 @@ eth_em_infos_get(struct rte_eth_dev *dev, struct rte_eth_dev_info *dev_info)
 		.nb_min = E1000_MIN_RING_DESC,
 		.nb_align = EM_TXD_ALIGN,
 	};
+
+	dev_info->speed_capa = ETH_LINK_SPEED_10M_HD | ETH_LINK_SPEED_10M |
+			ETH_LINK_SPEED_100M_HD | ETH_LINK_SPEED_100M |
+			ETH_LINK_SPEED_1G;
 }
 
 /* return 0 means link status changed, -1 means not changed */
diff --git a/drivers/net/e1000/igb_ethdev.c b/drivers/net/e1000/igb_ethdev.c
index 86f25f6..95d1711 100644
--- a/drivers/net/e1000/igb_ethdev.c
+++ b/drivers/net/e1000/igb_ethdev.c
@@ -1921,6 +1921,10 @@ eth_igb_infos_get(struct rte_eth_dev *dev, struct rte_eth_dev_info *dev_info)
 
 	dev_info->rx_desc_lim = rx_desc_lim;
 	dev_info->tx_desc_lim = tx_desc_lim;
+
+	dev_info->speed_capa = ETH_LINK_SPEED_10M_HD | ETH_LINK_SPEED_10M |
+			ETH_LINK_SPEED_100M_HD | ETH_LINK_SPEED_100M |
+			ETH_LINK_SPEED_1G;
 }
 
 static const uint32_t *
diff --git a/drivers/net/ena/ena_ethdev.c b/drivers/net/ena/ena_ethdev.c
index 1046286..4e403af 100644
--- a/drivers/net/ena/ena_ethdev.c
+++ b/drivers/net/ena/ena_ethdev.c
@@ -1170,6 +1170,15 @@ static void ena_infos_get(struct rte_eth_dev *dev,
 	ena_dev = &adapter->ena_dev;
 	ena_assert_msg(ena_dev != NULL, "Uninitialized device");
 
+	dev_info->speed_capa =
+			ETH_LINK_SPEED_1G   |
+			ETH_LINK_SPEED_2_5G |
+			ETH_LINK_SPEED_5G   |
+			ETH_LINK_SPEED_10G  |
+			ETH_LINK_SPEED_25G  |
+			ETH_LINK_SPEED_40G  |
+			ETH_LINK_SPEED_50G;
+
 	/* Get supported features from HW */
 	rc = ena_com_get_dev_attr_feat(ena_dev, &feat);
 	if (unlikely(rc)) {
diff --git a/drivers/net/fm10k/fm10k_ethdev.c b/drivers/net/fm10k/fm10k_ethdev.c
index 53aa1bb..85ad0df 100644
--- a/drivers/net/fm10k/fm10k_ethdev.c
+++ b/drivers/net/fm10k/fm10k_ethdev.c
@@ -1410,6 +1410,10 @@ fm10k_dev_infos_get(struct rte_eth_dev *dev,
 		.nb_min = FM10K_MIN_TX_DESC,
 		.nb_align = FM10K_MULT_TX_DESC,
 	};
+
+	dev_info->speed_capa = ETH_LINK_SPEED_1G | ETH_LINK_SPEED_2_5G |
+			ETH_LINK_SPEED_10G | ETH_LINK_SPEED_25G |
+			ETH_LINK_SPEED_40G;
 }
 
 #ifdef RTE_LIBRTE_FM10K_RX_OLFLAGS_ENABLE
diff --git a/drivers/net/i40e/i40e_ethdev.c b/drivers/net/i40e/i40e_ethdev.c
index cce9e6f..dce31db 100644
--- a/drivers/net/i40e/i40e_ethdev.c
+++ b/drivers/net/i40e/i40e_ethdev.c
@@ -2287,6 +2287,7 @@ static void
 i40e_dev_info_get(struct rte_eth_dev *dev, struct rte_eth_dev_info *dev_info)
 {
 	struct i40e_pf *pf = I40E_DEV_PRIVATE_TO_PF(dev->data->dev_private);
+	struct i40e_hw *hw = I40E_DEV_PRIVATE_TO_HW(dev->data->dev_private);
 	struct i40e_vsi *vsi = pf->main_vsi;
 
 	dev_info->max_rx_queues = vsi->nb_qps;
@@ -2358,6 +2359,13 @@ i40e_dev_info_get(struct rte_eth_dev *dev, struct rte_eth_dev_info *dev_info)
 		dev_info->max_rx_queues += dev_info->vmdq_queue_num;
 		dev_info->max_tx_queues += dev_info->vmdq_queue_num;
 	}
+
+	if (i40e_is_40G_device(hw->device_id))
+		/* For XL710 */
+		dev_info->speed_capa = ETH_LINK_SPEED_1G | ETH_LINK_SPEED_10G;
+	else
+		/* For X710 */
+		dev_info->speed_capa = ETH_LINK_SPEED_10G | ETH_LINK_SPEED_40G;
 }
 
 static int
diff --git a/drivers/net/ixgbe/ixgbe_ethdev.c b/drivers/net/ixgbe/ixgbe_ethdev.c
index a0179d2..a98e8eb 100644
--- a/drivers/net/ixgbe/ixgbe_ethdev.c
+++ b/drivers/net/ixgbe/ixgbe_ethdev.c
@@ -2960,6 +2960,14 @@ ixgbe_dev_info_get(struct rte_eth_dev *dev, struct rte_eth_dev_info *dev_info)
 	dev_info->hash_key_size = IXGBE_HKEY_MAX_INDEX * sizeof(uint32_t);
 	dev_info->reta_size = ixgbe_reta_size_get(hw->mac.type);
 	dev_info->flow_type_rss_offloads = IXGBE_RSS_OFFLOAD_ALL;
+
+	dev_info->speed_capa = ETH_LINK_SPEED_1G | ETH_LINK_SPEED_10G;
+	if (hw->mac.type == ixgbe_mac_X540 ||
+	    hw->mac.type == ixgbe_mac_X540_vf ||
+	    hw->mac.type == ixgbe_mac_X550 ||
+	    hw->mac.type == ixgbe_mac_X550_vf) {
+		dev_info->speed_capa |= ETH_LINK_SPEED_100M;
+	}
 }
 
 static const uint32_t *
diff --git a/drivers/net/mlx4/mlx4.c b/drivers/net/mlx4/mlx4.c
index f946f08..59ac423 100644
--- a/drivers/net/mlx4/mlx4.c
+++ b/drivers/net/mlx4/mlx4.c
@@ -4313,6 +4313,12 @@ mlx4_dev_infos_get(struct rte_eth_dev *dev, struct rte_eth_dev_info *info)
 		 0);
 	if (priv_get_ifname(priv, &ifname) == 0)
 		info->if_index = if_nametoindex(ifname);
+	info->speed_capa =
+			ETH_LINK_SPEED_1G |
+			ETH_LINK_SPEED_10G |
+			ETH_LINK_SPEED_20G |
+			ETH_LINK_SPEED_40G |
+			ETH_LINK_SPEED_56G;
 	priv_unlock(priv);
 }
 
diff --git a/drivers/net/mlx5/mlx5_ethdev.c b/drivers/net/mlx5/mlx5_ethdev.c
index 58bfa16..d7a0eea 100644
--- a/drivers/net/mlx5/mlx5_ethdev.c
+++ b/drivers/net/mlx5/mlx5_ethdev.c
@@ -559,6 +559,14 @@ mlx5_dev_infos_get(struct rte_eth_dev *dev, struct rte_eth_dev_info *info)
 	 * size if it is not fixed.
 	 * The API should be updated to solve this problem. */
 	info->reta_size = priv->ind_table_max_size;
+	info->speed_capa =
+			ETH_LINK_SPEED_1G |
+			ETH_LINK_SPEED_10G |
+			ETH_LINK_SPEED_20G |
+			ETH_LINK_SPEED_25G |
+			ETH_LINK_SPEED_40G |
+			ETH_LINK_SPEED_50G |
+			ETH_LINK_SPEED_56G;
 	priv_unlock(priv);
 }
 
diff --git a/drivers/net/nfp/nfp_net.c b/drivers/net/nfp/nfp_net.c
index 18ea0f4..bdeb21f 100644
--- a/drivers/net/nfp/nfp_net.c
+++ b/drivers/net/nfp/nfp_net.c
@@ -1061,6 +1061,8 @@ nfp_net_infos_get(struct rte_eth_dev *dev, struct rte_eth_dev_info *dev_info)
 
 	dev_info->reta_size = NFP_NET_CFG_RSS_ITBL_SZ;
 	dev_info->hash_key_size = NFP_NET_CFG_RSS_KEY_SZ;
+
+	dev_info->speed_capa = ETH_LINK_SPEED_50G;
 }
 
 static const uint32_t *
diff --git a/lib/librte_ether/rte_ethdev.h b/lib/librte_ether/rte_ethdev.h
index bc7d607..49fdcb7 100644
--- a/lib/librte_ether/rte_ethdev.h
+++ b/lib/librte_ether/rte_ethdev.h
@@ -242,6 +242,23 @@ struct rte_eth_stats {
 };
 
 /**
+ * Device supported speeds bitmap flags
+ */
+#define ETH_LINK_SPEED_10M_HD   (1 <<  1)  /**<  10 Mbps half-duplex */
+#define ETH_LINK_SPEED_10M      (1 <<  2)  /**<  10 Mbps full-duplex */
+#define ETH_LINK_SPEED_100M_HD  (1 <<  3)  /**< 100 Mbps half-duplex */
+#define ETH_LINK_SPEED_100M     (1 <<  4)  /**< 100 Mbps full-duplex */
+#define ETH_LINK_SPEED_1G       (1 <<  5)  /**<   1 Gbps */
+#define ETH_LINK_SPEED_2_5G     (1 <<  6)  /**< 2.5 Gbps */
+#define ETH_LINK_SPEED_5G       (1 <<  7)  /**<   5 Gbps */
+#define ETH_LINK_SPEED_10G      (1 <<  8)  /**<  10 Gbps */
+#define ETH_LINK_SPEED_20G      (1 <<  9)  /**<  20 Gbps */
+#define ETH_LINK_SPEED_25G      (1 << 10)  /**<  25 Gbps */
+#define ETH_LINK_SPEED_40G      (1 << 11)  /**<  40 Gbps */
+#define ETH_LINK_SPEED_50G      (1 << 12)  /**<  50 Gbps */
+#define ETH_LINK_SPEED_56G      (1 << 13)  /**<  56 Gbps */
+
+/**
  * Ethernet numeric link speeds in Mbps
  */
 #define ETH_LINK_SPEED_AUTONEG     0 /**< Auto-negotiate link speed. */
@@ -850,6 +867,9 @@ struct rte_eth_conf {
 #define DEV_TX_OFFLOAD_OUTER_IPV4_CKSUM 0x00000080 /**< Used for tunneling packet. */
 #define DEV_TX_OFFLOAD_QINQ_INSERT 0x00000100
 
+/**
+ * Ethernet device information
+ */
 struct rte_eth_dev_info {
 	struct rte_pci_device *pci_dev; /**< Device PCI information. */
 	const char *driver_name; /**< Device Driver name. */
@@ -878,6 +898,7 @@ struct rte_eth_dev_info {
 	uint16_t vmdq_pool_base;  /**< First ID of VMDQ pools. */
 	struct rte_eth_desc_lim rx_desc_lim;  /**< RX descriptors limits */
 	struct rte_eth_desc_lim tx_desc_lim;  /**< TX descriptors limits */
+	uint32_t speed_capa;  /**< Supported speeds bitmap (ETH_LINK_SPEED_). */
 };
 
 /**
-- 
2.1.4

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

* [PATCH v13 6/8] ethdev: redesign link speed config
  2016-03-26  1:27               ` [PATCH v13 0/8] ethdev: 100G and link speed API refactoring Marc Sune
                                   ` (4 preceding siblings ...)
  2016-03-26  1:27                 ` [PATCH v13 5/8] ethdev: add speed capabilities Marc Sune
@ 2016-03-26  1:27                 ` Marc Sune
  2016-03-29  6:18                   ` Xing, Beilei
  2016-03-26  1:27                 ` [PATCH v13 7/8] ethdev: convert speed number to bitmap flag Marc Sune
                                   ` (4 subsequent siblings)
  10 siblings, 1 reply; 167+ messages in thread
From: Marc Sune @ 2016-03-26  1:27 UTC (permalink / raw)
  To: Thomas Monjalon, Xu, Qian Q, Xing, Beilei, dev, Ananyev,
	Konstantin, Lu, Wenzhuo, Richardson, Bruce, Glynn, Michael J
  Cc: Marc Sune

This patch redesigns the API to set the link speed/s configuration
of an ethernet port. Specifically:

- it allows to define a set of advertised speeds for
  auto-negociation.
- it allows to disable link auto-negociation (single fixed speed).
- default: auto-negociate all supported speeds.

A flag autoneg in struct rte_eth_link indicates if link speed was a
result of auto-negociation or was fixed by configuration.

Signed-off-by: Marc Sune <marcdevel@gmail.com>
Tested-by: Nelio Laranjeiro <nelio.laranjeiro@6wind.com>
Signed-off-by: Thomas Monjalon <thomas.monjalon@6wind.com>
---
 app/test-pmd/cmdline.c                    |  26 ++++----
 doc/guides/rel_notes/deprecation.rst      |   3 -
 doc/guides/rel_notes/release_16_04.rst    |   9 +++
 drivers/net/af_packet/rte_eth_af_packet.c |   1 +
 drivers/net/bnx2x/bnx2x_ethdev.c          |   4 +-
 drivers/net/bonding/rte_eth_bond_8023ad.c |   2 +-
 drivers/net/e1000/em_ethdev.c             | 103 +++++++++++++++---------------
 drivers/net/e1000/igb_ethdev.c            |  95 ++++++++++++++-------------
 drivers/net/i40e/i40e_ethdev.c            |  48 +++++++-------
 drivers/net/i40e/i40e_ethdev_vf.c         |   7 +-
 drivers/net/ixgbe/ixgbe_ethdev.c          |  51 ++++++---------
 drivers/net/mlx4/mlx4.c                   |   2 +
 drivers/net/mlx5/mlx5_ethdev.c            |   2 +
 drivers/net/mpipe/mpipe_tilegx.c          |   2 +
 drivers/net/null/rte_eth_null.c           |   1 +
 drivers/net/pcap/rte_eth_pcap.c           |   1 +
 drivers/net/ring/rte_eth_ring.c           |   1 +
 drivers/net/szedata2/rte_eth_szedata2.c   |   2 +
 drivers/net/vmxnet3/vmxnet3_ethdev.c      |   1 +
 drivers/net/xenvirt/rte_eth_xenvirt.c     |   1 +
 examples/ip_pipeline/config_parse.c       |   3 +-
 lib/librte_ether/rte_ethdev.h             |  29 +++++----
 22 files changed, 207 insertions(+), 187 deletions(-)

diff --git a/app/test-pmd/cmdline.c b/app/test-pmd/cmdline.c
index 815b53b..741cac3 100644
--- a/app/test-pmd/cmdline.c
+++ b/app/test-pmd/cmdline.c
@@ -989,7 +989,7 @@ struct cmd_config_speed_all {
 };
 
 static int
-parse_and_check_speed_duplex(char *speedstr, char *duplexstr, uint16_t *speed)
+parse_and_check_speed_duplex(char *speedstr, char *duplexstr, uint32_t *speed)
 {
 
 	int duplex;
@@ -1006,20 +1006,22 @@ parse_and_check_speed_duplex(char *speedstr, char *duplexstr, uint16_t *speed)
 	}
 
 	if (!strcmp(speedstr, "10")) {
-		*speed = ETH_SPEED_NUM_10M;
+		*speed = (duplex == ETH_LINK_HALF_DUPLEX) ?
+				ETH_LINK_SPEED_10M_HD : ETH_LINK_SPEED_10M;
 	} else if (!strcmp(speedstr, "100")) {
-		*speed = ETH_SPEED_NUM_100M;
+		*speed = (duplex == ETH_LINK_HALF_DUPLEX) ?
+				ETH_LINK_SPEED_100M_HD : ETH_LINK_SPEED_100M;
 	} else {
 		if (duplex != ETH_LINK_FULL_DUPLEX) {
 			printf("Invalid speed/duplex parameters\n");
 			return -1;
 		}
 		if (!strcmp(speedstr, "1000")) {
-			*speed = ETH_SPEED_NUM_1G;
+			*speed = ETH_LINK_SPEED_1G;
 		} else if (!strcmp(speedstr, "10000")) {
-			*speed = ETH_SPEED_NUM_10G;
+			*speed = ETH_LINK_SPEED_10G;
 		} else if (!strcmp(speedstr, "40000")) {
-			*speed = ETH_SPEED_NUM_40G;
+			*speed = ETH_LINK_SPEED_40G;
 		} else if (!strcmp(speedstr, "auto")) {
 			*speed = ETH_LINK_SPEED_AUTONEG;
 		} else {
@@ -1037,8 +1039,7 @@ cmd_config_speed_all_parsed(void *parsed_result,
 			__attribute__((unused)) void *data)
 {
 	struct cmd_config_speed_all *res = parsed_result;
-	uint16_t link_speed = ETH_LINK_SPEED_AUTONEG;
-	uint16_t link_duplex = 0;
+	uint32_t link_speed;
 	portid_t pid;
 
 	if (!all_ports_stopped()) {
@@ -1051,8 +1052,7 @@ cmd_config_speed_all_parsed(void *parsed_result,
 		return;
 
 	FOREACH_PORT(pid, ports) {
-		ports[pid].dev_conf.link_speed = link_speed;
-		ports[pid].dev_conf.link_duplex = link_duplex;
+		ports[pid].dev_conf.link_speeds = link_speed;
 	}
 
 	cmd_reconfig_device_queue(RTE_PORT_ALL, 1, 1);
@@ -1110,8 +1110,7 @@ cmd_config_speed_specific_parsed(void *parsed_result,
 				__attribute__((unused)) void *data)
 {
 	struct cmd_config_speed_specific *res = parsed_result;
-	uint16_t link_speed = ETH_LINK_SPEED_AUTONEG;
-	uint16_t link_duplex = 0;
+	uint32_t link_speed;
 
 	if (!all_ports_stopped()) {
 		printf("Please stop all ports first\n");
@@ -1125,8 +1124,7 @@ cmd_config_speed_specific_parsed(void *parsed_result,
 			&link_speed) < 0)
 		return;
 
-	ports[res->id].dev_conf.link_speed = link_speed;
-	ports[res->id].dev_conf.link_duplex = link_duplex;
+	ports[res->id].dev_conf.link_speeds = link_speed;
 
 	cmd_reconfig_device_queue(RTE_PORT_ALL, 1, 1);
 }
diff --git a/doc/guides/rel_notes/deprecation.rst b/doc/guides/rel_notes/deprecation.rst
index 179e30f..c47610d 100644
--- a/doc/guides/rel_notes/deprecation.rst
+++ b/doc/guides/rel_notes/deprecation.rst
@@ -19,9 +19,6 @@ Deprecation Notices
   ibadcrc, ibadlen, imcasts, fdirmatch, fdirmiss,
   tx_pause_xon, rx_pause_xon, tx_pause_xoff, rx_pause_xoff
 
-* The ethdev structures rte_eth_link, rte_eth_dev_info and rte_eth_conf
-  must be updated to support 100G link and to have a cleaner link speed API.
-
 * ABI changes are planned for adding four new flow types. This impacts
   RTE_ETH_FLOW_MAX. The release 2.2 does not contain these ABI changes,
   but release 2.3 will. [postponed]
diff --git a/doc/guides/rel_notes/release_16_04.rst b/doc/guides/rel_notes/release_16_04.rst
index 9e7b0b7..c891a55 100644
--- a/doc/guides/rel_notes/release_16_04.rst
+++ b/doc/guides/rel_notes/release_16_04.rst
@@ -52,6 +52,12 @@ This section should contain new features added in this release. Sample format:
   The structure ``rte_eth_dev_info`` has now a ``speed_capa`` bitmap, which
   allows the application to know the supported speeds of each device.
 
+* **Added bitmap of link speeds to advertise.**
+
+  Allow defining a set of advertised speeds for auto-negotiation,
+  explicitly disabling link auto-negotiation (single speed)
+  and full auto-negotiation.
+
 * **Added new poll-mode driver for Amazon Elastic Network Adapters (ENA).**
 
   The driver operates variety of ENA adapters through feature negotiation
@@ -464,6 +470,9 @@ This section should contain API changes. Sample format:
 * The ethdev structure ``rte_eth_dev_info`` was changed to support device
   speed capabilities.
 
+* The ethdev structures ``rte_eth_link`` and ``rte_eth_conf`` were changed to
+  support the new link API.
+
 * The functions ``rte_eth_dev_udp_tunnel_add`` and ``rte_eth_dev_udp_tunnel_delete``
   have been renamed into ``rte_eth_dev_udp_tunnel_port_add`` and
   ``rte_eth_dev_udp_tunnel_port_delete``.
diff --git a/drivers/net/af_packet/rte_eth_af_packet.c b/drivers/net/af_packet/rte_eth_af_packet.c
index 641f849..f17bd7e 100644
--- a/drivers/net/af_packet/rte_eth_af_packet.c
+++ b/drivers/net/af_packet/rte_eth_af_packet.c
@@ -119,6 +119,7 @@ static struct rte_eth_link pmd_link = {
 	.link_speed = ETH_SPEED_NUM_10G,
 	.link_duplex = ETH_LINK_FULL_DUPLEX,
 	.link_status = ETH_LINK_DOWN,
+	.link_autoneg = ETH_LINK_SPEED_AUTONEG
 };
 
 static uint16_t
diff --git a/drivers/net/bnx2x/bnx2x_ethdev.c b/drivers/net/bnx2x/bnx2x_ethdev.c
index 897081f..071b44f 100644
--- a/drivers/net/bnx2x/bnx2x_ethdev.c
+++ b/drivers/net/bnx2x/bnx2x_ethdev.c
@@ -44,9 +44,9 @@ bnx2x_link_update(struct rte_eth_dev *dev)
 		case DUPLEX_HALF:
 			dev->data->dev_link.link_duplex = ETH_LINK_HALF_DUPLEX;
 			break;
-		default:
-			dev->data->dev_link.link_duplex = ETH_LINK_AUTONEG_DUPLEX;
 	}
+	dev->data->dev_link.link_autoneg = !(dev->data->dev_conf.link_speeds &
+			ETH_LINK_SPEED_FIXED);
 	dev->data->dev_link.link_status = sc->link_vars.link_up;
 }
 
diff --git a/drivers/net/bonding/rte_eth_bond_8023ad.c b/drivers/net/bonding/rte_eth_bond_8023ad.c
index ac8306f..cca7cc3 100644
--- a/drivers/net/bonding/rte_eth_bond_8023ad.c
+++ b/drivers/net/bonding/rte_eth_bond_8023ad.c
@@ -708,7 +708,7 @@ link_speed_key(uint16_t speed) {
 	uint16_t key_speed;
 
 	switch (speed) {
-	case ETH_LINK_SPEED_AUTONEG:
+	case ETH_SPEED_NUM_NONE:
 		key_speed = 0x00;
 		break;
 	case ETH_SPEED_NUM_10M:
diff --git a/drivers/net/e1000/em_ethdev.c b/drivers/net/e1000/em_ethdev.c
index d5f8c7f..9fb59a2 100644
--- a/drivers/net/e1000/em_ethdev.c
+++ b/drivers/net/e1000/em_ethdev.c
@@ -538,6 +538,9 @@ eth_em_start(struct rte_eth_dev *dev)
 	struct rte_intr_handle *intr_handle = &dev->pci_dev->intr_handle;
 	int ret, mask;
 	uint32_t intr_vector = 0;
+	uint32_t *speeds;
+	int num_speeds;
+	bool autoneg;
 
 	PMD_INIT_FUNC_TRACE();
 
@@ -612,56 +615,46 @@ eth_em_start(struct rte_eth_dev *dev)
 	E1000_WRITE_REG(hw, E1000_ITR, UINT16_MAX);
 
 	/* Setup link speed and duplex */
-	switch (dev->data->dev_conf.link_speed) {
-	case ETH_LINK_SPEED_AUTONEG:
-		if (dev->data->dev_conf.link_duplex == ETH_LINK_AUTONEG_DUPLEX)
-			hw->phy.autoneg_advertised = E1000_ALL_SPEED_DUPLEX;
-		else if (dev->data->dev_conf.link_duplex ==
-					ETH_LINK_HALF_DUPLEX)
-			hw->phy.autoneg_advertised = E1000_ALL_HALF_DUPLEX;
-		else if (dev->data->dev_conf.link_duplex ==
-					ETH_LINK_FULL_DUPLEX)
-			hw->phy.autoneg_advertised = E1000_ALL_FULL_DUPLEX;
-		else
-			goto error_invalid_config;
-		break;
-	case ETH_SPEED_NUM_10M:
-		if (dev->data->dev_conf.link_duplex == ETH_LINK_AUTONEG_DUPLEX)
-			hw->phy.autoneg_advertised = E1000_ALL_10_SPEED;
-		else if (dev->data->dev_conf.link_duplex ==
-					ETH_LINK_HALF_DUPLEX)
-			hw->phy.autoneg_advertised = ADVERTISE_10_HALF;
-		else if (dev->data->dev_conf.link_duplex ==
-					ETH_LINK_FULL_DUPLEX)
-			hw->phy.autoneg_advertised = ADVERTISE_10_FULL;
-		else
-			goto error_invalid_config;
-		break;
-	case ETH_SPEED_NUM_100M:
-		if (dev->data->dev_conf.link_duplex == ETH_LINK_AUTONEG_DUPLEX)
-			hw->phy.autoneg_advertised = E1000_ALL_100_SPEED;
-		else if (dev->data->dev_conf.link_duplex ==
-					ETH_LINK_HALF_DUPLEX)
-			hw->phy.autoneg_advertised = ADVERTISE_100_HALF;
-		else if (dev->data->dev_conf.link_duplex ==
-					ETH_LINK_FULL_DUPLEX)
-			hw->phy.autoneg_advertised = ADVERTISE_100_FULL;
-		else
+	speeds = &dev->data->dev_conf.link_speeds;
+	if (*speeds == ETH_LINK_SPEED_AUTONEG) {
+		hw->phy.autoneg_advertised = E1000_ALL_SPEED_DUPLEX;
+	} else {
+		num_speeds = 0;
+		autoneg = (*speeds & ETH_LINK_SPEED_FIXED) == 0;
+
+		/* Reset */
+		hw->phy.autoneg_advertised = 0;
+
+		if (*speeds & ~(ETH_LINK_SPEED_10M_HD | ETH_LINK_SPEED_10M |
+				ETH_LINK_SPEED_100M_HD | ETH_LINK_SPEED_100M |
+				ETH_LINK_SPEED_1G | ETH_LINK_SPEED_FIXED)) {
+			num_speeds = -1;
 			goto error_invalid_config;
-		break;
-	case ETH_SPEED_NUM_1G:
-		if ((dev->data->dev_conf.link_duplex ==
-				ETH_LINK_AUTONEG_DUPLEX) ||
-			(dev->data->dev_conf.link_duplex ==
-					ETH_LINK_FULL_DUPLEX))
-			hw->phy.autoneg_advertised = ADVERTISE_1000_FULL;
-		else
+		}
+		if (*speeds & ETH_LINK_SPEED_10M_HD) {
+			hw->phy.autoneg_advertised |= ADVERTISE_10_HALF;
+			num_speeds++;
+		}
+		if (*speeds & ETH_LINK_SPEED_10M) {
+			hw->phy.autoneg_advertised |= ADVERTISE_10_FULL;
+			num_speeds++;
+		}
+		if (*speeds & ETH_LINK_SPEED_100M_HD) {
+			hw->phy.autoneg_advertised |= ADVERTISE_100_HALF;
+			num_speeds++;
+		}
+		if (*speeds & ETH_LINK_SPEED_100M) {
+			hw->phy.autoneg_advertised |= ADVERTISE_100_FULL;
+			num_speeds++;
+		}
+		if (*speeds & ETH_LINK_SPEED_1G) {
+			hw->phy.autoneg_advertised |= ADVERTISE_1000_FULL;
+			num_speeds++;
+		}
+		if (num_speeds == 0 || (!autoneg && (num_speeds > 1)))
 			goto error_invalid_config;
-		break;
-	case ETH_SPEED_NUM_10G:
-	default:
-		goto error_invalid_config;
 	}
+
 	e1000_setup_link(hw);
 
 	if (rte_intr_allow_others(intr_handle)) {
@@ -694,9 +687,8 @@ eth_em_start(struct rte_eth_dev *dev)
 	return 0;
 
 error_invalid_config:
-	PMD_INIT_LOG(ERR, "Invalid link_speed/link_duplex (%u/%u) for port %u",
-		     dev->data->dev_conf.link_speed,
-		     dev->data->dev_conf.link_duplex, dev->data->port_id);
+	PMD_INIT_LOG(ERR, "Invalid advertised speeds (%u) for port %u",
+		     dev->data->dev_conf.link_speeds, dev->data->port_id);
 	em_dev_clear_queues(dev);
 	return -EINVAL;
 }
@@ -1106,13 +1098,20 @@ eth_em_link_update(struct rte_eth_dev *dev, int wait_to_complete)
 
 	/* Now we check if a transition has happened */
 	if (link_check && (link.link_status == ETH_LINK_DOWN)) {
-		hw->mac.ops.get_link_up_info(hw, &link.link_speed,
-			&link.link_duplex);
+		uint16_t duplex, speed;
+		hw->mac.ops.get_link_up_info(hw, &speed, &duplex);
+		link.link_duplex = (duplex == FULL_DUPLEX) ?
+				ETH_LINK_FULL_DUPLEX :
+				ETH_LINK_HALF_DUPLEX;
+		link.link_speed = speed;
 		link.link_status = ETH_LINK_UP;
+		link.link_autoneg = !(dev->data->dev_conf.link_speeds &
+				ETH_LINK_SPEED_FIXED);
 	} else if (!link_check && (link.link_status == ETH_LINK_UP)) {
 		link.link_speed = 0;
 		link.link_duplex = ETH_LINK_HALF_DUPLEX;
 		link.link_status = ETH_LINK_DOWN;
+		link.link_autoneg = ETH_LINK_SPEED_FIXED;
 	}
 	rte_em_dev_atomic_write_link_status(dev, &link);
 
diff --git a/drivers/net/e1000/igb_ethdev.c b/drivers/net/e1000/igb_ethdev.c
index 95d1711..e0053fe 100644
--- a/drivers/net/e1000/igb_ethdev.c
+++ b/drivers/net/e1000/igb_ethdev.c
@@ -1133,6 +1133,9 @@ eth_igb_start(struct rte_eth_dev *dev)
 	int ret, mask;
 	uint32_t intr_vector = 0;
 	uint32_t ctrl_ext;
+	uint32_t *speeds;
+	int num_speeds;
+	bool autoneg;
 
 	PMD_INIT_FUNC_TRACE();
 
@@ -1233,48 +1236,46 @@ eth_igb_start(struct rte_eth_dev *dev)
 	}
 
 	/* Setup link speed and duplex */
-	switch (dev->data->dev_conf.link_speed) {
-	case ETH_LINK_SPEED_AUTONEG:
-		if (dev->data->dev_conf.link_duplex == ETH_LINK_AUTONEG_DUPLEX)
-			hw->phy.autoneg_advertised = E1000_ALL_SPEED_DUPLEX;
-		else if (dev->data->dev_conf.link_duplex == ETH_LINK_HALF_DUPLEX)
-			hw->phy.autoneg_advertised = E1000_ALL_HALF_DUPLEX;
-		else if (dev->data->dev_conf.link_duplex == ETH_LINK_FULL_DUPLEX)
-			hw->phy.autoneg_advertised = E1000_ALL_FULL_DUPLEX;
-		else
-			goto error_invalid_config;
-		break;
-	case ETH_SPEED_NUM_10M:
-		if (dev->data->dev_conf.link_duplex == ETH_LINK_AUTONEG_DUPLEX)
-			hw->phy.autoneg_advertised = E1000_ALL_10_SPEED;
-		else if (dev->data->dev_conf.link_duplex == ETH_LINK_HALF_DUPLEX)
-			hw->phy.autoneg_advertised = ADVERTISE_10_HALF;
-		else if (dev->data->dev_conf.link_duplex == ETH_LINK_FULL_DUPLEX)
-			hw->phy.autoneg_advertised = ADVERTISE_10_FULL;
-		else
-			goto error_invalid_config;
-		break;
-	case ETH_SPEED_NUM_100M:
-		if (dev->data->dev_conf.link_duplex == ETH_LINK_AUTONEG_DUPLEX)
-			hw->phy.autoneg_advertised = E1000_ALL_100_SPEED;
-		else if (dev->data->dev_conf.link_duplex == ETH_LINK_HALF_DUPLEX)
-			hw->phy.autoneg_advertised = ADVERTISE_100_HALF;
-		else if (dev->data->dev_conf.link_duplex == ETH_LINK_FULL_DUPLEX)
-			hw->phy.autoneg_advertised = ADVERTISE_100_FULL;
-		else
+	speeds = &dev->data->dev_conf.link_speeds;
+	if (*speeds == ETH_LINK_SPEED_AUTONEG) {
+		hw->phy.autoneg_advertised = E1000_ALL_SPEED_DUPLEX;
+	} else {
+		num_speeds = 0;
+		autoneg = (*speeds & ETH_LINK_SPEED_FIXED) == 0;
+
+		/* Reset */
+		hw->phy.autoneg_advertised = 0;
+
+		if (*speeds & ~(ETH_LINK_SPEED_10M_HD | ETH_LINK_SPEED_10M |
+				ETH_LINK_SPEED_100M_HD | ETH_LINK_SPEED_100M |
+				ETH_LINK_SPEED_1G | ETH_LINK_SPEED_FIXED)) {
+			num_speeds = -1;
 			goto error_invalid_config;
-		break;
-	case ETH_SPEED_NUM_1G:
-		if ((dev->data->dev_conf.link_duplex == ETH_LINK_AUTONEG_DUPLEX) ||
-				(dev->data->dev_conf.link_duplex == ETH_LINK_FULL_DUPLEX))
-			hw->phy.autoneg_advertised = ADVERTISE_1000_FULL;
-		else
+		}
+		if (*speeds & ETH_LINK_SPEED_10M_HD) {
+			hw->phy.autoneg_advertised |= ADVERTISE_10_HALF;
+			num_speeds++;
+		}
+		if (*speeds & ETH_LINK_SPEED_10M) {
+			hw->phy.autoneg_advertised |= ADVERTISE_10_FULL;
+			num_speeds++;
+		}
+		if (*speeds & ETH_LINK_SPEED_100M_HD) {
+			hw->phy.autoneg_advertised |= ADVERTISE_100_HALF;
+			num_speeds++;
+		}
+		if (*speeds & ETH_LINK_SPEED_100M) {
+			hw->phy.autoneg_advertised |= ADVERTISE_100_FULL;
+			num_speeds++;
+		}
+		if (*speeds & ETH_LINK_SPEED_1G) {
+			hw->phy.autoneg_advertised |= ADVERTISE_1000_FULL;
+			num_speeds++;
+		}
+		if (num_speeds == 0 || (!autoneg && (num_speeds > 1)))
 			goto error_invalid_config;
-		break;
-	case ETH_SPEED_NUM_10G:
-	default:
-		goto error_invalid_config;
 	}
+
 	e1000_setup_link(hw);
 
 	if (rte_intr_allow_others(intr_handle)) {
@@ -1306,9 +1307,8 @@ eth_igb_start(struct rte_eth_dev *dev)
 	return 0;
 
 error_invalid_config:
-	PMD_INIT_LOG(ERR, "Invalid link_speed/link_duplex (%u/%u) for port %u",
-		     dev->data->dev_conf.link_speed,
-		     dev->data->dev_conf.link_duplex, dev->data->port_id);
+	PMD_INIT_LOG(ERR, "Invalid advertised speeds (%u) for port %u",
+		     dev->data->dev_conf.link_speeds, dev->data->port_id);
 	igb_dev_clear_queues(dev);
 	return -EINVAL;
 }
@@ -2061,13 +2061,20 @@ eth_igb_link_update(struct rte_eth_dev *dev, int wait_to_complete)
 
 	/* Now we check if a transition has happened */
 	if (link_check) {
-		hw->mac.ops.get_link_up_info(hw, &link.link_speed,
-					  &link.link_duplex);
+		uint16_t duplex, speed;
+		hw->mac.ops.get_link_up_info(hw, &speed, &duplex);
+		link.link_duplex = (duplex == FULL_DUPLEX) ?
+				ETH_LINK_FULL_DUPLEX :
+				ETH_LINK_HALF_DUPLEX;
+		link.link_speed = speed;
 		link.link_status = ETH_LINK_UP;
+		link.link_autoneg = !(dev->data->dev_conf.link_speeds &
+				ETH_LINK_SPEED_FIXED);
 	} else if (!link_check) {
 		link.link_speed = 0;
 		link.link_duplex = ETH_LINK_HALF_DUPLEX;
 		link.link_status = ETH_LINK_DOWN;
+		link.link_autoneg = ETH_LINK_SPEED_FIXED;
 	}
 	rte_igb_dev_atomic_write_link_status(dev, &link);
 
diff --git a/drivers/net/i40e/i40e_ethdev.c b/drivers/net/i40e/i40e_ethdev.c
index dce31db..c9ef417 100644
--- a/drivers/net/i40e/i40e_ethdev.c
+++ b/drivers/net/i40e/i40e_ethdev.c
@@ -1381,27 +1381,20 @@ i40e_vsi_disable_queues_intr(struct i40e_vsi *vsi)
 }
 
 static inline uint8_t
-i40e_parse_link_speed(uint16_t eth_link_speed)
+i40e_parse_link_speeds(uint16_t link_speeds)
 {
 	uint8_t link_speed = I40E_LINK_SPEED_UNKNOWN;
 
-	switch (eth_link_speed) {
-	case ETH_SPEED_NUM_40G:
-		link_speed = I40E_LINK_SPEED_40GB;
-		break;
-	case ETH_SPEED_NUM_20G:
-		link_speed = I40E_LINK_SPEED_20GB;
-		break;
-	case ETH_SPEED_NUM_10G:
-		link_speed = I40E_LINK_SPEED_10GB;
-		break;
-	case ETH_SPEED_NUM_1G:
-		link_speed = I40E_LINK_SPEED_1GB;
-		break;
-	case ETH_SPEED_NUM_100M:
-		link_speed = I40E_LINK_SPEED_100MB;
-		break;
-	}
+	if (link_speeds & ETH_LINK_SPEED_40G)
+		link_speed |= I40E_LINK_SPEED_40GB;
+	if (link_speeds & ETH_LINK_SPEED_20G)
+		link_speed |= I40E_LINK_SPEED_20GB;
+	if (link_speeds & ETH_LINK_SPEED_10G)
+		link_speed |= I40E_LINK_SPEED_10GB;
+	if (link_speeds & ETH_LINK_SPEED_1G)
+		link_speed |= I40E_LINK_SPEED_1GB;
+	if (link_speeds & ETH_LINK_SPEED_100M)
+		link_speed |= I40E_LINK_SPEED_100MB;
 
 	return link_speed;
 }
@@ -1427,9 +1420,9 @@ i40e_apply_link_speed(struct rte_eth_dev *dev)
 	struct i40e_hw *hw = I40E_DEV_PRIVATE_TO_HW(dev->data->dev_private);
 	struct rte_eth_conf *conf = &dev->data->dev_conf;
 
-	speed = i40e_parse_link_speed(conf->link_speed);
+	speed = i40e_parse_link_speeds(conf->link_speeds);
 	abilities |= I40E_AQ_PHY_ENABLE_ATOMIC_LINK;
-	if (conf->link_speed == ETH_LINK_SPEED_AUTONEG)
+	if (!(conf->link_speeds & ETH_LINK_SPEED_FIXED))
 		abilities |= I40E_AQ_PHY_AN_ENABLED;
 	else
 		abilities |= I40E_AQ_PHY_LINK_ENABLED;
@@ -1449,10 +1442,8 @@ i40e_dev_start(struct rte_eth_dev *dev)
 
 	hw->adapter_stopped = 0;
 
-	if ((dev->data->dev_conf.link_duplex != ETH_LINK_AUTONEG_DUPLEX) &&
-		(dev->data->dev_conf.link_duplex != ETH_LINK_FULL_DUPLEX)) {
-		PMD_INIT_LOG(ERR, "Invalid link_duplex (%hu) for port %hhu",
-			     dev->data->dev_conf.link_duplex,
+	if (dev->data->dev_conf.link_speeds & ETH_LINK_SPEED_FIXED) {
+		PMD_INIT_LOG(ERR, "Invalid link_speeds for port %hhu; autonegotiation disabled",
 			     dev->data->port_id);
 		return -EINVAL;
 	}
@@ -1525,6 +1516,12 @@ i40e_dev_start(struct rte_eth_dev *dev)
 	}
 
 	/* Apply link configure */
+	if (dev->data->dev_conf.link_speeds & ~(ETH_LINK_SPEED_100M |
+				ETH_LINK_SPEED_1G | ETH_LINK_SPEED_10G |
+				ETH_LINK_SPEED_20G | ETH_LINK_SPEED_40G)) {
+		PMD_DRV_LOG(ERR, "Invalid link setting");
+		goto err_up;
+	}
 	ret = i40e_apply_link_speed(dev);
 	if (I40E_SUCCESS != ret) {
 		PMD_DRV_LOG(ERR, "Fail to apply link setting");
@@ -1809,6 +1806,9 @@ i40e_dev_link_update(struct rte_eth_dev *dev,
 		break;
 	}
 
+	link.link_autoneg = !(dev->data->dev_conf.link_speeds &
+			ETH_LINK_SPEED_FIXED);
+
 out:
 	rte_i40e_dev_atomic_write_link_status(dev, &link);
 	if (link.link_status == old.link_status)
diff --git a/drivers/net/i40e/i40e_ethdev_vf.c b/drivers/net/i40e/i40e_ethdev_vf.c
index 295dcd2..8cf22ee 100644
--- a/drivers/net/i40e/i40e_ethdev_vf.c
+++ b/drivers/net/i40e/i40e_ethdev_vf.c
@@ -2121,12 +2121,13 @@ i40evf_dev_link_update(struct rte_eth_dev *dev,
 	 * DPDK pf host provide interfacet to acquire link status
 	 * while Linux driver does not
 	 */
-	if (vf->version_major == I40E_DPDK_VERSION_MAJOR)
+	if (vf->version_major == I40E_DPDK_VERSION_MAJOR) {
 		i40evf_get_link_status(dev, &new_link);
-	else {
+	} else {
 		/* Always assume it's up, for Linux driver PF host */
-		new_link.link_duplex = ETH_LINK_AUTONEG_DUPLEX;
 		new_link.link_speed  = ETH_SPEED_NUM_10G;
+		new_link.link_duplex = ETH_LINK_FULL_DUPLEX;
+		new_link.link_autoneg = ETH_LINK_SPEED_AUTONEG;
 		new_link.link_status = ETH_LINK_UP;
 	}
 	i40evf_dev_atomic_write_link_status(dev, &new_link);
diff --git a/drivers/net/ixgbe/ixgbe_ethdev.c b/drivers/net/ixgbe/ixgbe_ethdev.c
index a98e8eb..6cc2da0 100644
--- a/drivers/net/ixgbe/ixgbe_ethdev.c
+++ b/drivers/net/ixgbe/ixgbe_ethdev.c
@@ -2094,14 +2094,16 @@ ixgbe_dev_start(struct rte_eth_dev *dev)
 	int mask = 0;
 	int status;
 	uint16_t vf, idx;
+	uint32_t *link_speeds;
 
 	PMD_INIT_FUNC_TRACE();
 
-	/* IXGBE devices don't support half duplex */
-	if ((dev->data->dev_conf.link_duplex != ETH_LINK_AUTONEG_DUPLEX) &&
-			(dev->data->dev_conf.link_duplex != ETH_LINK_FULL_DUPLEX)) {
-		PMD_INIT_LOG(ERR, "Invalid link_duplex (%hu) for port %hhu",
-			     dev->data->dev_conf.link_duplex,
+	/* IXGBE devices don't support:
+	*    - half duplex (checked afterwards for valid speeds)
+	*    - fixed speed: TODO implement
+	*/
+	if (dev->data->dev_conf.link_speeds & ETH_LINK_SPEED_FIXED) {
+		PMD_INIT_LOG(ERR, "Invalid link_speeds for port %hhu; fix speed not supported",
 			     dev->data->port_id);
 		return -EINVAL;
 	}
@@ -2193,32 +2195,21 @@ ixgbe_dev_start(struct rte_eth_dev *dev)
 	if (err)
 		goto error;
 
-	switch(dev->data->dev_conf.link_speed) {
-	case ETH_LINK_SPEED_AUTONEG:
-		speed = (hw->mac.type != ixgbe_mac_82598EB) ?
-				IXGBE_LINK_SPEED_82599_AUTONEG :
-				IXGBE_LINK_SPEED_82598_AUTONEG;
-		break;
-	case ETH_SPEED_NUM_100M:
-		/*
-		 * Invalid for 82598 but error will be detected by
-		 * ixgbe_setup_link()
-		 */
-		speed = IXGBE_LINK_SPEED_100_FULL;
-		break;
-	case ETH_SPEED_NUM_1G:
-		speed = IXGBE_LINK_SPEED_1GB_FULL;
-		break;
-	case ETH_SPEED_NUM_10G:
-		speed = IXGBE_LINK_SPEED_10GB_FULL;
-		break;
-	default:
-		PMD_INIT_LOG(ERR, "Invalid link_speed (%hu) for port %hhu",
-			     dev->data->dev_conf.link_speed,
-			     dev->data->port_id);
+	link_speeds = &dev->data->dev_conf.link_speeds;
+	if (*link_speeds & ~(ETH_LINK_SPEED_100M | ETH_LINK_SPEED_1G |
+			ETH_LINK_SPEED_10G)) {
+		PMD_INIT_LOG(ERR, "Invalid link setting");
 		goto error;
 	}
 
+	speed = 0x0;
+	if (*link_speeds & ETH_LINK_SPEED_10G)
+		speed |= IXGBE_LINK_SPEED_10GB_FULL;
+	if (*link_speeds & ETH_LINK_SPEED_1G)
+		speed |= IXGBE_LINK_SPEED_1GB_FULL;
+	if (*link_speeds & ETH_LINK_SPEED_100M)
+		speed |= IXGBE_LINK_SPEED_100_FULL;
+
 	err = ixgbe_setup_link(hw, speed, link_up);
 	if (err)
 		goto error;
@@ -3083,7 +3074,7 @@ ixgbe_dev_link_update(struct rte_eth_dev *dev, int wait_to_complete)
 
 	if (diag != 0) {
 		link.link_speed = ETH_SPEED_NUM_100M;
-		link.link_duplex = ETH_LINK_HALF_DUPLEX;
+		link.link_duplex = ETH_LINK_FULL_DUPLEX;
 		rte_ixgbe_dev_atomic_write_link_status(dev, &link);
 		if (link.link_status == old.link_status)
 			return -1;
@@ -3102,7 +3093,7 @@ ixgbe_dev_link_update(struct rte_eth_dev *dev, int wait_to_complete)
 	switch (link_speed) {
 	default:
 	case IXGBE_LINK_SPEED_UNKNOWN:
-		link.link_duplex = ETH_LINK_HALF_DUPLEX;
+		link.link_duplex = ETH_LINK_FULL_DUPLEX;
 		link.link_speed = ETH_SPEED_NUM_100M;
 		break;
 
diff --git a/drivers/net/mlx4/mlx4.c b/drivers/net/mlx4/mlx4.c
index 59ac423..81528c9 100644
--- a/drivers/net/mlx4/mlx4.c
+++ b/drivers/net/mlx4/mlx4.c
@@ -4721,6 +4721,8 @@ mlx4_link_update_unlocked(struct rte_eth_dev *dev, int wait_to_complete)
 		dev_link.link_speed = link_speed;
 	dev_link.link_duplex = ((edata.duplex == DUPLEX_HALF) ?
 				ETH_LINK_HALF_DUPLEX : ETH_LINK_FULL_DUPLEX);
+	dev_link.link_autoneg = !(dev->data->dev_conf.link_speeds &
+			ETH_LINK_SPEED_FIXED);
 	if (memcmp(&dev_link, &dev->data->dev_link, sizeof(dev_link))) {
 		/* Link status changed. */
 		dev->data->dev_link = dev_link;
diff --git a/drivers/net/mlx5/mlx5_ethdev.c b/drivers/net/mlx5/mlx5_ethdev.c
index d7a0eea..beecc63 100644
--- a/drivers/net/mlx5/mlx5_ethdev.c
+++ b/drivers/net/mlx5/mlx5_ethdev.c
@@ -629,6 +629,8 @@ mlx5_link_update_unlocked(struct rte_eth_dev *dev, int wait_to_complete)
 		dev_link.link_speed = link_speed;
 	dev_link.link_duplex = ((edata.duplex == DUPLEX_HALF) ?
 				ETH_LINK_HALF_DUPLEX : ETH_LINK_FULL_DUPLEX);
+	dev_link.link_autoneg = !(dev->data->dev_conf.link_speeds &
+			ETH_LINK_SPEED_FIXED);
 	if (memcmp(&dev_link, &dev->data->dev_link, sizeof(dev_link))) {
 		/* Link status changed. */
 		dev->data->dev_link = dev_link;
diff --git a/drivers/net/mpipe/mpipe_tilegx.c b/drivers/net/mpipe/mpipe_tilegx.c
index 1a77c7a..adcbc19 100644
--- a/drivers/net/mpipe/mpipe_tilegx.c
+++ b/drivers/net/mpipe/mpipe_tilegx.c
@@ -394,6 +394,8 @@ mpipe_link_update(struct rte_eth_dev *dev, int wait_to_complete)
 
 		speed = state & GXIO_MPIPE_LINK_SPEED_MASK;
 
+		new.link_autoneg = (dev->data->dev_conf.link_speeds &
+				ETH_LINK_SPEED_AUTONEG);
 		if (speed == GXIO_MPIPE_LINK_1G) {
 			new.link_speed = ETH_SPEED_NUM_1G;
 			new.link_duplex = ETH_LINK_FULL_DUPLEX;
diff --git a/drivers/net/null/rte_eth_null.c b/drivers/net/null/rte_eth_null.c
index 5640585..5e8e203 100644
--- a/drivers/net/null/rte_eth_null.c
+++ b/drivers/net/null/rte_eth_null.c
@@ -92,6 +92,7 @@ static struct rte_eth_link pmd_link = {
 	.link_speed = ETH_SPEED_NUM_10G,
 	.link_duplex = ETH_LINK_FULL_DUPLEX,
 	.link_status = ETH_LINK_DOWN,
+	.link_autoneg = ETH_LINK_SPEED_AUTONEG,
 };
 
 static uint16_t
diff --git a/drivers/net/pcap/rte_eth_pcap.c b/drivers/net/pcap/rte_eth_pcap.c
index c657951..c98e234 100644
--- a/drivers/net/pcap/rte_eth_pcap.c
+++ b/drivers/net/pcap/rte_eth_pcap.c
@@ -126,6 +126,7 @@ static struct rte_eth_link pmd_link = {
 		.link_speed = ETH_SPEED_NUM_10G,
 		.link_duplex = ETH_LINK_FULL_DUPLEX,
 		.link_status = ETH_LINK_DOWN,
+		.link_autoneg = ETH_LINK_SPEED_FIXED,
 };
 
 static int
diff --git a/drivers/net/ring/rte_eth_ring.c b/drivers/net/ring/rte_eth_ring.c
index 58685e9..b1783c3 100644
--- a/drivers/net/ring/rte_eth_ring.c
+++ b/drivers/net/ring/rte_eth_ring.c
@@ -80,6 +80,7 @@ static struct rte_eth_link pmd_link = {
 		.link_speed = ETH_SPEED_NUM_10G,
 		.link_duplex = ETH_LINK_FULL_DUPLEX,
 		.link_status = ETH_LINK_DOWN,
+		.link_autoneg = ETH_LINK_SPEED_AUTONEG
 };
 
 static uint16_t
diff --git a/drivers/net/szedata2/rte_eth_szedata2.c b/drivers/net/szedata2/rte_eth_szedata2.c
index dd1ae9e..ee97a4e 100644
--- a/drivers/net/szedata2/rte_eth_szedata2.c
+++ b/drivers/net/szedata2/rte_eth_szedata2.c
@@ -1174,6 +1174,8 @@ eth_link_update(struct rte_eth_dev *dev,
 	link.link_status = (cgmii_ibuf_is_enabled(ibuf) &&
 			cgmii_ibuf_is_link_up(ibuf)) ? ETH_LINK_UP : ETH_LINK_DOWN;
 
+	link.link_autoneg = ETH_LINK_SPEED_FIXED;
+
 	rte_atomic64_cmpset((uint64_t *)dev_link, *(uint64_t *)dev_link,
 			*(uint64_t *)link_ptr);
 
diff --git a/drivers/net/vmxnet3/vmxnet3_ethdev.c b/drivers/net/vmxnet3/vmxnet3_ethdev.c
index 6afa14e..94d1b2c 100644
--- a/drivers/net/vmxnet3/vmxnet3_ethdev.c
+++ b/drivers/net/vmxnet3/vmxnet3_ethdev.c
@@ -780,6 +780,7 @@ vmxnet3_dev_link_update(struct rte_eth_dev *dev, __attribute__((unused)) int wai
 		link.link_status = ETH_LINK_UP;
 		link.link_duplex = ETH_LINK_FULL_DUPLEX;
 		link.link_speed = ETH_SPEED_NUM_10G;
+		link.link_autoneg = ETH_LINK_SPEED_FIXED;
 	}
 
 	vmxnet3_dev_atomic_write_link_status(dev, &link);
diff --git a/drivers/net/xenvirt/rte_eth_xenvirt.c b/drivers/net/xenvirt/rte_eth_xenvirt.c
index 77d3ba1..b9638d9 100644
--- a/drivers/net/xenvirt/rte_eth_xenvirt.c
+++ b/drivers/net/xenvirt/rte_eth_xenvirt.c
@@ -73,6 +73,7 @@ static struct rte_eth_link pmd_link = {
 		.link_speed = ETH_SPEED_NUM_10G,
 		.link_duplex = ETH_LINK_FULL_DUPLEX,
 		.link_status = ETH_LINK_DOWN,
+		.link_autoneg = ETH_LINK_SPEED_FIXED
 };
 
 static void
diff --git a/examples/ip_pipeline/config_parse.c b/examples/ip_pipeline/config_parse.c
index 152889d..2cd5707 100644
--- a/examples/ip_pipeline/config_parse.c
+++ b/examples/ip_pipeline/config_parse.c
@@ -87,8 +87,7 @@ static const struct app_link_params link_params_default = {
 	.pci_bdf = {0},
 
 	.conf = {
-		.link_speed = 0,
-		.link_duplex = 0,
+		.link_speeds = 0,
 		.rxmode = {
 			.mq_mode = ETH_MQ_RX_NONE,
 
diff --git a/lib/librte_ether/rte_ethdev.h b/lib/librte_ether/rte_ethdev.h
index 49fdcb7..9a1466b 100644
--- a/lib/librte_ether/rte_ethdev.h
+++ b/lib/librte_ether/rte_ethdev.h
@@ -244,6 +244,8 @@ struct rte_eth_stats {
 /**
  * Device supported speeds bitmap flags
  */
+#define ETH_LINK_SPEED_AUTONEG  (0 <<  0)  /**< Autonegotiate (all speeds) */
+#define ETH_LINK_SPEED_FIXED    (1 <<  0)  /**< Disable autoneg (fixed speed) */
 #define ETH_LINK_SPEED_10M_HD   (1 <<  1)  /**<  10 Mbps half-duplex */
 #define ETH_LINK_SPEED_10M      (1 <<  2)  /**<  10 Mbps full-duplex */
 #define ETH_LINK_SPEED_100M_HD  (1 <<  3)  /**< 100 Mbps half-duplex */
@@ -261,7 +263,7 @@ struct rte_eth_stats {
 /**
  * Ethernet numeric link speeds in Mbps
  */
-#define ETH_LINK_SPEED_AUTONEG     0 /**< Auto-negotiate link speed. */
+#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 */
@@ -278,15 +280,15 @@ struct rte_eth_stats {
  * A structure used to retrieve link-level information of an Ethernet port.
  */
 struct rte_eth_link {
-	uint16_t link_speed;      /**< ETH_SPEED_NUM_ */
-	uint16_t link_duplex;     /**< ETH_LINK_[HALF/FULL]_DUPLEX */
-	uint8_t  link_status : 1; /**< ETH_LINK_[DOWN/UP] */
-}__attribute__((aligned(8)));     /**< aligned for atomic64 read/write */
+	uint16_t link_speed;        /**< ETH_SPEED_NUM_ */
+	uint16_t link_duplex  : 1;  /**< ETH_LINK_[HALF/FULL]_DUPLEX */
+	uint16_t link_autoneg : 1;  /**< ETH_LINK_SPEED_[AUTONEG/FIXED] */
+	uint16_t link_status  : 1;  /**< ETH_LINK_[DOWN/UP] */
+} __attribute__((aligned(8)));      /**< aligned for atomic64 read/write */
 
 /* Utility constants */
-#define ETH_LINK_AUTONEG_DUPLEX 0       /**< Auto-negotiate duplex. */
-#define ETH_LINK_HALF_DUPLEX    1       /**< Half-duplex connection. */
-#define ETH_LINK_FULL_DUPLEX    2       /**< Full-duplex connection. */
+#define ETH_LINK_HALF_DUPLEX    0 /**< Half-duplex connection. */
+#define ETH_LINK_FULL_DUPLEX    1 /**< Full-duplex connection. */
 #define ETH_LINK_DOWN           0 /**< Link is down. */
 #define ETH_LINK_UP             1 /**< Link is up. */
 
@@ -802,10 +804,13 @@ struct rte_intr_conf {
  * configuration settings may be needed.
  */
 struct rte_eth_conf {
-	uint16_t link_speed;
-	/**< ETH_SPEED_NUM_ or 0 for autonegotiation */
-	uint16_t link_duplex;
-	/**< ETH_LINK_[HALF_DUPLEX|FULL_DUPLEX], or 0 for autonegotation */
+	uint32_t link_speeds; /**< bitmap of ETH_LINK_SPEED_XXX of speeds to be
+				used. ETH_LINK_SPEED_FIXED disables link
+				autonegotiation, and a unique speed shall be
+				set. Otherwise, the bitmap defines the set of
+				speeds to be advertised. If the special value
+				ETH_LINK_SPEED_AUTONEG (0) is used, all speeds
+				supported are advertised. */
 	struct rte_eth_rxmode rxmode; /**< Port RX configuration. */
 	struct rte_eth_txmode txmode; /**< Port TX configuration. */
 	uint32_t lpbk_mode; /**< Loopback operation mode. By default the value
-- 
2.1.4

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

* [PATCH v13 7/8] ethdev: convert speed number to bitmap flag
  2016-03-26  1:27               ` [PATCH v13 0/8] ethdev: 100G and link speed API refactoring Marc Sune
                                   ` (5 preceding siblings ...)
  2016-03-26  1:27                 ` [PATCH v13 6/8] ethdev: redesign link speed config Marc Sune
@ 2016-03-26  1:27                 ` Marc Sune
  2016-03-26  1:27                 ` [PATCH v13 8/8] ethdev: add 100G link speed Marc Sune
                                   ` (3 subsequent siblings)
  10 siblings, 0 replies; 167+ messages in thread
From: Marc Sune @ 2016-03-26  1:27 UTC (permalink / raw)
  To: Thomas Monjalon, Xu, Qian Q, Xing, Beilei, dev, Ananyev,
	Konstantin, Lu, Wenzhuo, Richardson, Bruce, Glynn, Michael J
  Cc: Marc Sune

It is a helper for the bitmap configuration.

Signed-off-by: Marc Sune <marcdevel@gmail.com>
Signed-off-by: Thomas Monjalon <thomas.monjalon@6wind.com>
---
 lib/librte_ether/rte_ethdev.c          | 31 +++++++++++++++++++++++++++++++
 lib/librte_ether/rte_ethdev.h          | 13 +++++++++++++
 lib/librte_ether/rte_ether_version.map |  1 +
 3 files changed, 45 insertions(+)

diff --git a/lib/librte_ether/rte_ethdev.c b/lib/librte_ether/rte_ethdev.c
index 76a30fd..695b475 100644
--- a/lib/librte_ether/rte_ethdev.c
+++ b/lib/librte_ether/rte_ethdev.c
@@ -866,6 +866,37 @@ rte_eth_dev_tx_queue_config(struct rte_eth_dev *dev, uint16_t nb_queues)
 	return 0;
 }
 
+uint32_t
+rte_eth_speed_bitflag(uint32_t speed, int duplex)
+{
+	switch (speed) {
+	case ETH_SPEED_NUM_10M:
+		return duplex ? ETH_LINK_SPEED_10M : ETH_LINK_SPEED_10M_HD;
+	case ETH_SPEED_NUM_100M:
+		return duplex ? ETH_LINK_SPEED_100M : ETH_LINK_SPEED_100M_HD;
+	case ETH_SPEED_NUM_1G:
+		return ETH_LINK_SPEED_1G;
+	case ETH_SPEED_NUM_2_5G:
+		return ETH_LINK_SPEED_2_5G;
+	case ETH_SPEED_NUM_5G:
+		return ETH_LINK_SPEED_5G;
+	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;
+	default:
+		return 0;
+	}
+}
+
 int
 rte_eth_dev_configure(uint8_t port_id, uint16_t nb_rx_q, uint16_t nb_tx_q,
 		      const struct rte_eth_conf *dev_conf)
diff --git a/lib/librte_ether/rte_ethdev.h b/lib/librte_ether/rte_ethdev.h
index 9a1466b..0b436d9 100644
--- a/lib/librte_ether/rte_ethdev.h
+++ b/lib/librte_ether/rte_ethdev.h
@@ -1876,6 +1876,19 @@ struct eth_driver {
 void rte_eth_driver_register(struct eth_driver *eth_drv);
 
 /**
+ * Convert a numerical speed in Mbps to a bitmap flag that can be used in
+ * the bitmap link_speeds of the struct rte_eth_conf
+ *
+ * @param speed
+ *   Numerical speed value in Mbps
+ * @param duplex
+ *   ETH_LINK_[HALF/FULL]_DUPLEX (only for 10/100M speeds)
+ * @return
+ *   0 if the speed cannot be mapped
+ */
+uint32_t rte_eth_speed_bitflag(uint32_t speed, int duplex);
+
+/**
  * Configure an Ethernet device.
  * This function must be invoked first before any other function in the
  * Ethernet API. This function can also be re-invoked when a device is in the
diff --git a/lib/librte_ether/rte_ether_version.map b/lib/librte_ether/rte_ether_version.map
index b1f4475..214ecc7 100644
--- a/lib/librte_ether/rte_ether_version.map
+++ b/lib/librte_ether/rte_ether_version.map
@@ -125,6 +125,7 @@ DPDK_16.04 {
 	rte_eth_dev_set_vlan_ether_type;
 	rte_eth_dev_udp_tunnel_port_add;
 	rte_eth_dev_udp_tunnel_port_delete;
+	rte_eth_speed_bitflag;
 	rte_eth_tx_buffer_count_callback;
 	rte_eth_tx_buffer_drop_callback;
 	rte_eth_tx_buffer_init;
-- 
2.1.4

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

* [PATCH v13 8/8] ethdev: add 100G link speed
  2016-03-26  1:27               ` [PATCH v13 0/8] ethdev: 100G and link speed API refactoring Marc Sune
                                   ` (6 preceding siblings ...)
  2016-03-26  1:27                 ` [PATCH v13 7/8] ethdev: convert speed number to bitmap flag Marc Sune
@ 2016-03-26  1:27                 ` Marc Sune
  2016-03-26  8:11                 ` [PATCH v13 0/8] ethdev: 100G and link speed API refactoring Thomas Monjalon
                                   ` (2 subsequent siblings)
  10 siblings, 0 replies; 167+ messages in thread
From: Marc Sune @ 2016-03-26  1:27 UTC (permalink / raw)
  To: Thomas Monjalon, Xu, Qian Q, Xing, Beilei, dev, Ananyev,
	Konstantin, Lu, Wenzhuo, Richardson, Bruce, Glynn, Michael J
  Cc: Marc Sune

From: Thomas Monjalon <thomas.monjalon@6wind.com>

The link speed configuration is now done with bitmaps so 100G speed
requires only a new bit flag.
The actual link speed is a number so its size must be increased from
16-bit to 32-bit.

Signed-off-by: Marc Sune <marcdevel@gmail.com>
Signed-off-by: Thomas Monjalon <thomas.monjalon@6wind.com>
Tested-by: Nelio Laranjeiro <nelio.laranjeiro@6wind.com>
Tested-by: Matej Vido <vido@cesnet.cz>
---
 app/test-pmd/cmdline.c                      | 12 +++++++-----
 doc/guides/nics/szedata2.rst                |  6 ------
 doc/guides/rel_notes/release_16_04.rst      |  5 +++++
 doc/guides/testpmd_app_ug/testpmd_funcs.rst |  2 +-
 drivers/net/ena/ena_ethdev.c                |  3 ++-
 drivers/net/fm10k/fm10k_ethdev.c            |  2 +-
 drivers/net/mlx5/mlx5_ethdev.c              |  3 ++-
 drivers/net/nfp/nfp_net.c                   |  2 +-
 drivers/net/szedata2/rte_eth_szedata2.c     |  9 ++-------
 lib/librte_ether/rte_ethdev.c               |  2 ++
 lib/librte_ether/rte_ethdev.h               |  4 +++-
 11 files changed, 26 insertions(+), 24 deletions(-)

diff --git a/app/test-pmd/cmdline.c b/app/test-pmd/cmdline.c
index 741cac3..c5b9479 100644
--- a/app/test-pmd/cmdline.c
+++ b/app/test-pmd/cmdline.c
@@ -549,7 +549,7 @@ static void cmd_help_long_parsed(void *parsed_result,
 			"    Detach physical or virtual dev by port_id\n\n"
 
 			"port config (port_id|all)"
-			" speed (10|100|1000|10000|40000|auto)"
+			" speed (10|100|1000|10000|40000|100000|auto)"
 			" duplex (half|full|auto)\n"
 			"    Set speed and duplex for all ports or port_id\n\n"
 
@@ -1022,6 +1022,8 @@ parse_and_check_speed_duplex(char *speedstr, char *duplexstr, uint32_t *speed)
 			*speed = ETH_LINK_SPEED_10G;
 		} else if (!strcmp(speedstr, "40000")) {
 			*speed = ETH_LINK_SPEED_40G;
+		} else if (!strcmp(speedstr, "100000")) {
+			*speed = ETH_LINK_SPEED_100G;
 		} else if (!strcmp(speedstr, "auto")) {
 			*speed = ETH_LINK_SPEED_AUTONEG;
 		} else {
@@ -1069,7 +1071,7 @@ cmdline_parse_token_string_t cmd_config_speed_all_item1 =
 	TOKEN_STRING_INITIALIZER(struct cmd_config_speed_all, item1, "speed");
 cmdline_parse_token_string_t cmd_config_speed_all_value1 =
 	TOKEN_STRING_INITIALIZER(struct cmd_config_speed_all, value1,
-						"10#100#1000#10000#40000#auto");
+						"10#100#1000#10000#40000#100000#auto");
 cmdline_parse_token_string_t cmd_config_speed_all_item2 =
 	TOKEN_STRING_INITIALIZER(struct cmd_config_speed_all, item2, "duplex");
 cmdline_parse_token_string_t cmd_config_speed_all_value2 =
@@ -1079,7 +1081,7 @@ cmdline_parse_token_string_t cmd_config_speed_all_value2 =
 cmdline_parse_inst_t cmd_config_speed_all = {
 	.f = cmd_config_speed_all_parsed,
 	.data = NULL,
-	.help_str = "port config all speed 10|100|1000|10000|40000|auto duplex "
+	.help_str = "port config all speed 10|100|1000|10000|40000|100000|auto duplex "
 							"half|full|auto",
 	.tokens = {
 		(void *)&cmd_config_speed_all_port,
@@ -1143,7 +1145,7 @@ cmdline_parse_token_string_t cmd_config_speed_specific_item1 =
 								"speed");
 cmdline_parse_token_string_t cmd_config_speed_specific_value1 =
 	TOKEN_STRING_INITIALIZER(struct cmd_config_speed_specific, value1,
-						"10#100#1000#10000#40000#auto");
+						"10#100#1000#10000#40000#100000#auto");
 cmdline_parse_token_string_t cmd_config_speed_specific_item2 =
 	TOKEN_STRING_INITIALIZER(struct cmd_config_speed_specific, item2,
 								"duplex");
@@ -1154,7 +1156,7 @@ cmdline_parse_token_string_t cmd_config_speed_specific_value2 =
 cmdline_parse_inst_t cmd_config_speed_specific = {
 	.f = cmd_config_speed_specific_parsed,
 	.data = NULL,
-	.help_str = "port config X speed 10|100|1000|10000|40000|auto duplex "
+	.help_str = "port config X speed 10|100|1000|10000|40000|100000|auto duplex "
 							"half|full|auto",
 	.tokens = {
 		(void *)&cmd_config_speed_specific_port,
diff --git a/doc/guides/nics/szedata2.rst b/doc/guides/nics/szedata2.rst
index 77c15b3..741b400 100644
--- a/doc/guides/nics/szedata2.rst
+++ b/doc/guides/nics/szedata2.rst
@@ -148,9 +148,3 @@ Example output:
      TX threshold registers: pthresh=0 hthresh=0 wthresh=0
      TX RS bit threshold=0 - TXQ flags=0x0
    testpmd>
-
-.. note::
-
-   Link speed API currently supports speeds up to 40 Gbps.
-   Therefore there is used 10G constant for 100 Gbps cards until the link speed
-   API is not changed.
diff --git a/doc/guides/rel_notes/release_16_04.rst b/doc/guides/rel_notes/release_16_04.rst
index c891a55..a0fc02d 100644
--- a/doc/guides/rel_notes/release_16_04.rst
+++ b/doc/guides/rel_notes/release_16_04.rst
@@ -320,6 +320,11 @@ EAL
 Drivers
 ~~~~~~~
 
+* **ethdev: Fixed overflow for 100Gbps.**
+
+  100Gbps in Mbps (100000) was exceeding 16-bit max value of ``link_speed``
+  in ``rte_eth_link``.
+
 * **ethdev: Fixed byte order consistency between fdir flow and mask.**
 
   Fixed issue in ethdev library that the structure for setting
diff --git a/doc/guides/testpmd_app_ug/testpmd_funcs.rst b/doc/guides/testpmd_app_ug/testpmd_funcs.rst
index 94fba6a..aed5e47 100644
--- a/doc/guides/testpmd_app_ug/testpmd_funcs.rst
+++ b/doc/guides/testpmd_app_ug/testpmd_funcs.rst
@@ -1155,7 +1155,7 @@ port config - speed
 
 Set the speed and duplex mode for all ports or a specific port::
 
-   testpmd> port config (port_id|all) speed (10|100|1000|10000|auto) \
+   testpmd> port config (port_id|all) speed (10|100|1000|10000|40000|100000|auto) \
             duplex (half|full|auto)
 
 port config - queues/descriptors
diff --git a/drivers/net/ena/ena_ethdev.c b/drivers/net/ena/ena_ethdev.c
index 4e403af..02af67a 100644
--- a/drivers/net/ena/ena_ethdev.c
+++ b/drivers/net/ena/ena_ethdev.c
@@ -1177,7 +1177,8 @@ static void ena_infos_get(struct rte_eth_dev *dev,
 			ETH_LINK_SPEED_10G  |
 			ETH_LINK_SPEED_25G  |
 			ETH_LINK_SPEED_40G  |
-			ETH_LINK_SPEED_50G;
+			ETH_LINK_SPEED_50G  |
+			ETH_LINK_SPEED_100G;
 
 	/* Get supported features from HW */
 	rc = ena_com_get_dev_attr_feat(ena_dev, &feat);
diff --git a/drivers/net/fm10k/fm10k_ethdev.c b/drivers/net/fm10k/fm10k_ethdev.c
index 85ad0df..953d9c1 100644
--- a/drivers/net/fm10k/fm10k_ethdev.c
+++ b/drivers/net/fm10k/fm10k_ethdev.c
@@ -1413,7 +1413,7 @@ fm10k_dev_infos_get(struct rte_eth_dev *dev,
 
 	dev_info->speed_capa = ETH_LINK_SPEED_1G | ETH_LINK_SPEED_2_5G |
 			ETH_LINK_SPEED_10G | ETH_LINK_SPEED_25G |
-			ETH_LINK_SPEED_40G;
+			ETH_LINK_SPEED_40G | ETH_LINK_SPEED_100G;
 }
 
 #ifdef RTE_LIBRTE_FM10K_RX_OLFLAGS_ENABLE
diff --git a/drivers/net/mlx5/mlx5_ethdev.c b/drivers/net/mlx5/mlx5_ethdev.c
index beecc63..36b369e 100644
--- a/drivers/net/mlx5/mlx5_ethdev.c
+++ b/drivers/net/mlx5/mlx5_ethdev.c
@@ -566,7 +566,8 @@ mlx5_dev_infos_get(struct rte_eth_dev *dev, struct rte_eth_dev_info *info)
 			ETH_LINK_SPEED_25G |
 			ETH_LINK_SPEED_40G |
 			ETH_LINK_SPEED_50G |
-			ETH_LINK_SPEED_56G;
+			ETH_LINK_SPEED_56G |
+			ETH_LINK_SPEED_100G;
 	priv_unlock(priv);
 }
 
diff --git a/drivers/net/nfp/nfp_net.c b/drivers/net/nfp/nfp_net.c
index bdeb21f..4e909e0 100644
--- a/drivers/net/nfp/nfp_net.c
+++ b/drivers/net/nfp/nfp_net.c
@@ -1062,7 +1062,7 @@ nfp_net_infos_get(struct rte_eth_dev *dev, struct rte_eth_dev_info *dev_info)
 	dev_info->reta_size = NFP_NET_CFG_RSS_ITBL_SZ;
 	dev_info->hash_key_size = NFP_NET_CFG_RSS_KEY_SZ;
 
-	dev_info->speed_capa = ETH_LINK_SPEED_50G;
+	dev_info->speed_capa = ETH_LINK_SPEED_50G | ETH_LINK_SPEED_100G;
 }
 
 static const uint32_t *
diff --git a/drivers/net/szedata2/rte_eth_szedata2.c b/drivers/net/szedata2/rte_eth_szedata2.c
index ee97a4e..78c43b0 100644
--- a/drivers/net/szedata2/rte_eth_szedata2.c
+++ b/drivers/net/szedata2/rte_eth_szedata2.c
@@ -1036,6 +1036,7 @@ eth_dev_info(struct rte_eth_dev *dev,
 	dev_info->max_rx_queues = internals->max_rx_queues;
 	dev_info->max_tx_queues = internals->max_tx_queues;
 	dev_info->min_rx_bufsize = 0;
+	dev_info->speed_capa = ETH_LINK_SPEED_100G;
 }
 
 static void
@@ -1155,13 +1156,7 @@ eth_link_update(struct rte_eth_dev *dev,
 		link.link_speed = ETH_SPEED_NUM_40G;
 		break;
 	case SZEDATA2_LINK_SPEED_100G:
-		/*
-		 * TODO
-		 * If link_speed value from rte_eth_link structure
-		 * will be changed to support 100Gbps speed change
-		 * this value to 100G.
-		 */
-		link.link_speed = ETH_SPEED_NUM_10G;
+		link.link_speed = ETH_SPEED_NUM_100G;
 		break;
 	default:
 		link.link_speed = ETH_SPEED_NUM_10G;
diff --git a/lib/librte_ether/rte_ethdev.c b/lib/librte_ether/rte_ethdev.c
index 695b475..fd49b26 100644
--- a/lib/librte_ether/rte_ethdev.c
+++ b/lib/librte_ether/rte_ethdev.c
@@ -892,6 +892,8 @@ rte_eth_speed_bitflag(uint32_t speed, int duplex)
 		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;
 	}
diff --git a/lib/librte_ether/rte_ethdev.h b/lib/librte_ether/rte_ethdev.h
index 0b436d9..fb247a7 100644
--- a/lib/librte_ether/rte_ethdev.h
+++ b/lib/librte_ether/rte_ethdev.h
@@ -259,6 +259,7 @@ struct rte_eth_stats {
 #define ETH_LINK_SPEED_40G      (1 << 11)  /**<  40 Gbps */
 #define ETH_LINK_SPEED_50G      (1 << 12)  /**<  50 Gbps */
 #define ETH_LINK_SPEED_56G      (1 << 13)  /**<  56 Gbps */
+#define ETH_LINK_SPEED_100G     (1 << 14)  /**< 100 Gbps */
 
 /**
  * Ethernet numeric link speeds in Mbps
@@ -275,12 +276,13 @@ struct rte_eth_stats {
 #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 */
 
 /**
  * A structure used to retrieve link-level information of an Ethernet port.
  */
 struct rte_eth_link {
-	uint16_t link_speed;        /**< ETH_SPEED_NUM_ */
+	uint32_t link_speed;        /**< ETH_SPEED_NUM_ */
 	uint16_t link_duplex  : 1;  /**< ETH_LINK_[HALF/FULL]_DUPLEX */
 	uint16_t link_autoneg : 1;  /**< ETH_LINK_SPEED_[AUTONEG/FIXED] */
 	uint16_t link_status  : 1;  /**< ETH_LINK_[DOWN/UP] */
-- 
2.1.4

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

* Re: [PATCH v11 0/8] ethdev: 100G and link speed API refactoring
  2016-03-25 21:30                               ` Marc
  2016-03-26  1:25                                 ` Marc
@ 2016-03-26  8:08                                 ` Thomas Monjalon
  2016-03-26 10:24                                   ` Marc
  1 sibling, 1 reply; 167+ messages in thread
From: Thomas Monjalon @ 2016-03-26  8:08 UTC (permalink / raw)
  To: Marc
  Cc: Zhang, Helin, Xu, Qian Q, Xing, Beilei, dev, Ananyev, Konstantin,
	Lu, Wenzhuo, Richardson, Bruce, Glynn, Michael J

Hi Marc,

Thanks for finding time to help.

2016-03-25 22:30, Marc:
> From v9 to v10 patchset the values ETH_LINK_SPEED_AUTONEG and ETH_LINK_SPEED_FIXED were flipped. Reverting this makes it work:
> 
> marc@Beluga:~/personal/dpdk/tools$ git diff
> diff --git a/lib/librte_ether/rte_ethdev.h b/lib/librte_ether/rte_ethdev.h
> index ef2502a..fb247a7 100644
> --- a/lib/librte_ether/rte_ethdev.h
> +++ b/lib/librte_ether/rte_ethdev.h
> @@ -244,8 +244,8 @@ struct rte_eth_stats {
>  /**
>   * Device supported speeds bitmap flags
>   */
> -#define ETH_LINK_SPEED_FIXED    (0 <<  0)  /**< Disable autoneg (fixed speed) */
> -#define ETH_LINK_SPEED_AUTONEG  (1 <<  0)  /**< Autonegotiate (all speeds) */
> +#define ETH_LINK_SPEED_AUTONEG  (0 <<  0)  /**< Autonegotiate (all speeds) */
> +#define ETH_LINK_SPEED_FIXED    (1 <<  0)  /**< Disable autoneg (fixed speed) */
>  #define ETH_LINK_SPEED_10M_HD   (1 <<  1)  /**<  10 Mbps half-duplex */
>  #define ETH_LINK_SPEED_10M      (1 <<  2)  /**<  10 Mbps full-duplex */
>  #define ETH_LINK_SPEED_100M_HD  (1 <<  3)  /**< 100 Mbps half-duplex */
> 
> I think having autoneg == 0 is better. Do you agree Thomas?

No I do not agree, because this flag is now used also for
rte_eth_link.link_autoneg.
So it is more logic to set it to 1.

Would it be possible to fix without reverting?

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

* Re: [PATCH v13 0/8] ethdev: 100G and link speed API refactoring
  2016-03-26  1:27               ` [PATCH v13 0/8] ethdev: 100G and link speed API refactoring Marc Sune
                                   ` (7 preceding siblings ...)
  2016-03-26  1:27                 ` [PATCH v13 8/8] ethdev: add 100G link speed Marc Sune
@ 2016-03-26  8:11                 ` Thomas Monjalon
  2016-03-31 16:17                   ` Adrien Mazarguil
  2016-03-30  9:23                 ` Thomas Monjalon
  2016-03-31 22:12                 ` [PATCH v14 " Marc Sune
  10 siblings, 1 reply; 167+ messages in thread
From: Thomas Monjalon @ 2016-03-26  8:11 UTC (permalink / raw)
  To: Marc Sune
  Cc: Xu, Qian Q, Xing, Beilei, dev, Ananyev, Konstantin, Lu, Wenzhuo,
	Richardson, Bruce, Glynn, Michael J

> v13:
>     - Fix startup regression; revert flip of ETH_LINK_SPEED_FIXED and
>       ETH_LINK_SPEED_AUTONEG values. ETH_LINK_SPEED_AUTONEG is now 0.

As commented earlier, I would prefer avoiding this revert.
Comments are welcome.

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

* Re: [PATCH v11 0/8] ethdev: 100G and link speed API refactoring
  2016-03-26  8:08                                 ` Thomas Monjalon
@ 2016-03-26 10:24                                   ` Marc
  2016-03-27  9:53                                     ` Thomas Monjalon
  0 siblings, 1 reply; 167+ messages in thread
From: Marc @ 2016-03-26 10:24 UTC (permalink / raw)
  To: Thomas Monjalon
  Cc: Zhang, Helin, Xu, Qian Q, Xing, Beilei, dev, Ananyev, Konstantin,
	Lu, Wenzhuo, Richardson, Bruce, Glynn, Michael J

On 26 March 2016 at 09:08, Thomas Monjalon <thomas.monjalon@6wind.com>
wrote:

> Hi Marc,
>
> Thanks for finding time to help.
>
> 2016-03-25 22:30, Marc:
> > From v9 to v10 patchset the values ETH_LINK_SPEED_AUTONEG and
> ETH_LINK_SPEED_FIXED were flipped. Reverting this makes it work:
> >
> > marc@Beluga:~/personal/dpdk/tools$ git diff
> > diff --git a/lib/librte_ether/rte_ethdev.h
> b/lib/librte_ether/rte_ethdev.h
> > index ef2502a..fb247a7 100644
> > --- a/lib/librte_ether/rte_ethdev.h
> > +++ b/lib/librte_ether/rte_ethdev.h
> > @@ -244,8 +244,8 @@ struct rte_eth_stats {
> >  /**
> >   * Device supported speeds bitmap flags
> >   */
> > -#define ETH_LINK_SPEED_FIXED    (0 <<  0)  /**< Disable autoneg (fixed
> speed) */
> > -#define ETH_LINK_SPEED_AUTONEG  (1 <<  0)  /**< Autonegotiate (all
> speeds) */
> > +#define ETH_LINK_SPEED_AUTONEG  (0 <<  0)  /**< Autonegotiate (all
> speeds) */
> > +#define ETH_LINK_SPEED_FIXED    (1 <<  0)  /**< Disable autoneg (fixed
> speed) */
> >  #define ETH_LINK_SPEED_10M_HD   (1 <<  1)  /**<  10 Mbps half-duplex */
> >  #define ETH_LINK_SPEED_10M      (1 <<  2)  /**<  10 Mbps full-duplex */
> >  #define ETH_LINK_SPEED_100M_HD  (1 <<  3)  /**< 100 Mbps half-duplex */
> >
> > I think having autoneg == 0 is better. Do you agree Thomas?
>
> No I do not agree, because this flag is now used also for
> rte_eth_link.link_autoneg.
> So it is more logic to set it to 1.
>

Having to explicitly specify ETH_LINK_SPEED_AUTONEG in link_speeds during
port configuration for achieving auto-negociation, which is what 98% of
applications will use, seems anti-natural to me and breaks existing
applications.

The only benefit of your approach is not to have another macro #define
ETH_LINK_AUTONEG 1, which is marginal IMHO.


>
> Would it be possible to fix without reverting?
>

At least, all existing applications will have to be modified. I would have
to go through v12 again to see if there are other issues still to be fixed,
and also apply the 2 fixes I found for e1000.

Marc

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

* Re: [PATCH v11 0/8] ethdev: 100G and link speed API refactoring
  2016-03-26 10:24                                   ` Marc
@ 2016-03-27  9:53                                     ` Thomas Monjalon
  2016-03-27 19:39                                       ` Marc
  0 siblings, 1 reply; 167+ messages in thread
From: Thomas Monjalon @ 2016-03-27  9:53 UTC (permalink / raw)
  To: Marc
  Cc: Zhang, Helin, Xu, Qian Q, Xing, Beilei, dev, Ananyev, Konstantin,
	Lu, Wenzhuo, Richardson, Bruce, Glynn, Michael J

2016-03-26 11:24, Marc:
> On 26 March 2016 at 09:08, Thomas Monjalon <thomas.monjalon@6wind.com>
> wrote:
> > 2016-03-25 22:30, Marc:
> > > From v9 to v10 patchset the values ETH_LINK_SPEED_AUTONEG and
> > ETH_LINK_SPEED_FIXED were flipped. Reverting this makes it work:
> > >
> > > marc@Beluga:~/personal/dpdk/tools$ git diff
> > > diff --git a/lib/librte_ether/rte_ethdev.h
> > b/lib/librte_ether/rte_ethdev.h
> > > index ef2502a..fb247a7 100644
> > > --- a/lib/librte_ether/rte_ethdev.h
> > > +++ b/lib/librte_ether/rte_ethdev.h
> > > @@ -244,8 +244,8 @@ struct rte_eth_stats {
> > >  /**
> > >   * Device supported speeds bitmap flags
> > >   */
> > > -#define ETH_LINK_SPEED_FIXED    (0 <<  0)  /**< Disable autoneg (fixed
> > speed) */
> > > -#define ETH_LINK_SPEED_AUTONEG  (1 <<  0)  /**< Autonegotiate (all
> > speeds) */
> > > +#define ETH_LINK_SPEED_AUTONEG  (0 <<  0)  /**< Autonegotiate (all
> > speeds) */
> > > +#define ETH_LINK_SPEED_FIXED    (1 <<  0)  /**< Disable autoneg (fixed
> > speed) */
> > >  #define ETH_LINK_SPEED_10M_HD   (1 <<  1)  /**<  10 Mbps half-duplex */
> > >  #define ETH_LINK_SPEED_10M      (1 <<  2)  /**<  10 Mbps full-duplex */
> > >  #define ETH_LINK_SPEED_100M_HD  (1 <<  3)  /**< 100 Mbps half-duplex */
> > >
> > > I think having autoneg == 0 is better. Do you agree Thomas?
> >
> > No I do not agree, because this flag is now used also for
> > rte_eth_link.link_autoneg.
> > So it is more logic to set it to 1.
> 
> Having to explicitly specify ETH_LINK_SPEED_AUTONEG in link_speeds during
> port configuration for achieving auto-negociation, which is what 98% of
> applications will use, seems anti-natural to me and breaks existing
> applications.

Yes, you're right. We have to avoid apps modifications.
By keeping autoneg the default behaviour (value 0), we avoid issues.

> The only benefit of your approach is not to have another macro #define
> ETH_LINK_AUTONEG 1, which is marginal IMHO.

Yes, you're right.
I suggest adding 2 macros for rte_eth_link.link_autoneg:
#define ETH_LINK_FIXED      0 /**< No autonegotiation. */
#define ETH_LINK_AUTONEG    1 /**< Autonegotiated. */

and keep these ones to use with rte_eth_conf.link_speeds and
rte_eth_dev_info.speed_capa:
#define ETH_LINK_SPEED_AUTONEG  (0 <<  0)  /**< Autonegotiate (all speeds) */
#define ETH_LINK_SPEED_FIXED    (1 <<  0)  /**< Disable autoneg (fixed speed) */

Opinions?

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

* Re: [PATCH v11 0/8] ethdev: 100G and link speed API refactoring
  2016-03-27  9:53                                     ` Thomas Monjalon
@ 2016-03-27 19:39                                       ` Marc
  2016-03-28 13:42                                         ` Thomas Monjalon
  0 siblings, 1 reply; 167+ messages in thread
From: Marc @ 2016-03-27 19:39 UTC (permalink / raw)
  To: Thomas Monjalon
  Cc: Zhang, Helin, Xu, Qian Q, Xing, Beilei, dev, Ananyev, Konstantin,
	Lu, Wenzhuo, Richardson, Bruce, Glynn, Michael J

On 27 March 2016 at 11:53, Thomas Monjalon <thomas.monjalon@6wind.com>
wrote:

> 2016-03-26 11:24, Marc:
> > On 26 March 2016 at 09:08, Thomas Monjalon <thomas.monjalon@6wind.com>
> > wrote:
> > > 2016-03-25 22:30, Marc:
> > > > From v9 to v10 patchset the values ETH_LINK_SPEED_AUTONEG and
> > > ETH_LINK_SPEED_FIXED were flipped. Reverting this makes it work:
> > > >
> > > > marc@Beluga:~/personal/dpdk/tools$ git diff
> > > > diff --git a/lib/librte_ether/rte_ethdev.h
> > > b/lib/librte_ether/rte_ethdev.h
> > > > index ef2502a..fb247a7 100644
> > > > --- a/lib/librte_ether/rte_ethdev.h
> > > > +++ b/lib/librte_ether/rte_ethdev.h
> > > > @@ -244,8 +244,8 @@ struct rte_eth_stats {
> > > >  /**
> > > >   * Device supported speeds bitmap flags
> > > >   */
> > > > -#define ETH_LINK_SPEED_FIXED    (0 <<  0)  /**< Disable autoneg
> (fixed
> > > speed) */
> > > > -#define ETH_LINK_SPEED_AUTONEG  (1 <<  0)  /**< Autonegotiate (all
> > > speeds) */
> > > > +#define ETH_LINK_SPEED_AUTONEG  (0 <<  0)  /**< Autonegotiate (all
> > > speeds) */
> > > > +#define ETH_LINK_SPEED_FIXED    (1 <<  0)  /**< Disable autoneg
> (fixed
> > > speed) */
> > > >  #define ETH_LINK_SPEED_10M_HD   (1 <<  1)  /**<  10 Mbps
> half-duplex */
> > > >  #define ETH_LINK_SPEED_10M      (1 <<  2)  /**<  10 Mbps
> full-duplex */
> > > >  #define ETH_LINK_SPEED_100M_HD  (1 <<  3)  /**< 100 Mbps
> half-duplex */
> > > >
> > > > I think having autoneg == 0 is better. Do you agree Thomas?
> > >
> > > No I do not agree, because this flag is now used also for
> > > rte_eth_link.link_autoneg.
> > > So it is more logic to set it to 1.
> >
> > Having to explicitly specify ETH_LINK_SPEED_AUTONEG in link_speeds during
> > port configuration for achieving auto-negociation, which is what 98% of
> > applications will use, seems anti-natural to me and breaks existing
> > applications.
>
> Yes, you're right. We have to avoid apps modifications.
> By keeping autoneg the default behaviour (value 0), we avoid issues.
>
> > The only benefit of your approach is not to have another macro #define
> > ETH_LINK_AUTONEG 1, which is marginal IMHO.
>
> Yes, you're right.
> I suggest adding 2 macros for rte_eth_link.link_autoneg:
> #define ETH_LINK_FIXED      0 /**< No autonegotiation. */
> #define ETH_LINK_AUTONEG    1 /**< Autonegotiated. */
>
> and keep these ones to use with rte_eth_conf.link_speeds and
> rte_eth_dev_info.speed_capa:
> #define ETH_LINK_SPEED_AUTONEG  (0 <<  0)  /**< Autonegotiate (all speeds)
> */
> #define ETH_LINK_SPEED_FIXED    (1 <<  0)  /**< Disable autoneg (fixed
> speed) */
>
> Opinions?
>


Agree on all of them. I can add them in the (hopefully) final v14, once all
or main drivers have been tested.

Regards
marc

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

* Re: [PATCH v11 0/8] ethdev: 100G and link speed API refactoring
  2016-03-27 19:39                                       ` Marc
@ 2016-03-28 13:42                                         ` Thomas Monjalon
  2016-03-28 19:11                                           ` Marc
  0 siblings, 1 reply; 167+ messages in thread
From: Thomas Monjalon @ 2016-03-28 13:42 UTC (permalink / raw)
  To: Marc
  Cc: Zhang, Helin, Xu, Qian Q, Xing, Beilei, dev, Ananyev, Konstantin,
	Lu, Wenzhuo, Richardson, Bruce, Glynn, Michael J

Hi Marc,

2016-03-27 21:39, Marc:
> On 27 March 2016 at 11:53, Thomas Monjalon <thomas.monjalon@6wind.com>
> wrote:
> > 2016-03-26 11:24, Marc:
> > > On 26 March 2016 at 09:08, Thomas Monjalon <thomas.monjalon@6wind.com>
> > > wrote:
> > > > 2016-03-25 22:30, Marc:
> > > > > From v9 to v10 patchset the values ETH_LINK_SPEED_AUTONEG and
> > > > ETH_LINK_SPEED_FIXED were flipped. Reverting this makes it work:
[...]
> > > > > I think having autoneg == 0 is better. Do you agree Thomas?
> > > >
> > > > No I do not agree, because this flag is now used also for
> > > > rte_eth_link.link_autoneg.
> > > > So it is more logic to set it to 1.
> > >
> > > Having to explicitly specify ETH_LINK_SPEED_AUTONEG in link_speeds during
> > > port configuration for achieving auto-negociation, which is what 98% of
> > > applications will use, seems anti-natural to me and breaks existing
> > > applications.
> >
> > Yes, you're right. We have to avoid apps modifications.
> > By keeping autoneg the default behaviour (value 0), we avoid issues.
> >
> > > The only benefit of your approach is not to have another macro #define
> > > ETH_LINK_AUTONEG 1, which is marginal IMHO.
> >
> > Yes, you're right.
> > I suggest adding 2 macros for rte_eth_link.link_autoneg:
> > #define ETH_LINK_FIXED      0 /**< No autonegotiation. */
> > #define ETH_LINK_AUTONEG    1 /**< Autonegotiated. */
> >
> > and keep these ones to use with rte_eth_conf.link_speeds and
> > rte_eth_dev_info.speed_capa:
> > #define ETH_LINK_SPEED_AUTONEG  (0 <<  0)  /**< Autonegotiate (all speeds) */
> > #define ETH_LINK_SPEED_FIXED    (1 <<  0)  /**< Disable autoneg (fixed speed) */
> >
> > Opinions?
> 
> Agree on all of them. I can add them in the (hopefully) final v14, once all
> or main drivers have been tested.

It would be better to make the v14 as soon as possible to let others test
the latest revision.
Thanks

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

* Re: [PATCH v11 0/8] ethdev: 100G and link speed API refactoring
  2016-03-28 13:42                                         ` Thomas Monjalon
@ 2016-03-28 19:11                                           ` Marc
  0 siblings, 0 replies; 167+ messages in thread
From: Marc @ 2016-03-28 19:11 UTC (permalink / raw)
  To: Thomas Monjalon
  Cc: Zhang, Helin, Xu, Qian Q, Xing, Beilei, dev, Ananyev, Konstantin,
	Lu, Wenzhuo, Richardson, Bruce, Glynn, Michael J

On 28 March 2016 at 15:42, Thomas Monjalon <thomas.monjalon@6wind.com>
wrote:

> Hi Marc,
>
> 2016-03-27 21:39, Marc:
> > On 27 March 2016 at 11:53, Thomas Monjalon <thomas.monjalon@6wind.com>
> > wrote:
> > > 2016-03-26 11:24, Marc:
> > > > On 26 March 2016 at 09:08, Thomas Monjalon <
> thomas.monjalon@6wind.com>
> > > > wrote:
> > > > > 2016-03-25 22:30, Marc:
> > > > > > From v9 to v10 patchset the values ETH_LINK_SPEED_AUTONEG and
> > > > > ETH_LINK_SPEED_FIXED were flipped. Reverting this makes it work:
> [...]
> > > > > > I think having autoneg == 0 is better. Do you agree Thomas?
> > > > >
> > > > > No I do not agree, because this flag is now used also for
> > > > > rte_eth_link.link_autoneg.
> > > > > So it is more logic to set it to 1.
> > > >
> > > > Having to explicitly specify ETH_LINK_SPEED_AUTONEG in link_speeds
> during
> > > > port configuration for achieving auto-negociation, which is what 98%
> of
> > > > applications will use, seems anti-natural to me and breaks existing
> > > > applications.
> > >
> > > Yes, you're right. We have to avoid apps modifications.
> > > By keeping autoneg the default behaviour (value 0), we avoid issues.
> > >
> > > > The only benefit of your approach is not to have another macro
> #define
> > > > ETH_LINK_AUTONEG 1, which is marginal IMHO.
> > >
> > > Yes, you're right.
> > > I suggest adding 2 macros for rte_eth_link.link_autoneg:
> > > #define ETH_LINK_FIXED      0 /**< No autonegotiation. */
> > > #define ETH_LINK_AUTONEG    1 /**< Autonegotiated. */
> > >
> > > and keep these ones to use with rte_eth_conf.link_speeds and
> > > rte_eth_dev_info.speed_capa:
> > > #define ETH_LINK_SPEED_AUTONEG  (0 <<  0)  /**< Autonegotiate (all
> speeds) */
> > > #define ETH_LINK_SPEED_FIXED    (1 <<  0)  /**< Disable autoneg (fixed
> speed) */
> > >
> > > Opinions?
> >
> > Agree on all of them. I can add them in the (hopefully) final v14, once
> all
> > or main drivers have been tested.
>
> It would be better to make the v14 as soon as possible to let others test
> the latest revision.
> Thanks
>

Adding these MACROs (ETH_LINK_FIXED, ETH_LINK_AUTONEG) are the only changes
to be done for v14 so far. The rest were there already (v13).

There is no point on doing this re-spin now, because these MACROs are
anyway not used by applications yet (autoneg flag in rte_link is an
addition to this patch set).

So I would go for testing drivers on this v13 and collect any changes,
eventually, for v14.

marc

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

* Re: [PATCH v13 6/8] ethdev: redesign link speed config
  2016-03-26  1:27                 ` [PATCH v13 6/8] ethdev: redesign link speed config Marc Sune
@ 2016-03-29  6:18                   ` Xing, Beilei
  2016-03-30  7:59                     ` Marc
  0 siblings, 1 reply; 167+ messages in thread
From: Xing, Beilei @ 2016-03-29  6:18 UTC (permalink / raw)
  To: Marc Sune, Thomas Monjalon, Xu, Qian Q, dev, Ananyev, Konstantin,
	Lu, Wenzhuo, Richardson, Bruce, Glynn, Michael J



> -----Original Message-----
> From: Marc Sune [mailto:marcdevel@gmail.com]
> Sent: Saturday, March 26, 2016 9:27 AM
> To: Thomas Monjalon <thomas.monjalon@6wind.com>; Xu, Qian Q
> <qian.q.xu@intel.com>; Xing, Beilei <beilei.xing@intel.com>; dev@dpdk.org;
> Ananyev, Konstantin <konstantin.ananyev@intel.com>; Lu, Wenzhuo
> <wenzhuo.lu@intel.com>; Richardson, Bruce <bruce.richardson@intel.com>;
> Glynn, Michael J <michael.j.glynn@intel.com>
> Cc: Marc Sune <marcdevel@gmail.com>
> Subject: [PATCH v13 6/8] ethdev: redesign link speed config
> 

> a/drivers/net/ixgbe/ixgbe_ethdev.c b/drivers/net/ixgbe/ixgbe_ethdev.c
> index a98e8eb..6cc2da0 100644
> --- a/drivers/net/ixgbe/ixgbe_ethdev.c
> +++ b/drivers/net/ixgbe/ixgbe_ethdev.c
> @@ -2193,32 +2195,21 @@ ixgbe_dev_start(struct rte_eth_dev *dev)
>  	if (err)
>  		goto error;
> 
> +	speed = 0x0;
> +	if (*link_speeds & ETH_LINK_SPEED_10G)
> +		speed |= IXGBE_LINK_SPEED_10GB_FULL;
> +	if (*link_speeds & ETH_LINK_SPEED_1G)
> +		speed |= IXGBE_LINK_SPEED_1GB_FULL;
> +	if (*link_speeds & ETH_LINK_SPEED_100M)
> +		speed |= IXGBE_LINK_SPEED_100_FULL;
> +
>  	err = ixgbe_setup_link(hw, speed, link_up);
>  	if (err)
>  		goto error;

Hi Marc,
According to ixgbe HW, link speed shouldn't be 0 when setting up, 
Otherwise device will start fail. So we need to set speed if link_speed 
is ETH_LINK_SPEED_AUTONEG. Following code is for reference.

        speed = 0x0;
        if ((*link_speeds & 0x1) == ETH_LINK_SPEED_AUTONEG)
                speed = (hw->mac.type != ixgbe_mac_82598EB) ?
                        IXGBE_LINK_SPEED_82599_AUTONEG :
                        IXGBE_LINK_SPEED_82598_AUTONEG;
        else {
                if (*link_speeds & ETH_LINK_SPEED_10G)
                        speed |= IXGBE_LINK_SPEED_10GB_FULL;
                if (*link_speeds & ETH_LINK_SPEED_1G)
                        speed |= IXGBE_LINK_SPEED_1GB_FULL;
                if (*link_speeds & ETH_LINK_SPEED_100M)
                        speed |= IXGBE_LINK_SPEED_100_FULL;
        }

Beilei Xing
Thanks

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

* Re: [PATCH v13 5/8] ethdev: add speed capabilities
  2016-03-26  1:27                 ` [PATCH v13 5/8] ethdev: add speed capabilities Marc Sune
@ 2016-03-29 13:31                   ` Alejandro Lucero
  2016-03-30  8:06                     ` Marc
  0 siblings, 1 reply; 167+ messages in thread
From: Alejandro Lucero @ 2016-03-29 13:31 UTC (permalink / raw)
  To: Marc Sune
  Cc: Thomas Monjalon, Xu, Qian Q, Xing, Beilei, dev, Ananyev,
	Konstantin, Lu, Wenzhuo, Richardson, Bruce, Glynn, Michael J

For nfp.c, speed_capa should be ETH_LINK_SPEED_40G instead of
ETH_LINK_SPEED_50G.
By the way, the change in patch 4 sets the right link speed using the new
constants.

Regards

On Sat, Mar 26, 2016 at 1:27 AM, Marc Sune <marcdevel@gmail.com> wrote:

> The speed capabilities of a device can be retrieved with
> rte_eth_dev_info_get().
>
> The new field speed_capa is initialized in the drivers without
> taking care of device characteristics in this patch.
> When the capabilities of a driver are accurate, the table in
> overview.rst must be filled.
>
> Signed-off-by: Marc Sune <marcdevel@gmail.com>
> ---
>  doc/guides/nics/overview.rst           |  1 +
>  doc/guides/rel_notes/release_16_04.rst |  8 ++++++++
>  drivers/net/bnx2x/bnx2x_ethdev.c       |  1 +
>  drivers/net/cxgbe/cxgbe_ethdev.c       |  1 +
>  drivers/net/e1000/em_ethdev.c          |  4 ++++
>  drivers/net/e1000/igb_ethdev.c         |  4 ++++
>  drivers/net/ena/ena_ethdev.c           |  9 +++++++++
>  drivers/net/fm10k/fm10k_ethdev.c       |  4 ++++
>  drivers/net/i40e/i40e_ethdev.c         |  8 ++++++++
>  drivers/net/ixgbe/ixgbe_ethdev.c       |  8 ++++++++
>  drivers/net/mlx4/mlx4.c                |  6 ++++++
>  drivers/net/mlx5/mlx5_ethdev.c         |  8 ++++++++
>  drivers/net/nfp/nfp_net.c              |  2 ++
>  lib/librte_ether/rte_ethdev.h          | 21 +++++++++++++++++++++
>  14 files changed, 85 insertions(+)
>
> diff --git a/doc/guides/nics/overview.rst b/doc/guides/nics/overview.rst
> index 542479a..62f1868 100644
> --- a/doc/guides/nics/overview.rst
> +++ b/doc/guides/nics/overview.rst
> @@ -86,6 +86,7 @@ Most of these differences are summarized below.
>                                            e   e       e   e   e
>            e
>                                            c   c       c   c   c
>            c
>     ==================== = = = = = = = = = = = = = = = = = = = = = = = = =
> = = = = = = = =
> +   speed capabilities
>     link status                  X       X X
>      X X
>     link status event                    X X
>        X
>     queue status event
>        X
> diff --git a/doc/guides/rel_notes/release_16_04.rst
> b/doc/guides/rel_notes/release_16_04.rst
> index 79d76e1..9e7b0b7 100644
> --- a/doc/guides/rel_notes/release_16_04.rst
> +++ b/doc/guides/rel_notes/release_16_04.rst
> @@ -47,6 +47,11 @@ This section should contain new features added in this
> release. Sample format:
>    A new function ``rte_pktmbuf_alloc_bulk()`` has been added to allow the
> user
>    to allocate a bulk of mbufs.
>
> +* **Added device link speed capabilities.**
> +
> +  The structure ``rte_eth_dev_info`` has now a ``speed_capa`` bitmap,
> which
> +  allows the application to know the supported speeds of each device.
> +
>  * **Added new poll-mode driver for Amazon Elastic Network Adapters
> (ENA).**
>
>    The driver operates variety of ENA adapters through feature negotiation
> @@ -456,6 +461,9 @@ This section should contain API changes. Sample format:
>    All drivers are now counting the missed packets only once, i.e. drivers
> will
>    not increment ierrors anymore for missed packets.
>
> +* The ethdev structure ``rte_eth_dev_info`` was changed to support device
> +  speed capabilities.
> +
>  * The functions ``rte_eth_dev_udp_tunnel_add`` and
> ``rte_eth_dev_udp_tunnel_delete``
>    have been renamed into ``rte_eth_dev_udp_tunnel_port_add`` and
>    ``rte_eth_dev_udp_tunnel_port_delete``.
> diff --git a/drivers/net/bnx2x/bnx2x_ethdev.c
> b/drivers/net/bnx2x/bnx2x_ethdev.c
> index a3c6c01..897081f 100644
> --- a/drivers/net/bnx2x/bnx2x_ethdev.c
> +++ b/drivers/net/bnx2x/bnx2x_ethdev.c
> @@ -327,6 +327,7 @@ bnx2x_dev_infos_get(struct rte_eth_dev *dev,
> __rte_unused struct rte_eth_dev_inf
>         dev_info->min_rx_bufsize = BNX2X_MIN_RX_BUF_SIZE;
>         dev_info->max_rx_pktlen  = BNX2X_MAX_RX_PKT_LEN;
>         dev_info->max_mac_addrs  = BNX2X_MAX_MAC_ADDRS;
> +       dev_info->speed_capa = ETH_LINK_SPEED_10G | ETH_LINK_SPEED_20G;
>  }
>
>  static void
> diff --git a/drivers/net/cxgbe/cxgbe_ethdev.c
> b/drivers/net/cxgbe/cxgbe_ethdev.c
> index 8845c76..bb134e5 100644
> --- a/drivers/net/cxgbe/cxgbe_ethdev.c
> +++ b/drivers/net/cxgbe/cxgbe_ethdev.c
> @@ -171,6 +171,7 @@ static void cxgbe_dev_info_get(struct rte_eth_dev
> *eth_dev,
>
>         device_info->rx_desc_lim = cxgbe_desc_lim;
>         device_info->tx_desc_lim = cxgbe_desc_lim;
> +       device_info->speed_capa = ETH_LINK_SPEED_10G | ETH_LINK_SPEED_40G;
>  }
>
>  static void cxgbe_dev_promiscuous_enable(struct rte_eth_dev *eth_dev)
> diff --git a/drivers/net/e1000/em_ethdev.c b/drivers/net/e1000/em_ethdev.c
> index 473d77f..d5f8c7f 100644
> --- a/drivers/net/e1000/em_ethdev.c
> +++ b/drivers/net/e1000/em_ethdev.c
> @@ -1054,6 +1054,10 @@ eth_em_infos_get(struct rte_eth_dev *dev, struct
> rte_eth_dev_info *dev_info)
>                 .nb_min = E1000_MIN_RING_DESC,
>                 .nb_align = EM_TXD_ALIGN,
>         };
> +
> +       dev_info->speed_capa = ETH_LINK_SPEED_10M_HD | ETH_LINK_SPEED_10M |
> +                       ETH_LINK_SPEED_100M_HD | ETH_LINK_SPEED_100M |
> +                       ETH_LINK_SPEED_1G;
>  }
>
>  /* return 0 means link status changed, -1 means not changed */
> diff --git a/drivers/net/e1000/igb_ethdev.c
> b/drivers/net/e1000/igb_ethdev.c
> index 86f25f6..95d1711 100644
> --- a/drivers/net/e1000/igb_ethdev.c
> +++ b/drivers/net/e1000/igb_ethdev.c
> @@ -1921,6 +1921,10 @@ eth_igb_infos_get(struct rte_eth_dev *dev, struct
> rte_eth_dev_info *dev_info)
>
>         dev_info->rx_desc_lim = rx_desc_lim;
>         dev_info->tx_desc_lim = tx_desc_lim;
> +
> +       dev_info->speed_capa = ETH_LINK_SPEED_10M_HD | ETH_LINK_SPEED_10M |
> +                       ETH_LINK_SPEED_100M_HD | ETH_LINK_SPEED_100M |
> +                       ETH_LINK_SPEED_1G;
>  }
>
>  static const uint32_t *
> diff --git a/drivers/net/ena/ena_ethdev.c b/drivers/net/ena/ena_ethdev.c
> index 1046286..4e403af 100644
> --- a/drivers/net/ena/ena_ethdev.c
> +++ b/drivers/net/ena/ena_ethdev.c
> @@ -1170,6 +1170,15 @@ static void ena_infos_get(struct rte_eth_dev *dev,
>         ena_dev = &adapter->ena_dev;
>         ena_assert_msg(ena_dev != NULL, "Uninitialized device");
>
> +       dev_info->speed_capa =
> +                       ETH_LINK_SPEED_1G   |
> +                       ETH_LINK_SPEED_2_5G |
> +                       ETH_LINK_SPEED_5G   |
> +                       ETH_LINK_SPEED_10G  |
> +                       ETH_LINK_SPEED_25G  |
> +                       ETH_LINK_SPEED_40G  |
> +                       ETH_LINK_SPEED_50G;
> +
>         /* Get supported features from HW */
>         rc = ena_com_get_dev_attr_feat(ena_dev, &feat);
>         if (unlikely(rc)) {
> diff --git a/drivers/net/fm10k/fm10k_ethdev.c
> b/drivers/net/fm10k/fm10k_ethdev.c
> index 53aa1bb..85ad0df 100644
> --- a/drivers/net/fm10k/fm10k_ethdev.c
> +++ b/drivers/net/fm10k/fm10k_ethdev.c
> @@ -1410,6 +1410,10 @@ fm10k_dev_infos_get(struct rte_eth_dev *dev,
>                 .nb_min = FM10K_MIN_TX_DESC,
>                 .nb_align = FM10K_MULT_TX_DESC,
>         };
> +
> +       dev_info->speed_capa = ETH_LINK_SPEED_1G | ETH_LINK_SPEED_2_5G |
> +                       ETH_LINK_SPEED_10G | ETH_LINK_SPEED_25G |
> +                       ETH_LINK_SPEED_40G;
>  }
>
>  #ifdef RTE_LIBRTE_FM10K_RX_OLFLAGS_ENABLE
> diff --git a/drivers/net/i40e/i40e_ethdev.c
> b/drivers/net/i40e/i40e_ethdev.c
> index cce9e6f..dce31db 100644
> --- a/drivers/net/i40e/i40e_ethdev.c
> +++ b/drivers/net/i40e/i40e_ethdev.c
> @@ -2287,6 +2287,7 @@ static void
>  i40e_dev_info_get(struct rte_eth_dev *dev, struct rte_eth_dev_info
> *dev_info)
>  {
>         struct i40e_pf *pf =
> I40E_DEV_PRIVATE_TO_PF(dev->data->dev_private);
> +       struct i40e_hw *hw =
> I40E_DEV_PRIVATE_TO_HW(dev->data->dev_private);
>         struct i40e_vsi *vsi = pf->main_vsi;
>
>         dev_info->max_rx_queues = vsi->nb_qps;
> @@ -2358,6 +2359,13 @@ i40e_dev_info_get(struct rte_eth_dev *dev, struct
> rte_eth_dev_info *dev_info)
>                 dev_info->max_rx_queues += dev_info->vmdq_queue_num;
>                 dev_info->max_tx_queues += dev_info->vmdq_queue_num;
>         }
> +
> +       if (i40e_is_40G_device(hw->device_id))
> +               /* For XL710 */
> +               dev_info->speed_capa = ETH_LINK_SPEED_1G |
> ETH_LINK_SPEED_10G;
> +       else
> +               /* For X710 */
> +               dev_info->speed_capa = ETH_LINK_SPEED_10G |
> ETH_LINK_SPEED_40G;
>  }
>
>  static int
> diff --git a/drivers/net/ixgbe/ixgbe_ethdev.c
> b/drivers/net/ixgbe/ixgbe_ethdev.c
> index a0179d2..a98e8eb 100644
> --- a/drivers/net/ixgbe/ixgbe_ethdev.c
> +++ b/drivers/net/ixgbe/ixgbe_ethdev.c
> @@ -2960,6 +2960,14 @@ ixgbe_dev_info_get(struct rte_eth_dev *dev, struct
> rte_eth_dev_info *dev_info)
>         dev_info->hash_key_size = IXGBE_HKEY_MAX_INDEX * sizeof(uint32_t);
>         dev_info->reta_size = ixgbe_reta_size_get(hw->mac.type);
>         dev_info->flow_type_rss_offloads = IXGBE_RSS_OFFLOAD_ALL;
> +
> +       dev_info->speed_capa = ETH_LINK_SPEED_1G | ETH_LINK_SPEED_10G;
> +       if (hw->mac.type == ixgbe_mac_X540 ||
> +           hw->mac.type == ixgbe_mac_X540_vf ||
> +           hw->mac.type == ixgbe_mac_X550 ||
> +           hw->mac.type == ixgbe_mac_X550_vf) {
> +               dev_info->speed_capa |= ETH_LINK_SPEED_100M;
> +       }
>  }
>
>  static const uint32_t *
> diff --git a/drivers/net/mlx4/mlx4.c b/drivers/net/mlx4/mlx4.c
> index f946f08..59ac423 100644
> --- a/drivers/net/mlx4/mlx4.c
> +++ b/drivers/net/mlx4/mlx4.c
> @@ -4313,6 +4313,12 @@ mlx4_dev_infos_get(struct rte_eth_dev *dev, struct
> rte_eth_dev_info *info)
>                  0);
>         if (priv_get_ifname(priv, &ifname) == 0)
>                 info->if_index = if_nametoindex(ifname);
> +       info->speed_capa =
> +                       ETH_LINK_SPEED_1G |
> +                       ETH_LINK_SPEED_10G |
> +                       ETH_LINK_SPEED_20G |
> +                       ETH_LINK_SPEED_40G |
> +                       ETH_LINK_SPEED_56G;
>         priv_unlock(priv);
>  }
>
> diff --git a/drivers/net/mlx5/mlx5_ethdev.c
> b/drivers/net/mlx5/mlx5_ethdev.c
> index 58bfa16..d7a0eea 100644
> --- a/drivers/net/mlx5/mlx5_ethdev.c
> +++ b/drivers/net/mlx5/mlx5_ethdev.c
> @@ -559,6 +559,14 @@ mlx5_dev_infos_get(struct rte_eth_dev *dev, struct
> rte_eth_dev_info *info)
>          * size if it is not fixed.
>          * The API should be updated to solve this problem. */
>         info->reta_size = priv->ind_table_max_size;
> +       info->speed_capa =
> +                       ETH_LINK_SPEED_1G |
> +                       ETH_LINK_SPEED_10G |
> +                       ETH_LINK_SPEED_20G |
> +                       ETH_LINK_SPEED_25G |
> +                       ETH_LINK_SPEED_40G |
> +                       ETH_LINK_SPEED_50G |
> +                       ETH_LINK_SPEED_56G;
>         priv_unlock(priv);
>  }
>
> diff --git a/drivers/net/nfp/nfp_net.c b/drivers/net/nfp/nfp_net.c
> index 18ea0f4..bdeb21f 100644
> --- a/drivers/net/nfp/nfp_net.c
> +++ b/drivers/net/nfp/nfp_net.c
> @@ -1061,6 +1061,8 @@ nfp_net_infos_get(struct rte_eth_dev *dev, struct
> rte_eth_dev_info *dev_info)
>
>         dev_info->reta_size = NFP_NET_CFG_RSS_ITBL_SZ;
>         dev_info->hash_key_size = NFP_NET_CFG_RSS_KEY_SZ;
> +
> +       dev_info->speed_capa = ETH_LINK_SPEED_50G;
>  }
>
>  static const uint32_t *
> diff --git a/lib/librte_ether/rte_ethdev.h b/lib/librte_ether/rte_ethdev.h
> index bc7d607..49fdcb7 100644
> --- a/lib/librte_ether/rte_ethdev.h
> +++ b/lib/librte_ether/rte_ethdev.h
> @@ -242,6 +242,23 @@ struct rte_eth_stats {
>  };
>
>  /**
> + * Device supported speeds bitmap flags
> + */
> +#define ETH_LINK_SPEED_10M_HD   (1 <<  1)  /**<  10 Mbps half-duplex */
> +#define ETH_LINK_SPEED_10M      (1 <<  2)  /**<  10 Mbps full-duplex */
> +#define ETH_LINK_SPEED_100M_HD  (1 <<  3)  /**< 100 Mbps half-duplex */
> +#define ETH_LINK_SPEED_100M     (1 <<  4)  /**< 100 Mbps full-duplex */
> +#define ETH_LINK_SPEED_1G       (1 <<  5)  /**<   1 Gbps */
> +#define ETH_LINK_SPEED_2_5G     (1 <<  6)  /**< 2.5 Gbps */
> +#define ETH_LINK_SPEED_5G       (1 <<  7)  /**<   5 Gbps */
> +#define ETH_LINK_SPEED_10G      (1 <<  8)  /**<  10 Gbps */
> +#define ETH_LINK_SPEED_20G      (1 <<  9)  /**<  20 Gbps */
> +#define ETH_LINK_SPEED_25G      (1 << 10)  /**<  25 Gbps */
> +#define ETH_LINK_SPEED_40G      (1 << 11)  /**<  40 Gbps */
> +#define ETH_LINK_SPEED_50G      (1 << 12)  /**<  50 Gbps */
> +#define ETH_LINK_SPEED_56G      (1 << 13)  /**<  56 Gbps */
> +
> +/**
>   * Ethernet numeric link speeds in Mbps
>   */
>  #define ETH_LINK_SPEED_AUTONEG     0 /**< Auto-negotiate link speed. */
> @@ -850,6 +867,9 @@ struct rte_eth_conf {
>  #define DEV_TX_OFFLOAD_OUTER_IPV4_CKSUM 0x00000080 /**< Used for
> tunneling packet. */
>  #define DEV_TX_OFFLOAD_QINQ_INSERT 0x00000100
>
> +/**
> + * Ethernet device information
> + */
>  struct rte_eth_dev_info {
>         struct rte_pci_device *pci_dev; /**< Device PCI information. */
>         const char *driver_name; /**< Device Driver name. */
> @@ -878,6 +898,7 @@ struct rte_eth_dev_info {
>         uint16_t vmdq_pool_base;  /**< First ID of VMDQ pools. */
>         struct rte_eth_desc_lim rx_desc_lim;  /**< RX descriptors limits */
>         struct rte_eth_desc_lim tx_desc_lim;  /**< TX descriptors limits */
> +       uint32_t speed_capa;  /**< Supported speeds bitmap
> (ETH_LINK_SPEED_). */
>  };
>
>  /**
> --
> 2.1.4
>
>

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

* Re: [PATCH v13 6/8] ethdev: redesign link speed config
  2016-03-29  6:18                   ` Xing, Beilei
@ 2016-03-30  7:59                     ` Marc
  2016-03-31  0:57                       ` Xing, Beilei
  0 siblings, 1 reply; 167+ messages in thread
From: Marc @ 2016-03-30  7:59 UTC (permalink / raw)
  To: Xing, Beilei
  Cc: Thomas Monjalon, Xu, Qian Q, dev, Ananyev, Konstantin, Lu,
	Wenzhuo, Richardson, Bruce, Glynn, Michael J

On 29 March 2016 at 08:18, Xing, Beilei <beilei.xing@intel.com> wrote:

>
>
> > -----Original Message-----
> > From: Marc Sune [mailto:marcdevel@gmail.com]
> > Sent: Saturday, March 26, 2016 9:27 AM
> > To: Thomas Monjalon <thomas.monjalon@6wind.com>; Xu, Qian Q
> > <qian.q.xu@intel.com>; Xing, Beilei <beilei.xing@intel.com>;
> dev@dpdk.org;
> > Ananyev, Konstantin <konstantin.ananyev@intel.com>; Lu, Wenzhuo
> > <wenzhuo.lu@intel.com>; Richardson, Bruce <bruce.richardson@intel.com>;
> > Glynn, Michael J <michael.j.glynn@intel.com>
> > Cc: Marc Sune <marcdevel@gmail.com>
> > Subject: [PATCH v13 6/8] ethdev: redesign link speed config
> >
>
> > a/drivers/net/ixgbe/ixgbe_ethdev.c b/drivers/net/ixgbe/ixgbe_ethdev.c
> > index a98e8eb..6cc2da0 100644
> > --- a/drivers/net/ixgbe/ixgbe_ethdev.c
> > +++ b/drivers/net/ixgbe/ixgbe_ethdev.c
> > @@ -2193,32 +2195,21 @@ ixgbe_dev_start(struct rte_eth_dev *dev)
> >       if (err)
> >               goto error;
> >
> > +     speed = 0x0;
> > +     if (*link_speeds & ETH_LINK_SPEED_10G)
> > +             speed |= IXGBE_LINK_SPEED_10GB_FULL;
> > +     if (*link_speeds & ETH_LINK_SPEED_1G)
> > +             speed |= IXGBE_LINK_SPEED_1GB_FULL;
> > +     if (*link_speeds & ETH_LINK_SPEED_100M)
> > +             speed |= IXGBE_LINK_SPEED_100_FULL;
> > +
> >       err = ixgbe_setup_link(hw, speed, link_up);
> >       if (err)
> >               goto error;
>
> Hi Marc,
> According to ixgbe HW, link speed shouldn't be 0 when setting up,
> Otherwise device will start fail. So we need to set speed if link_speed
> is ETH_LINK_SPEED_AUTONEG. Following code is for reference.
>
>         speed = 0x0;
>         if ((*link_speeds & 0x1) == ETH_LINK_SPEED_AUTONEG)
>                 speed = (hw->mac.type != ixgbe_mac_82598EB) ?
>                         IXGBE_LINK_SPEED_82599_AUTONEG :
>                         IXGBE_LINK_SPEED_82598_AUTONEG;
>         else {
>                 if (*link_speeds & ETH_LINK_SPEED_10G)
>                         speed |= IXGBE_LINK_SPEED_10GB_FULL;
>                 if (*link_speeds & ETH_LINK_SPEED_1G)
>                         speed |= IXGBE_LINK_SPEED_1GB_FULL;
>                 if (*link_speeds & ETH_LINK_SPEED_100M)
>                         speed |= IXGBE_LINK_SPEED_100_FULL;
>         }
>

Beilei,

OK, thanks.

Can you/someone please try v13 + this modification, so that we make sure
this is the final version for ixgbe?

Regards
Marc


>
> Beilei Xing
> Thanks
>

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

* Re: [PATCH v13 5/8] ethdev: add speed capabilities
  2016-03-29 13:31                   ` Alejandro Lucero
@ 2016-03-30  8:06                     ` Marc
  0 siblings, 0 replies; 167+ messages in thread
From: Marc @ 2016-03-30  8:06 UTC (permalink / raw)
  To: Alejandro Lucero
  Cc: Thomas Monjalon, Xu, Qian Q, Xing, Beilei, dev, Ananyev,
	Konstantin, Lu, Wenzhuo, Richardson, Bruce, Glynn, Michael J

On 29 March 2016 at 15:31, Alejandro Lucero <alejandro.lucero@netronome.com>
wrote:

> For nfp.c, speed_capa should be ETH_LINK_SPEED_40G instead of ETH_LINK_SPEED_50G.
> By the way, the change in patch 4 sets the right link speed using the new
> constants.
>
> Regards
>

Noted for v14, thanks

Marc


>
> On Sat, Mar 26, 2016 at 1:27 AM, Marc Sune <marcdevel@gmail.com> wrote:
>
>> The speed capabilities of a device can be retrieved with
>> rte_eth_dev_info_get().
>>
>> The new field speed_capa is initialized in the drivers without
>> taking care of device characteristics in this patch.
>> When the capabilities of a driver are accurate, the table in
>> overview.rst must be filled.
>>
>> Signed-off-by: Marc Sune <marcdevel@gmail.com>
>> ---
>>  doc/guides/nics/overview.rst           |  1 +
>>  doc/guides/rel_notes/release_16_04.rst |  8 ++++++++
>>  drivers/net/bnx2x/bnx2x_ethdev.c       |  1 +
>>  drivers/net/cxgbe/cxgbe_ethdev.c       |  1 +
>>  drivers/net/e1000/em_ethdev.c          |  4 ++++
>>  drivers/net/e1000/igb_ethdev.c         |  4 ++++
>>  drivers/net/ena/ena_ethdev.c           |  9 +++++++++
>>  drivers/net/fm10k/fm10k_ethdev.c       |  4 ++++
>>  drivers/net/i40e/i40e_ethdev.c         |  8 ++++++++
>>  drivers/net/ixgbe/ixgbe_ethdev.c       |  8 ++++++++
>>  drivers/net/mlx4/mlx4.c                |  6 ++++++
>>  drivers/net/mlx5/mlx5_ethdev.c         |  8 ++++++++
>>  drivers/net/nfp/nfp_net.c              |  2 ++
>>  lib/librte_ether/rte_ethdev.h          | 21 +++++++++++++++++++++
>>  14 files changed, 85 insertions(+)
>>
>> diff --git a/doc/guides/nics/overview.rst b/doc/guides/nics/overview.rst
>> index 542479a..62f1868 100644
>> --- a/doc/guides/nics/overview.rst
>> +++ b/doc/guides/nics/overview.rst
>> @@ -86,6 +86,7 @@ Most of these differences are summarized below.
>>                                            e   e       e   e   e
>>            e
>>                                            c   c       c   c   c
>>            c
>>     ==================== = = = = = = = = = = = = = = = = = = = = = = = =
>> = = = = = = = = =
>> +   speed capabilities
>>     link status                  X       X X
>>      X X
>>     link status event                    X X
>>        X
>>     queue status event
>>        X
>> diff --git a/doc/guides/rel_notes/release_16_04.rst
>> b/doc/guides/rel_notes/release_16_04.rst
>> index 79d76e1..9e7b0b7 100644
>> --- a/doc/guides/rel_notes/release_16_04.rst
>> +++ b/doc/guides/rel_notes/release_16_04.rst
>> @@ -47,6 +47,11 @@ This section should contain new features added in this
>> release. Sample format:
>>    A new function ``rte_pktmbuf_alloc_bulk()`` has been added to allow
>> the user
>>    to allocate a bulk of mbufs.
>>
>> +* **Added device link speed capabilities.**
>> +
>> +  The structure ``rte_eth_dev_info`` has now a ``speed_capa`` bitmap,
>> which
>> +  allows the application to know the supported speeds of each device.
>> +
>>  * **Added new poll-mode driver for Amazon Elastic Network Adapters
>> (ENA).**
>>
>>    The driver operates variety of ENA adapters through feature negotiation
>> @@ -456,6 +461,9 @@ This section should contain API changes. Sample
>> format:
>>    All drivers are now counting the missed packets only once, i.e.
>> drivers will
>>    not increment ierrors anymore for missed packets.
>>
>> +* The ethdev structure ``rte_eth_dev_info`` was changed to support device
>> +  speed capabilities.
>> +
>>  * The functions ``rte_eth_dev_udp_tunnel_add`` and
>> ``rte_eth_dev_udp_tunnel_delete``
>>    have been renamed into ``rte_eth_dev_udp_tunnel_port_add`` and
>>    ``rte_eth_dev_udp_tunnel_port_delete``.
>> diff --git a/drivers/net/bnx2x/bnx2x_ethdev.c
>> b/drivers/net/bnx2x/bnx2x_ethdev.c
>> index a3c6c01..897081f 100644
>> --- a/drivers/net/bnx2x/bnx2x_ethdev.c
>> +++ b/drivers/net/bnx2x/bnx2x_ethdev.c
>> @@ -327,6 +327,7 @@ bnx2x_dev_infos_get(struct rte_eth_dev *dev,
>> __rte_unused struct rte_eth_dev_inf
>>         dev_info->min_rx_bufsize = BNX2X_MIN_RX_BUF_SIZE;
>>         dev_info->max_rx_pktlen  = BNX2X_MAX_RX_PKT_LEN;
>>         dev_info->max_mac_addrs  = BNX2X_MAX_MAC_ADDRS;
>> +       dev_info->speed_capa = ETH_LINK_SPEED_10G | ETH_LINK_SPEED_20G;
>>  }
>>
>>  static void
>> diff --git a/drivers/net/cxgbe/cxgbe_ethdev.c
>> b/drivers/net/cxgbe/cxgbe_ethdev.c
>> index 8845c76..bb134e5 100644
>> --- a/drivers/net/cxgbe/cxgbe_ethdev.c
>> +++ b/drivers/net/cxgbe/cxgbe_ethdev.c
>> @@ -171,6 +171,7 @@ static void cxgbe_dev_info_get(struct rte_eth_dev
>> *eth_dev,
>>
>>         device_info->rx_desc_lim = cxgbe_desc_lim;
>>         device_info->tx_desc_lim = cxgbe_desc_lim;
>> +       device_info->speed_capa = ETH_LINK_SPEED_10G | ETH_LINK_SPEED_40G;
>>  }
>>
>>  static void cxgbe_dev_promiscuous_enable(struct rte_eth_dev *eth_dev)
>> diff --git a/drivers/net/e1000/em_ethdev.c b/drivers/net/e1000/em_ethdev.c
>> index 473d77f..d5f8c7f 100644
>> --- a/drivers/net/e1000/em_ethdev.c
>> +++ b/drivers/net/e1000/em_ethdev.c
>> @@ -1054,6 +1054,10 @@ eth_em_infos_get(struct rte_eth_dev *dev, struct
>> rte_eth_dev_info *dev_info)
>>                 .nb_min = E1000_MIN_RING_DESC,
>>                 .nb_align = EM_TXD_ALIGN,
>>         };
>> +
>> +       dev_info->speed_capa = ETH_LINK_SPEED_10M_HD | ETH_LINK_SPEED_10M
>> |
>> +                       ETH_LINK_SPEED_100M_HD | ETH_LINK_SPEED_100M |
>> +                       ETH_LINK_SPEED_1G;
>>  }
>>
>>  /* return 0 means link status changed, -1 means not changed */
>> diff --git a/drivers/net/e1000/igb_ethdev.c
>> b/drivers/net/e1000/igb_ethdev.c
>> index 86f25f6..95d1711 100644
>> --- a/drivers/net/e1000/igb_ethdev.c
>> +++ b/drivers/net/e1000/igb_ethdev.c
>> @@ -1921,6 +1921,10 @@ eth_igb_infos_get(struct rte_eth_dev *dev, struct
>> rte_eth_dev_info *dev_info)
>>
>>         dev_info->rx_desc_lim = rx_desc_lim;
>>         dev_info->tx_desc_lim = tx_desc_lim;
>> +
>> +       dev_info->speed_capa = ETH_LINK_SPEED_10M_HD | ETH_LINK_SPEED_10M
>> |
>> +                       ETH_LINK_SPEED_100M_HD | ETH_LINK_SPEED_100M |
>> +                       ETH_LINK_SPEED_1G;
>>  }
>>
>>  static const uint32_t *
>> diff --git a/drivers/net/ena/ena_ethdev.c b/drivers/net/ena/ena_ethdev.c
>> index 1046286..4e403af 100644
>> --- a/drivers/net/ena/ena_ethdev.c
>> +++ b/drivers/net/ena/ena_ethdev.c
>> @@ -1170,6 +1170,15 @@ static void ena_infos_get(struct rte_eth_dev *dev,
>>         ena_dev = &adapter->ena_dev;
>>         ena_assert_msg(ena_dev != NULL, "Uninitialized device");
>>
>> +       dev_info->speed_capa =
>> +                       ETH_LINK_SPEED_1G   |
>> +                       ETH_LINK_SPEED_2_5G |
>> +                       ETH_LINK_SPEED_5G   |
>> +                       ETH_LINK_SPEED_10G  |
>> +                       ETH_LINK_SPEED_25G  |
>> +                       ETH_LINK_SPEED_40G  |
>> +                       ETH_LINK_SPEED_50G;
>> +
>>         /* Get supported features from HW */
>>         rc = ena_com_get_dev_attr_feat(ena_dev, &feat);
>>         if (unlikely(rc)) {
>> diff --git a/drivers/net/fm10k/fm10k_ethdev.c
>> b/drivers/net/fm10k/fm10k_ethdev.c
>> index 53aa1bb..85ad0df 100644
>> --- a/drivers/net/fm10k/fm10k_ethdev.c
>> +++ b/drivers/net/fm10k/fm10k_ethdev.c
>> @@ -1410,6 +1410,10 @@ fm10k_dev_infos_get(struct rte_eth_dev *dev,
>>                 .nb_min = FM10K_MIN_TX_DESC,
>>                 .nb_align = FM10K_MULT_TX_DESC,
>>         };
>> +
>> +       dev_info->speed_capa = ETH_LINK_SPEED_1G | ETH_LINK_SPEED_2_5G |
>> +                       ETH_LINK_SPEED_10G | ETH_LINK_SPEED_25G |
>> +                       ETH_LINK_SPEED_40G;
>>  }
>>
>>  #ifdef RTE_LIBRTE_FM10K_RX_OLFLAGS_ENABLE
>> diff --git a/drivers/net/i40e/i40e_ethdev.c
>> b/drivers/net/i40e/i40e_ethdev.c
>> index cce9e6f..dce31db 100644
>> --- a/drivers/net/i40e/i40e_ethdev.c
>> +++ b/drivers/net/i40e/i40e_ethdev.c
>> @@ -2287,6 +2287,7 @@ static void
>>  i40e_dev_info_get(struct rte_eth_dev *dev, struct rte_eth_dev_info
>> *dev_info)
>>  {
>>         struct i40e_pf *pf =
>> I40E_DEV_PRIVATE_TO_PF(dev->data->dev_private);
>> +       struct i40e_hw *hw =
>> I40E_DEV_PRIVATE_TO_HW(dev->data->dev_private);
>>         struct i40e_vsi *vsi = pf->main_vsi;
>>
>>         dev_info->max_rx_queues = vsi->nb_qps;
>> @@ -2358,6 +2359,13 @@ i40e_dev_info_get(struct rte_eth_dev *dev, struct
>> rte_eth_dev_info *dev_info)
>>                 dev_info->max_rx_queues += dev_info->vmdq_queue_num;
>>                 dev_info->max_tx_queues += dev_info->vmdq_queue_num;
>>         }
>> +
>> +       if (i40e_is_40G_device(hw->device_id))
>> +               /* For XL710 */
>> +               dev_info->speed_capa = ETH_LINK_SPEED_1G |
>> ETH_LINK_SPEED_10G;
>> +       else
>> +               /* For X710 */
>> +               dev_info->speed_capa = ETH_LINK_SPEED_10G |
>> ETH_LINK_SPEED_40G;
>>  }
>>
>>  static int
>> diff --git a/drivers/net/ixgbe/ixgbe_ethdev.c
>> b/drivers/net/ixgbe/ixgbe_ethdev.c
>> index a0179d2..a98e8eb 100644
>> --- a/drivers/net/ixgbe/ixgbe_ethdev.c
>> +++ b/drivers/net/ixgbe/ixgbe_ethdev.c
>> @@ -2960,6 +2960,14 @@ ixgbe_dev_info_get(struct rte_eth_dev *dev, struct
>> rte_eth_dev_info *dev_info)
>>         dev_info->hash_key_size = IXGBE_HKEY_MAX_INDEX * sizeof(uint32_t);
>>         dev_info->reta_size = ixgbe_reta_size_get(hw->mac.type);
>>         dev_info->flow_type_rss_offloads = IXGBE_RSS_OFFLOAD_ALL;
>> +
>> +       dev_info->speed_capa = ETH_LINK_SPEED_1G | ETH_LINK_SPEED_10G;
>> +       if (hw->mac.type == ixgbe_mac_X540 ||
>> +           hw->mac.type == ixgbe_mac_X540_vf ||
>> +           hw->mac.type == ixgbe_mac_X550 ||
>> +           hw->mac.type == ixgbe_mac_X550_vf) {
>> +               dev_info->speed_capa |= ETH_LINK_SPEED_100M;
>> +       }
>>  }
>>
>>  static const uint32_t *
>> diff --git a/drivers/net/mlx4/mlx4.c b/drivers/net/mlx4/mlx4.c
>> index f946f08..59ac423 100644
>> --- a/drivers/net/mlx4/mlx4.c
>> +++ b/drivers/net/mlx4/mlx4.c
>> @@ -4313,6 +4313,12 @@ mlx4_dev_infos_get(struct rte_eth_dev *dev, struct
>> rte_eth_dev_info *info)
>>                  0);
>>         if (priv_get_ifname(priv, &ifname) == 0)
>>                 info->if_index = if_nametoindex(ifname);
>> +       info->speed_capa =
>> +                       ETH_LINK_SPEED_1G |
>> +                       ETH_LINK_SPEED_10G |
>> +                       ETH_LINK_SPEED_20G |
>> +                       ETH_LINK_SPEED_40G |
>> +                       ETH_LINK_SPEED_56G;
>>         priv_unlock(priv);
>>  }
>>
>> diff --git a/drivers/net/mlx5/mlx5_ethdev.c
>> b/drivers/net/mlx5/mlx5_ethdev.c
>> index 58bfa16..d7a0eea 100644
>> --- a/drivers/net/mlx5/mlx5_ethdev.c
>> +++ b/drivers/net/mlx5/mlx5_ethdev.c
>> @@ -559,6 +559,14 @@ mlx5_dev_infos_get(struct rte_eth_dev *dev, struct
>> rte_eth_dev_info *info)
>>          * size if it is not fixed.
>>          * The API should be updated to solve this problem. */
>>         info->reta_size = priv->ind_table_max_size;
>> +       info->speed_capa =
>> +                       ETH_LINK_SPEED_1G |
>> +                       ETH_LINK_SPEED_10G |
>> +                       ETH_LINK_SPEED_20G |
>> +                       ETH_LINK_SPEED_25G |
>> +                       ETH_LINK_SPEED_40G |
>> +                       ETH_LINK_SPEED_50G |
>> +                       ETH_LINK_SPEED_56G;
>>         priv_unlock(priv);
>>  }
>>
>> diff --git a/drivers/net/nfp/nfp_net.c b/drivers/net/nfp/nfp_net.c
>> index 18ea0f4..bdeb21f 100644
>> --- a/drivers/net/nfp/nfp_net.c
>> +++ b/drivers/net/nfp/nfp_net.c
>> @@ -1061,6 +1061,8 @@ nfp_net_infos_get(struct rte_eth_dev *dev, struct
>> rte_eth_dev_info *dev_info)
>>
>>         dev_info->reta_size = NFP_NET_CFG_RSS_ITBL_SZ;
>>         dev_info->hash_key_size = NFP_NET_CFG_RSS_KEY_SZ;
>> +
>> +       dev_info->speed_capa = ETH_LINK_SPEED_50G;
>>  }
>>
>>  static const uint32_t *
>> diff --git a/lib/librte_ether/rte_ethdev.h b/lib/librte_ether/rte_ethdev.h
>> index bc7d607..49fdcb7 100644
>> --- a/lib/librte_ether/rte_ethdev.h
>> +++ b/lib/librte_ether/rte_ethdev.h
>> @@ -242,6 +242,23 @@ struct rte_eth_stats {
>>  };
>>
>>  /**
>> + * Device supported speeds bitmap flags
>> + */
>> +#define ETH_LINK_SPEED_10M_HD   (1 <<  1)  /**<  10 Mbps half-duplex */
>> +#define ETH_LINK_SPEED_10M      (1 <<  2)  /**<  10 Mbps full-duplex */
>> +#define ETH_LINK_SPEED_100M_HD  (1 <<  3)  /**< 100 Mbps half-duplex */
>> +#define ETH_LINK_SPEED_100M     (1 <<  4)  /**< 100 Mbps full-duplex */
>> +#define ETH_LINK_SPEED_1G       (1 <<  5)  /**<   1 Gbps */
>> +#define ETH_LINK_SPEED_2_5G     (1 <<  6)  /**< 2.5 Gbps */
>> +#define ETH_LINK_SPEED_5G       (1 <<  7)  /**<   5 Gbps */
>> +#define ETH_LINK_SPEED_10G      (1 <<  8)  /**<  10 Gbps */
>> +#define ETH_LINK_SPEED_20G      (1 <<  9)  /**<  20 Gbps */
>> +#define ETH_LINK_SPEED_25G      (1 << 10)  /**<  25 Gbps */
>> +#define ETH_LINK_SPEED_40G      (1 << 11)  /**<  40 Gbps */
>> +#define ETH_LINK_SPEED_50G      (1 << 12)  /**<  50 Gbps */
>> +#define ETH_LINK_SPEED_56G      (1 << 13)  /**<  56 Gbps */
>> +
>> +/**
>>   * Ethernet numeric link speeds in Mbps
>>   */
>>  #define ETH_LINK_SPEED_AUTONEG     0 /**< Auto-negotiate link speed. */
>> @@ -850,6 +867,9 @@ struct rte_eth_conf {
>>  #define DEV_TX_OFFLOAD_OUTER_IPV4_CKSUM 0x00000080 /**< Used for
>> tunneling packet. */
>>  #define DEV_TX_OFFLOAD_QINQ_INSERT 0x00000100
>>
>> +/**
>> + * Ethernet device information
>> + */
>>  struct rte_eth_dev_info {
>>         struct rte_pci_device *pci_dev; /**< Device PCI information. */
>>         const char *driver_name; /**< Device Driver name. */
>> @@ -878,6 +898,7 @@ struct rte_eth_dev_info {
>>         uint16_t vmdq_pool_base;  /**< First ID of VMDQ pools. */
>>         struct rte_eth_desc_lim rx_desc_lim;  /**< RX descriptors limits
>> */
>>         struct rte_eth_desc_lim tx_desc_lim;  /**< TX descriptors limits
>> */
>> +       uint32_t speed_capa;  /**< Supported speeds bitmap
>> (ETH_LINK_SPEED_). */
>>  };
>>
>>  /**
>> --
>> 2.1.4
>>
>>
>

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

* Re: [PATCH v13 0/8] ethdev: 100G and link speed API refactoring
  2016-03-26  1:27               ` [PATCH v13 0/8] ethdev: 100G and link speed API refactoring Marc Sune
                                   ` (8 preceding siblings ...)
  2016-03-26  8:11                 ` [PATCH v13 0/8] ethdev: 100G and link speed API refactoring Thomas Monjalon
@ 2016-03-30  9:23                 ` Thomas Monjalon
  2016-03-31  6:25                   ` Lu, Wenzhuo
  2016-03-31 22:12                 ` [PATCH v14 " Marc Sune
  10 siblings, 1 reply; 167+ messages in thread
From: Thomas Monjalon @ 2016-03-30  9:23 UTC (permalink / raw)
  To: dev
  Cc: Marc Sune, Xu, Qian Q, Xing, Beilei, Ananyev, Konstantin, Lu,
	Wenzhuo, Richardson, Bruce, Glynn, Michael J

2016-03-26 02:27, Marc Sune:
> There are still too few tests and reviews, especially for
> autonegotiation with Intel devices (patch #6).
> I would not be surprised to see some bugs in this rework.
> 
> The capabilities must be adapted per device. It can be
> improved in a separate patch.
> 
> It will be integrated in 16.04-rc3.
> Please test and review shortly, thanks!

Still no feedback for e1000 and i40e devices.
Should we consider it is working fine?

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

* Re: [PATCH v13 6/8] ethdev: redesign link speed config
  2016-03-30  7:59                     ` Marc
@ 2016-03-31  0:57                       ` Xing, Beilei
  2016-03-31 12:28                         ` Thomas Monjalon
  0 siblings, 1 reply; 167+ messages in thread
From: Xing, Beilei @ 2016-03-31  0:57 UTC (permalink / raw)
  To: Marc
  Cc: Thomas Monjalon, Xu, Qian Q, dev, Ananyev, Konstantin, Lu,
	Wenzhuo, Richardson, Bruce, Glynn, Michael J

Marc,

I’ve verified v13 + the modification, and it works.

Best Regards
Beilei Xing

From: marc.sune@gmail.com [mailto:marc.sune@gmail.com] On Behalf Of Marc
Sent: Wednesday, March 30, 2016 4:00 PM
To: Xing, Beilei <beilei.xing@intel.com>
Cc: Thomas Monjalon <thomas.monjalon@6wind.com>; Xu, Qian Q <qian.q.xu@intel.com>; dev@dpdk.org; Ananyev, Konstantin <konstantin.ananyev@intel.com>; Lu, Wenzhuo <wenzhuo.lu@intel.com>; Richardson, Bruce <bruce.richardson@intel.com>; Glynn, Michael J <michael.j.glynn@intel.com>
Subject: Re: [PATCH v13 6/8] ethdev: redesign link speed config



On 29 March 2016 at 08:18, Xing, Beilei <beilei.xing@intel.com<mailto:beilei.xing@intel.com>> wrote:


> -----Original Message-----
> From: Marc Sune [mailto:marcdevel@gmail.com<mailto:marcdevel@gmail.com>]
> Sent: Saturday, March 26, 2016 9:27 AM
> To: Thomas Monjalon <thomas.monjalon@6wind.com<mailto:thomas.monjalon@6wind.com>>; Xu, Qian Q
> <qian.q.xu@intel.com<mailto:qian.q.xu@intel.com>>; Xing, Beilei <beilei.xing@intel.com<mailto:beilei.xing@intel.com>>; dev@dpdk.org<mailto:dev@dpdk.org>;
> Ananyev, Konstantin <konstantin.ananyev@intel.com<mailto:konstantin.ananyev@intel.com>>; Lu, Wenzhuo
> <wenzhuo.lu@intel.com<mailto:wenzhuo.lu@intel.com>>; Richardson, Bruce <bruce.richardson@intel.com<mailto:bruce.richardson@intel.com>>;
> Glynn, Michael J <michael.j.glynn@intel.com<mailto:michael.j.glynn@intel.com>>
> Cc: Marc Sune <marcdevel@gmail.com<mailto:marcdevel@gmail.com>>
> Subject: [PATCH v13 6/8] ethdev: redesign link speed config
>

> a/drivers/net/ixgbe/ixgbe_ethdev.c b/drivers/net/ixgbe/ixgbe_ethdev.c
> index a98e8eb..6cc2da0 100644
> --- a/drivers/net/ixgbe/ixgbe_ethdev.c
> +++ b/drivers/net/ixgbe/ixgbe_ethdev.c
> @@ -2193,32 +2195,21 @@ ixgbe_dev_start(struct rte_eth_dev *dev)
>       if (err)
>               goto error;
>
> +     speed = 0x0;
> +     if (*link_speeds & ETH_LINK_SPEED_10G)
> +             speed |= IXGBE_LINK_SPEED_10GB_FULL;
> +     if (*link_speeds & ETH_LINK_SPEED_1G)
> +             speed |= IXGBE_LINK_SPEED_1GB_FULL;
> +     if (*link_speeds & ETH_LINK_SPEED_100M)
> +             speed |= IXGBE_LINK_SPEED_100_FULL;
> +
>       err = ixgbe_setup_link(hw, speed, link_up);
>       if (err)
>               goto error;

Hi Marc,
According to ixgbe HW, link speed shouldn't be 0 when setting up,
Otherwise device will start fail. So we need to set speed if link_speed
is ETH_LINK_SPEED_AUTONEG. Following code is for reference.

        speed = 0x0;
        if ((*link_speeds & 0x1) == ETH_LINK_SPEED_AUTONEG)
                speed = (hw->mac.type != ixgbe_mac_82598EB) ?
                        IXGBE_LINK_SPEED_82599_AUTONEG :
                        IXGBE_LINK_SPEED_82598_AUTONEG;
        else {
                if (*link_speeds & ETH_LINK_SPEED_10G)
                        speed |= IXGBE_LINK_SPEED_10GB_FULL;
                if (*link_speeds & ETH_LINK_SPEED_1G)
                        speed |= IXGBE_LINK_SPEED_1GB_FULL;
                if (*link_speeds & ETH_LINK_SPEED_100M)
                        speed |= IXGBE_LINK_SPEED_100_FULL;
        }

Beilei,

OK, thanks.

Can you/someone please try v13 + this modification, so that we make sure this is the final version for ixgbe?

Regards
Marc


Beilei Xing
Thanks


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

* Re: [PATCH v13 0/8] ethdev: 100G and link speed API refactoring
  2016-03-30  9:23                 ` Thomas Monjalon
@ 2016-03-31  6:25                   ` Lu, Wenzhuo
  0 siblings, 0 replies; 167+ messages in thread
From: Lu, Wenzhuo @ 2016-03-31  6:25 UTC (permalink / raw)
  To: Thomas Monjalon, dev
  Cc: Marc Sune, Xu, Qian Q, Xing, Beilei, Ananyev, Konstantin,
	Richardson, Bruce, Glynn, Michael J

Hi Thomas, Marc,

> -----Original Message-----
> From: Thomas Monjalon [mailto:thomas.monjalon@6wind.com]
> Sent: Wednesday, March 30, 2016 5:23 PM
> To: dev@dpdk.org
> Cc: Marc Sune; Xu, Qian Q; Xing, Beilei; Ananyev, Konstantin; Lu, Wenzhuo;
> Richardson, Bruce; Glynn, Michael J
> Subject: Re: [PATCH v13 0/8] ethdev: 100G and link speed API refactoring
> 
> 2016-03-26 02:27, Marc Sune:
> > There are still too few tests and reviews, especially for
> > autonegotiation with Intel devices (patch #6).
> > I would not be surprised to see some bugs in this rework.
> >
> > The capabilities must be adapted per device. It can be improved in a
> > separate patch.
> >
> > It will be integrated in 16.04-rc3.
> > Please test and review shortly, thanks!
> 
> Still no feedback for e1000 and i40e devices.
> Should we consider it is working fine?
I've tried i350 with this patch set. At least the basic rx/tx function is working.
But it's a big patch, I still have some questions. I'll comment soon.

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

* Re: [PATCH v13 6/8] ethdev: redesign link speed config
  2016-03-31  0:57                       ` Xing, Beilei
@ 2016-03-31 12:28                         ` Thomas Monjalon
  2016-04-01  9:53                           ` Xing, Beilei
  0 siblings, 1 reply; 167+ messages in thread
From: Thomas Monjalon @ 2016-03-31 12:28 UTC (permalink / raw)
  To: Xing, Beilei
  Cc: dev, Marc, Xu, Qian Q, Ananyev, Konstantin, Lu, Wenzhuo,
	Richardson, Bruce, Glynn, Michael J

2016-03-31 00:57, Xing, Beilei:
> I’ve verified v13 + the modification, and it works.

Please, what have you tested? Which drivers? Which configurations?

It is important to test several uses of rte_eth_conf.link_speeds:
- ETH_LINK_SPEED_AUTONEG (all speeds)
- ETH_LINK_SPEED_FIXED (only one speed)
- a subset of speeds to advertise and negotiate

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

* Re: [PATCH v13 0/8] ethdev: 100G and link speed API refactoring
  2016-03-26  8:11                 ` [PATCH v13 0/8] ethdev: 100G and link speed API refactoring Thomas Monjalon
@ 2016-03-31 16:17                   ` Adrien Mazarguil
  0 siblings, 0 replies; 167+ messages in thread
From: Adrien Mazarguil @ 2016-03-31 16:17 UTC (permalink / raw)
  To: Thomas Monjalon
  Cc: Marc Sune, Xu, Qian Q, Xing, Beilei, dev, Ananyev, Konstantin,
	Lu, Wenzhuo, Richardson, Bruce, Glynn, Michael J

On Sat, Mar 26, 2016 at 09:11:38AM +0100, Thomas Monjalon wrote:
> > v13:
> >     - Fix startup regression; revert flip of ETH_LINK_SPEED_FIXED and
> >       ETH_LINK_SPEED_AUTONEG values. ETH_LINK_SPEED_AUTONEG is now 0.
> 
> As commented earlier, I would prefer avoiding this revert.
> Comments are welcome.

I've tested v13 using testpmd and ixgbe. Performed the following checks:

- Port start/stop - OK, link speed is displayed correctly.
- Forcing 1G / duplex auto - OK.
- Forcing 10G / duplex auto - OK.
- Forcing 10G / duplex half - half is not allowed (expected).
- Forcing 40G / duplex auto - unsupported, causes port start to fail
  (expected). 
- Forcing 1G / duplex full - OK.
- Forcing 100 / duplex half - unsupported, causes port start to fail
  (expected). 
- Forcing 100 / duplex full - OK.
- Traffic flows whenever link speed is supported/negotiated.

Tested-by: Adrien Mazarguil <adrien.mazarguil@6wind.com>

-- 
Adrien Mazarguil
6WIND

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

* [PATCH v14 0/8] ethdev: 100G and link speed API refactoring
  2016-03-26  1:27               ` [PATCH v13 0/8] ethdev: 100G and link speed API refactoring Marc Sune
                                   ` (9 preceding siblings ...)
  2016-03-30  9:23                 ` Thomas Monjalon
@ 2016-03-31 22:12                 ` Marc Sune
  2016-03-31 22:12                   ` [PATCH v14 1/8] ethdev: use constants for link state Marc Sune
                                     ` (8 more replies)
  10 siblings, 9 replies; 167+ messages in thread
From: Marc Sune @ 2016-03-31 22:12 UTC (permalink / raw)
  To: Thomas Monjalon, Xu, Qian Q, Xing, Beilei, dev, Ananyev,
	Konstantin, Lu, Wenzhuo, Richardson, Bruce, Glynn, Michael J
  Cc: Marc Sune

From: Marc Sune <marc@voltanet.io>

This series of patches adds the following capabilities:

* speed_capa bitmap in rte_eth_dev_info, which is filled by the PMDs
  according to the physical device capabilities.
* refactors link API in ethdev to allow the definition of the advertised
  link speeds, fix speed (no auto-negociation) or advertise all supported
  speeds (default).

v14:
    - Rebase to master HEAD
    - Add ETH_LINK_FIXED / ETH_LINK_AUTONEG MACROs in rte_ethdev.h
    - Fix NFP speed capability (50G -> 40G)
    - Fix ixgbe full AUTONEG

v13:
    - Fix startup regression; revert flip of ETH_LINK_SPEED_FIXED and
      ETH_LINK_SPEED_AUTONEG values. ETH_LINK_SPEED_AUTONEG is now 0.
    - Fix incorrect duplex link reporting for e1000.
    - Do not allow more than one speed in the bitmap when
      ETH_LINK_SPEED_FIXED is used for e1000.

v12:
    - rebase on 16.04-rc2
    - fix mlx capabilities
    - update ENA driver

v11:
    - rebase on 16.04-rc1
    - replace on more link status value in e1000 driver
    - merge szedata2 patches
    - remove szedata2 temporary comments in code and doc

v10:
    - rebase
    - rework release notes
    - rearrange patch splitting
    - fix doxygen comments
    - fix typos
    - removed log format of link.link_speed as %d (keep %u)
    - complete ETH_LINK_[DOWN/UP] replacement from 0/1
    - change ETH_LINK_SPEED_AUTONEG to 1
    - replace ETH_LINK_SPEED_NEG by ETH_LINK_SPEED_AUTONEG (1)
    - replace ETH_LINK_SPEED_NO_AUTONEG by ETH_LINK_SPEED_FIXED (0)
    - rework rte_eth_speed_to_bm_flag to rte_eth_speed_bitflag
    - complete 100G support in testpmd

v9: rebased to current HEAD. Reverted numeric speed to 32 bit in struct
    rte_eth_link (no atomic link get > 64bit). Fixed mlx5 driver compilation
    and link speeds. Moved documentation to release_16_04.rst and fixed several
    issues. Upgrade NIC notes with speed capabilities.

v8: Rebased to current HEAD. Modified em driver impl. to not touch base files.
    Merged patch 5 into 3 (map file). Changed numeric speed to a 64 bit value.
    Filled-in speed capabilities for drivers bnx2x, cxgbe, mlx5 and nfp in
    addition to the ones of previous patch sets.

v7: Rebased to current HEAD. Moved documentation to v2.3. Still needs testing
    from PMD maintainers.

v6: Move link_duplex to be part of bitfield. Fixed i40 autoneg flag link
    update code. Added rte_eth_speed_to_bm_flag() to .map file. Fixed other
    spelling issues. Rebased to current HEAD.

v5: revert to v2 speed capabilities patch. Fixed MLX4 speed capabilities
    (thanks N. Laranjeiro). Refactored link speed API to allow setting
    advertised speeds (3/4). Added NO_AUTONEG option to explicitely disable
    auto-negociation. Updated 2.2 rel. notes (4/4). Rebased to current HEAD.

v4: fixed errata in the documentation of field speeds of rte_eth_conf, and
    commit 1/2 message. rebased to v2.1.0. v3 was incorrectly based on
    ~2.1.0-rc1.

v3: rebase to v2.1. unified ETH_LINK_SPEED and ETH_SPEED_CAP into ETH_SPEED.
    Converted field speed in struct rte_eth_conf to speed, to allow a bitmap
    for defining the announced speeds, as suggested M. Brorup. Fixed spelling
    issues.

v2: rebase, converted speed_capa into 32 bits bitmap, fixed alignment
    (checkpatch).
*** BLURB HERE ***

Marc Sune (6):
  ethdev: use constants for link duplex
  app/testpmd: move speed and duplex parsing in a function
  ethdev: rename link speed constants
  ethdev: add speed capabilities
  ethdev: redesign link speed config
  ethdev: convert speed number to bitmap flag

Thomas Monjalon (2):
  ethdev: use constants for link state
  ethdev: add 100G link speed

 app/test-pipeline/init.c                           |   2 +-
 app/test-pmd/cmdline.c                             | 125 ++++++++++-----------
 app/test-pmd/testpmd.c                             |   2 +-
 app/test/test_pmd_perf.c                           |   2 +-
 app/test/virtual_pmd.c                             |   8 +-
 doc/guides/nics/overview.rst                       |   1 +
 doc/guides/nics/szedata2.rst                       |   6 -
 doc/guides/rel_notes/deprecation.rst               |   3 -
 doc/guides/rel_notes/release_16_04.rst             |  22 ++++
 doc/guides/testpmd_app_ug/testpmd_funcs.rst        |   2 +-
 drivers/net/af_packet/rte_eth_af_packet.c          |   9 +-
 drivers/net/bnx2x/bnx2x_ethdev.c                   |   7 +-
 drivers/net/bnx2x/elink.c                          |   2 +-
 drivers/net/bonding/rte_eth_bond_8023ad.c          |  14 +--
 drivers/net/bonding/rte_eth_bond_api.c             |   4 +-
 drivers/net/bonding/rte_eth_bond_pmd.c             |  12 +-
 drivers/net/cxgbe/base/t4_hw.c                     |   8 +-
 drivers/net/cxgbe/cxgbe_ethdev.c                   |   1 +
 drivers/net/e1000/em_ethdev.c                      | 117 +++++++++----------
 drivers/net/e1000/igb_ethdev.c                     | 105 +++++++++--------
 drivers/net/ena/ena_ethdev.c                       |  12 +-
 drivers/net/fm10k/fm10k_ethdev.c                   |   6 +-
 drivers/net/i40e/i40e_ethdev.c                     |  76 +++++++------
 drivers/net/i40e/i40e_ethdev_vf.c                  |  11 +-
 drivers/net/ixgbe/ixgbe_ethdev.c                   |  83 +++++++-------
 drivers/net/mlx4/mlx4.c                            |   8 ++
 drivers/net/mlx5/mlx5_ethdev.c                     |  11 ++
 drivers/net/mpipe/mpipe_tilegx.c                   |  18 +--
 drivers/net/nfp/nfp_net.c                          |   6 +-
 drivers/net/null/rte_eth_null.c                    |   9 +-
 drivers/net/pcap/rte_eth_pcap.c                    |   9 +-
 drivers/net/ring/rte_eth_ring.c                    |  13 ++-
 drivers/net/szedata2/rte_eth_szedata2.c            |  19 ++--
 drivers/net/vhost/rte_eth_vhost.c                  |   6 +-
 drivers/net/virtio/virtio_ethdev.c                 |   8 +-
 drivers/net/virtio/virtio_ethdev.h                 |   2 -
 drivers/net/vmxnet3/vmxnet3_ethdev.c               |   5 +-
 drivers/net/xenvirt/rte_eth_xenvirt.c              |   9 +-
 examples/exception_path/main.c                     |   2 +-
 examples/ip_fragmentation/main.c                   |   2 +-
 examples/ip_pipeline/config_parse.c                |   3 +-
 examples/ip_pipeline/init.c                        |   2 +-
 examples/ip_reassembly/main.c                      |   2 +-
 examples/ipsec-secgw/ipsec-secgw.c                 |   2 +-
 examples/ipv4_multicast/main.c                     |   2 +-
 examples/kni/main.c                                |   2 +-
 examples/l2fwd-crypto/main.c                       |   2 +-
 examples/l2fwd-ivshmem/host/host.c                 |   2 +-
 examples/l2fwd-jobstats/main.c                     |   2 +-
 examples/l2fwd-keepalive/main.c                    |   2 +-
 examples/l2fwd/main.c                              |   2 +-
 examples/l3fwd-acl/main.c                          |   2 +-
 examples/l3fwd-power/main.c                        |   2 +-
 examples/l3fwd/main.c                              |   2 +-
 examples/link_status_interrupt/main.c              |   2 +-
 examples/load_balancer/init.c                      |   2 +-
 .../client_server_mp/mp_server/init.c              |   2 +-
 examples/multi_process/l2fwd_fork/main.c           |   2 +-
 examples/multi_process/symmetric_mp/main.c         |   2 +-
 examples/performance-thread/l3fwd-thread/main.c    |   2 +-
 lib/librte_ether/rte_ethdev.c                      |  33 ++++++
 lib/librte_ether/rte_ethdev.h                      |  93 +++++++++++----
 lib/librte_ether/rte_ether_version.map             |   1 +
 63 files changed, 549 insertions(+), 386 deletions(-)

-- 
2.1.4

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

* [PATCH v14 1/8] ethdev: use constants for link state
  2016-03-31 22:12                 ` [PATCH v14 " Marc Sune
@ 2016-03-31 22:12                   ` Marc Sune
  2016-03-31 22:12                   ` [PATCH v14 2/8] ethdev: use constants for link duplex Marc Sune
                                     ` (7 subsequent siblings)
  8 siblings, 0 replies; 167+ messages in thread
From: Marc Sune @ 2016-03-31 22:12 UTC (permalink / raw)
  To: Thomas Monjalon, Xu, Qian Q, Xing, Beilei, dev, Ananyev,
	Konstantin, Lu, Wenzhuo, Richardson, Bruce, Glynn, Michael J
  Cc: Marc Sune

From: Thomas Monjalon <thomas.monjalon@6wind.com>

Define and use ETH_LINK_UP and ETH_LINK_DOWN where appropriate.

Signed-off-by: Marc Sune <marcdevel@gmail.com>
Signed-off-by: Thomas Monjalon <thomas.monjalon@6wind.com>
---
 app/test-pipeline/init.c                                 |  2 +-
 app/test-pmd/testpmd.c                                   |  2 +-
 app/test/test_pmd_perf.c                                 |  2 +-
 app/test/virtual_pmd.c                                   |  6 +++---
 drivers/net/af_packet/rte_eth_af_packet.c                |  6 +++---
 drivers/net/bnx2x/bnx2x_ethdev.c                         |  2 +-
 drivers/net/bnx2x/elink.c                                |  2 +-
 drivers/net/bonding/rte_eth_bond_api.c                   |  4 ++--
 drivers/net/bonding/rte_eth_bond_pmd.c                   | 12 ++++++------
 drivers/net/e1000/em_ethdev.c                            |  8 ++++----
 drivers/net/e1000/igb_ethdev.c                           |  4 ++--
 drivers/net/fm10k/fm10k_ethdev.c                         |  2 +-
 drivers/net/i40e/i40e_ethdev_vf.c                        |  2 +-
 drivers/net/ixgbe/ixgbe_ethdev.c                         |  4 ++--
 drivers/net/mpipe/mpipe_tilegx.c                         | 12 ++++++------
 drivers/net/nfp/nfp_net.c                                |  2 +-
 drivers/net/null/rte_eth_null.c                          |  6 +++---
 drivers/net/pcap/rte_eth_pcap.c                          |  6 +++---
 drivers/net/ring/rte_eth_ring.c                          | 10 +++++-----
 drivers/net/szedata2/rte_eth_szedata2.c                  |  2 +-
 drivers/net/vhost/rte_eth_vhost.c                        |  6 +++---
 drivers/net/virtio/virtio_ethdev.c                       |  6 +++---
 drivers/net/vmxnet3/vmxnet3_ethdev.c                     |  2 +-
 drivers/net/xenvirt/rte_eth_xenvirt.c                    |  6 +++---
 examples/exception_path/main.c                           |  2 +-
 examples/ip_fragmentation/main.c                         |  2 +-
 examples/ip_pipeline/init.c                              |  2 +-
 examples/ip_reassembly/main.c                            |  2 +-
 examples/ipsec-secgw/ipsec-secgw.c                       |  2 +-
 examples/ipv4_multicast/main.c                           |  2 +-
 examples/kni/main.c                                      |  2 +-
 examples/l2fwd-crypto/main.c                             |  2 +-
 examples/l2fwd-ivshmem/host/host.c                       |  2 +-
 examples/l2fwd-jobstats/main.c                           |  2 +-
 examples/l2fwd-keepalive/main.c                          |  2 +-
 examples/l2fwd/main.c                                    |  2 +-
 examples/l3fwd-acl/main.c                                |  2 +-
 examples/l3fwd-power/main.c                              |  2 +-
 examples/l3fwd/main.c                                    |  2 +-
 examples/link_status_interrupt/main.c                    |  2 +-
 examples/load_balancer/init.c                            |  2 +-
 examples/multi_process/client_server_mp/mp_server/init.c |  2 +-
 examples/multi_process/l2fwd_fork/main.c                 |  2 +-
 examples/multi_process/symmetric_mp/main.c               |  2 +-
 examples/performance-thread/l3fwd-thread/main.c          |  2 +-
 lib/librte_ether/rte_ethdev.h                            |  5 ++++-
 46 files changed, 83 insertions(+), 80 deletions(-)

diff --git a/app/test-pipeline/init.c b/app/test-pipeline/init.c
index db2196b..aef082f 100644
--- a/app/test-pipeline/init.c
+++ b/app/test-pipeline/init.c
@@ -205,7 +205,7 @@ app_ports_check_link(void)
 			link.link_speed / 1000,
 			link.link_status ? "UP" : "DOWN");
 
-		if (link.link_status == 0)
+		if (link.link_status == ETH_LINK_DOWN)
 			all_ports_up = 0;
 	}
 
diff --git a/app/test-pmd/testpmd.c b/app/test-pmd/testpmd.c
index 8605e62..1398c6c 100644
--- a/app/test-pmd/testpmd.c
+++ b/app/test-pmd/testpmd.c
@@ -1641,7 +1641,7 @@ check_all_ports_link_status(uint32_t port_mask)
 				continue;
 			}
 			/* clear all_ports_up flag if any link down */
-			if (link.link_status == 0) {
+			if (link.link_status == ETH_LINK_DOWN) {
 				all_ports_up = 0;
 				break;
 			}
diff --git a/app/test/test_pmd_perf.c b/app/test/test_pmd_perf.c
index 48e16c9..59803f7 100644
--- a/app/test/test_pmd_perf.c
+++ b/app/test/test_pmd_perf.c
@@ -192,7 +192,7 @@ check_all_ports_link_status(uint8_t port_num, uint32_t port_mask)
 				continue;
 			}
 			/* clear all_ports_up flag if any link down */
-			if (link.link_status == 0) {
+			if (link.link_status == ETH_LINK_DOWN) {
 				all_ports_up = 0;
 				break;
 			}
diff --git a/app/test/virtual_pmd.c b/app/test/virtual_pmd.c
index a538c8a..b1d40d7 100644
--- a/app/test/virtual_pmd.c
+++ b/app/test/virtual_pmd.c
@@ -79,7 +79,7 @@ static void  virtual_ethdev_stop(struct rte_eth_dev *eth_dev __rte_unused)
 	void *pkt = NULL;
 	struct virtual_ethdev_private *prv = eth_dev->data->dev_private;
 
-	eth_dev->data->dev_link.link_status = 0;
+	eth_dev->data->dev_link.link_status = ETH_LINK_DOWN;
 	eth_dev->data->dev_started = 0;
 	while (rte_ring_dequeue(prv->rx_queue, &pkt) != -ENOENT)
 		rte_pktmbuf_free(pkt);
@@ -199,7 +199,7 @@ virtual_ethdev_link_update_success(struct rte_eth_dev *bonded_eth_dev,
 		int wait_to_complete __rte_unused)
 {
 	if (!bonded_eth_dev->data->dev_started)
-		bonded_eth_dev->data->dev_link.link_status = 0;
+		bonded_eth_dev->data->dev_link.link_status = ETH_LINK_DOWN;
 
 	return 0;
 }
@@ -603,7 +603,7 @@ virtual_ethdev_create(const char *name, struct ether_addr *mac_addr,
 
 	TAILQ_INIT(&(eth_dev->link_intr_cbs));
 
-	eth_dev->data->dev_link.link_status = 0;
+	eth_dev->data->dev_link.link_status = ETH_LINK_DOWN;
 	eth_dev->data->dev_link.link_speed = ETH_LINK_SPEED_10000;
 	eth_dev->data->dev_link.link_duplex = ETH_LINK_FULL_DUPLEX;
 
diff --git a/drivers/net/af_packet/rte_eth_af_packet.c b/drivers/net/af_packet/rte_eth_af_packet.c
index 5544528..dee7b59 100644
--- a/drivers/net/af_packet/rte_eth_af_packet.c
+++ b/drivers/net/af_packet/rte_eth_af_packet.c
@@ -118,7 +118,7 @@ static const char *drivername = "AF_PACKET PMD";
 static struct rte_eth_link pmd_link = {
 	.link_speed = 10000,
 	.link_duplex = ETH_LINK_FULL_DUPLEX,
-	.link_status = 0
+	.link_status = ETH_LINK_DOWN,
 };
 
 static uint16_t
@@ -234,7 +234,7 @@ eth_af_packet_tx(void *queue, struct rte_mbuf **bufs, uint16_t nb_pkts)
 static int
 eth_dev_start(struct rte_eth_dev *dev)
 {
-	dev->data->dev_link.link_status = 1;
+	dev->data->dev_link.link_status = ETH_LINK_UP;
 	return 0;
 }
 
@@ -257,7 +257,7 @@ eth_dev_stop(struct rte_eth_dev *dev)
 			close(sockfd);
 	}
 
-	dev->data->dev_link.link_status = 0;
+	dev->data->dev_link.link_status = ETH_LINK_DOWN;
 }
 
 static int
diff --git a/drivers/net/bnx2x/bnx2x_ethdev.c b/drivers/net/bnx2x/bnx2x_ethdev.c
index 7e5be08..a3c6c01 100644
--- a/drivers/net/bnx2x/bnx2x_ethdev.c
+++ b/drivers/net/bnx2x/bnx2x_ethdev.c
@@ -266,7 +266,7 @@ bnx2xvf_dev_link_update(struct rte_eth_dev *dev, __rte_unused int wait_to_comple
 	if (sc->old_bulletin.valid_bitmap & (1 << CHANNEL_DOWN)) {
 		PMD_DRV_LOG(ERR, "PF indicated channel is down."
 				"VF device is no longer operational");
-		dev->data->dev_link.link_status = 0;
+		dev->data->dev_link.link_status = ETH_LINK_DOWN;
 	}
 
 	return old_link_status == dev->data->dev_link.link_status ? -1 : 0;
diff --git a/drivers/net/bnx2x/elink.c b/drivers/net/bnx2x/elink.c
index da2366e..b9149b8 100644
--- a/drivers/net/bnx2x/elink.c
+++ b/drivers/net/bnx2x/elink.c
@@ -6312,7 +6312,7 @@ elink_status_t elink_link_update(struct elink_params * params,
 	for (phy_index = ELINK_INT_PHY; phy_index < params->num_phys;
 	     phy_index++) {
 		phy_vars[phy_index].flow_ctrl = 0;
-		phy_vars[phy_index].link_status = 0;
+		phy_vars[phy_index].link_status = ETH_LINK_DOWN;
 		phy_vars[phy_index].line_speed = 0;
 		phy_vars[phy_index].duplex = DUPLEX_FULL;
 		phy_vars[phy_index].phy_link_up = 0;
diff --git a/drivers/net/bonding/rte_eth_bond_api.c b/drivers/net/bonding/rte_eth_bond_api.c
index d473ac2..e9247b5 100644
--- a/drivers/net/bonding/rte_eth_bond_api.c
+++ b/drivers/net/bonding/rte_eth_bond_api.c
@@ -205,7 +205,7 @@ rte_eth_bond_create(const char *name, uint8_t mode, uint8_t socket_id)
 
 	TAILQ_INIT(&(eth_dev->link_intr_cbs));
 
-	eth_dev->data->dev_link.link_status = 0;
+	eth_dev->data->dev_link.link_status = ETH_LINK_DOWN;
 
 	eth_dev->data->mac_addrs = rte_zmalloc_socket(name, ETHER_ADDR_LEN, 0,
 			socket_id);
@@ -420,7 +420,7 @@ __eth_bond_slave_add_lock_free(uint8_t bonded_port_id, uint8_t slave_port_id)
 	if (bonded_eth_dev->data->dev_started) {
 		rte_eth_link_get_nowait(slave_port_id, &link_props);
 
-		 if (link_props.link_status == 1) {
+		 if (link_props.link_status == ETH_LINK_UP) {
 			if (internals->active_slave_count == 0 &&
 			    !internals->user_defined_primary_port)
 				bond_ethdev_primary_set(internals,
diff --git a/drivers/net/bonding/rte_eth_bond_pmd.c b/drivers/net/bonding/rte_eth_bond_pmd.c
index fb26d35..684f285 100644
--- a/drivers/net/bonding/rte_eth_bond_pmd.c
+++ b/drivers/net/bonding/rte_eth_bond_pmd.c
@@ -1506,7 +1506,7 @@ bond_ethdev_start(struct rte_eth_dev *eth_dev)
 		return -1;
 	}
 
-	eth_dev->data->dev_link.link_status = 0;
+	eth_dev->data->dev_link.link_status = ETH_LINK_DOWN;
 	eth_dev->data->dev_started = 1;
 
 	internals = eth_dev->data->dev_private;
@@ -1623,7 +1623,7 @@ bond_ethdev_stop(struct rte_eth_dev *eth_dev)
 	internals->active_slave_count = 0;
 	internals->link_status_polling_enabled = 0;
 
-	eth_dev->data->dev_link.link_status = 0;
+	eth_dev->data->dev_link.link_status = ETH_LINK_DOWN;
 	eth_dev->data->dev_started = 0;
 }
 
@@ -1789,7 +1789,7 @@ bond_ethdev_link_update(struct rte_eth_dev *bonded_eth_dev,
 
 	if (!bonded_eth_dev->data->dev_started ||
 		internals->active_slave_count == 0) {
-		bonded_eth_dev->data->dev_link.link_status = 0;
+		bonded_eth_dev->data->dev_link.link_status = ETH_LINK_DOWN;
 		return 0;
 	} else {
 		struct rte_eth_dev *slave_eth_dev;
@@ -1800,7 +1800,7 @@ bond_ethdev_link_update(struct rte_eth_dev *bonded_eth_dev,
 
 			(*slave_eth_dev->dev_ops->link_update)(slave_eth_dev,
 					wait_to_complete);
-			if (slave_eth_dev->data->dev_link.link_status == 1) {
+			if (slave_eth_dev->data->dev_link.link_status == ETH_LINK_UP) {
 				link_up = 1;
 				break;
 			}
@@ -1969,7 +1969,7 @@ bond_ethdev_lsc_event_callback(uint8_t port_id, enum rte_eth_event_type type,
 		/* if no active slave ports then set this port to be primary port */
 		if (internals->active_slave_count < 1) {
 			/* If first active slave, then change link status */
-			bonded_eth_dev->data->dev_link.link_status = 1;
+			bonded_eth_dev->data->dev_link.link_status = ETH_LINK_UP;
 			internals->current_primary_port = port_id;
 			lsc_flag = 1;
 
@@ -1997,7 +1997,7 @@ bond_ethdev_lsc_event_callback(uint8_t port_id, enum rte_eth_event_type type,
 		 * link properties */
 		if (internals->active_slave_count < 1) {
 			lsc_flag = 1;
-			bonded_eth_dev->data->dev_link.link_status = 0;
+			bonded_eth_dev->data->dev_link.link_status = ETH_LINK_DOWN;
 
 			link_properties_reset(bonded_eth_dev);
 		}
diff --git a/drivers/net/e1000/em_ethdev.c b/drivers/net/e1000/em_ethdev.c
index 9b5e1af..9c50674 100644
--- a/drivers/net/e1000/em_ethdev.c
+++ b/drivers/net/e1000/em_ethdev.c
@@ -1102,14 +1102,14 @@ eth_em_link_update(struct rte_eth_dev *dev, int wait_to_complete)
 	old = link;
 
 	/* Now we check if a transition has happened */
-	if (link_check && (link.link_status == 0)) {
+	if (link_check && (link.link_status == ETH_LINK_DOWN)) {
 		hw->mac.ops.get_link_up_info(hw, &link.link_speed,
 			&link.link_duplex);
-		link.link_status = 1;
-	} else if (!link_check && (link.link_status == 1)) {
+		link.link_status = ETH_LINK_UP;
+	} else if (!link_check && (link.link_status == ETH_LINK_UP)) {
 		link.link_speed = 0;
 		link.link_duplex = 0;
-		link.link_status = 0;
+		link.link_status = ETH_LINK_DOWN;
 	}
 	rte_em_dev_atomic_write_link_status(dev, &link);
 
diff --git a/drivers/net/e1000/igb_ethdev.c b/drivers/net/e1000/igb_ethdev.c
index bd0ae26..045fc63 100644
--- a/drivers/net/e1000/igb_ethdev.c
+++ b/drivers/net/e1000/igb_ethdev.c
@@ -2059,11 +2059,11 @@ eth_igb_link_update(struct rte_eth_dev *dev, int wait_to_complete)
 	if (link_check) {
 		hw->mac.ops.get_link_up_info(hw, &link.link_speed,
 					  &link.link_duplex);
-		link.link_status = 1;
+		link.link_status = ETH_LINK_UP;
 	} else if (!link_check) {
 		link.link_speed = 0;
 		link.link_duplex = 0;
-		link.link_status = 0;
+		link.link_status = ETH_LINK_DOWN;
 	}
 	rte_igb_dev_atomic_write_link_status(dev, &link);
 
diff --git a/drivers/net/fm10k/fm10k_ethdev.c b/drivers/net/fm10k/fm10k_ethdev.c
index b03c802..b76e9e5 100644
--- a/drivers/net/fm10k/fm10k_ethdev.c
+++ b/drivers/net/fm10k/fm10k_ethdev.c
@@ -1251,7 +1251,7 @@ fm10k_link_update(struct rte_eth_dev *dev,
 	 * is no 50Gbps Ethernet. */
 	dev->data->dev_link.link_speed  = 0;
 	dev->data->dev_link.link_duplex = ETH_LINK_FULL_DUPLEX;
-	dev->data->dev_link.link_status = 1;
+	dev->data->dev_link.link_status = ETH_LINK_UP;
 
 	return 0;
 }
diff --git a/drivers/net/i40e/i40e_ethdev_vf.c b/drivers/net/i40e/i40e_ethdev_vf.c
index a13d9cc..91df13b 100644
--- a/drivers/net/i40e/i40e_ethdev_vf.c
+++ b/drivers/net/i40e/i40e_ethdev_vf.c
@@ -2127,7 +2127,7 @@ i40evf_dev_link_update(struct rte_eth_dev *dev,
 		/* Always assume it's up, for Linux driver PF host */
 		new_link.link_duplex = ETH_LINK_AUTONEG_DUPLEX;
 		new_link.link_speed  = ETH_LINK_SPEED_10000;
-		new_link.link_status = 1;
+		new_link.link_status = ETH_LINK_UP;
 	}
 	i40evf_dev_atomic_write_link_status(dev, &new_link);
 
diff --git a/drivers/net/ixgbe/ixgbe_ethdev.c b/drivers/net/ixgbe/ixgbe_ethdev.c
index 78524b2..8bcd0d8 100644
--- a/drivers/net/ixgbe/ixgbe_ethdev.c
+++ b/drivers/net/ixgbe/ixgbe_ethdev.c
@@ -3064,7 +3064,7 @@ ixgbe_dev_link_update(struct rte_eth_dev *dev, int wait_to_complete)
 	int link_up;
 	int diag;
 
-	link.link_status = 0;
+	link.link_status = ETH_LINK_DOWN;
 	link.link_speed = 0;
 	link.link_duplex = 0;
 	memset(&old, 0, sizeof(old));
@@ -3093,7 +3093,7 @@ ixgbe_dev_link_update(struct rte_eth_dev *dev, int wait_to_complete)
 			return -1;
 		return 0;
 	}
-	link.link_status = 1;
+	link.link_status = ETH_LINK_UP;
 	link.link_duplex = ETH_LINK_FULL_DUPLEX;
 
 	switch (link_speed) {
diff --git a/drivers/net/mpipe/mpipe_tilegx.c b/drivers/net/mpipe/mpipe_tilegx.c
index 7180e5a..d93ab7e 100644
--- a/drivers/net/mpipe/mpipe_tilegx.c
+++ b/drivers/net/mpipe/mpipe_tilegx.c
@@ -397,11 +397,11 @@ mpipe_link_update(struct rte_eth_dev *dev, int wait_to_complete)
 		if (speed == GXIO_MPIPE_LINK_1G) {
 			new.link_speed = ETH_LINK_SPEED_1000;
 			new.link_duplex = ETH_LINK_FULL_DUPLEX;
-			new.link_status = 1;
+			new.link_status = ETH_LINK_UP;
 		} else if (speed == GXIO_MPIPE_LINK_10G) {
 			new.link_speed = ETH_LINK_SPEED_10000;
 			new.link_duplex = ETH_LINK_FULL_DUPLEX;
-			new.link_status = 1;
+			new.link_status = ETH_LINK_UP;
 		}
 
 		rc = mpipe_link_compare(&old, &new);
@@ -848,9 +848,9 @@ mpipe_start(struct rte_eth_dev *dev)
 
 	/* Start xmit/recv on queues. */
 	for (queue = 0; queue < priv->nb_tx_queues; queue++)
-		mpipe_tx_queue(priv, queue)->q.link_status = 1;
+		mpipe_tx_queue(priv, queue)->q.link_status = ETH_LINK_UP;
 	for (queue = 0; queue < priv->nb_rx_queues; queue++)
-		mpipe_rx_queue(priv, queue)->q.link_status = 1;
+		mpipe_rx_queue(priv, queue)->q.link_status = ETH_LINK_UP;
 	priv->running = 1;
 
 	return 0;
@@ -865,9 +865,9 @@ mpipe_stop(struct rte_eth_dev *dev)
 	int rc;
 
 	for (queue = 0; queue < priv->nb_tx_queues; queue++)
-		mpipe_tx_queue(priv, queue)->q.link_status = 0;
+		mpipe_tx_queue(priv, queue)->q.link_status = ETH_LINK_DOWN;
 	for (queue = 0; queue < priv->nb_rx_queues; queue++)
-		mpipe_rx_queue(priv, queue)->q.link_status = 0;
+		mpipe_rx_queue(priv, queue)->q.link_status = ETH_LINK_DOWN;
 
 	/* Make sure the link_status writes land. */
 	rte_wmb();
diff --git a/drivers/net/nfp/nfp_net.c b/drivers/net/nfp/nfp_net.c
index f12288c..0044897 100644
--- a/drivers/net/nfp/nfp_net.c
+++ b/drivers/net/nfp/nfp_net.c
@@ -817,7 +817,7 @@ nfp_net_link_update(struct rte_eth_dev *dev, __rte_unused int wait_to_complete)
 	memset(&link, 0, sizeof(struct rte_eth_link));
 
 	if (nn_link_status & NFP_NET_CFG_STS_LINK)
-		link.link_status = 1;
+		link.link_status = ETH_LINK_UP;
 
 	link.link_duplex = ETH_LINK_FULL_DUPLEX;
 	/* Other cards can limit the tx and rx rate per VF */
diff --git a/drivers/net/null/rte_eth_null.c b/drivers/net/null/rte_eth_null.c
index 1c354ad..6adea91 100644
--- a/drivers/net/null/rte_eth_null.c
+++ b/drivers/net/null/rte_eth_null.c
@@ -91,7 +91,7 @@ static const char *drivername = "Null PMD";
 static struct rte_eth_link pmd_link = {
 	.link_speed = 10000,
 	.link_duplex = ETH_LINK_FULL_DUPLEX,
-	.link_status = 0
+	.link_status = ETH_LINK_DOWN,
 };
 
 static uint16_t
@@ -199,7 +199,7 @@ eth_dev_start(struct rte_eth_dev *dev)
 	if (dev == NULL)
 		return -EINVAL;
 
-	dev->data->dev_link.link_status = 1;
+	dev->data->dev_link.link_status = ETH_LINK_UP;
 	return 0;
 }
 
@@ -209,7 +209,7 @@ eth_dev_stop(struct rte_eth_dev *dev)
 	if (dev == NULL)
 		return;
 
-	dev->data->dev_link.link_status = 0;
+	dev->data->dev_link.link_status = ETH_LINK_DOWN;
 }
 
 static int
diff --git a/drivers/net/pcap/rte_eth_pcap.c b/drivers/net/pcap/rte_eth_pcap.c
index 5202086..b90c725 100644
--- a/drivers/net/pcap/rte_eth_pcap.c
+++ b/drivers/net/pcap/rte_eth_pcap.c
@@ -125,7 +125,7 @@ static const char *drivername = "Pcap PMD";
 static struct rte_eth_link pmd_link = {
 		.link_speed = 10000,
 		.link_duplex = ETH_LINK_FULL_DUPLEX,
-		.link_status = 0
+		.link_status = ETH_LINK_DOWN,
 };
 
 static int
@@ -428,7 +428,7 @@ eth_dev_start(struct rte_eth_dev *dev)
 
 status_up:
 
-	dev->data->dev_link.link_status = 1;
+	dev->data->dev_link.link_status = ETH_LINK_UP;
 	return 0;
 }
 
@@ -479,7 +479,7 @@ eth_dev_stop(struct rte_eth_dev *dev)
 	}
 
 status_down:
-	dev->data->dev_link.link_status = 0;
+	dev->data->dev_link.link_status = ETH_LINK_DOWN;
 }
 
 static int
diff --git a/drivers/net/ring/rte_eth_ring.c b/drivers/net/ring/rte_eth_ring.c
index ba19cd7..4335c6a 100644
--- a/drivers/net/ring/rte_eth_ring.c
+++ b/drivers/net/ring/rte_eth_ring.c
@@ -79,7 +79,7 @@ static const char *drivername = "Rings PMD";
 static struct rte_eth_link pmd_link = {
 		.link_speed = 10000,
 		.link_duplex = ETH_LINK_FULL_DUPLEX,
-		.link_status = 0
+		.link_status = ETH_LINK_DOWN,
 };
 
 static uint16_t
@@ -119,27 +119,27 @@ eth_dev_configure(struct rte_eth_dev *dev __rte_unused) { return 0; }
 static int
 eth_dev_start(struct rte_eth_dev *dev)
 {
-	dev->data->dev_link.link_status = 1;
+	dev->data->dev_link.link_status = ETH_LINK_UP;
 	return 0;
 }
 
 static void
 eth_dev_stop(struct rte_eth_dev *dev)
 {
-	dev->data->dev_link.link_status = 0;
+	dev->data->dev_link.link_status = ETH_LINK_DOWN;
 }
 
 static int
 eth_dev_set_link_down(struct rte_eth_dev *dev)
 {
-	dev->data->dev_link.link_status = 0;
+	dev->data->dev_link.link_status = ETH_LINK_DOWN;
 	return 0;
 }
 
 static int
 eth_dev_set_link_up(struct rte_eth_dev *dev)
 {
-	dev->data->dev_link.link_status = 1;
+	dev->data->dev_link.link_status = ETH_LINK_UP;
 	return 0;
 }
 
diff --git a/drivers/net/szedata2/rte_eth_szedata2.c b/drivers/net/szedata2/rte_eth_szedata2.c
index 1d6a600..47aa7e3 100644
--- a/drivers/net/szedata2/rte_eth_szedata2.c
+++ b/drivers/net/szedata2/rte_eth_szedata2.c
@@ -1172,7 +1172,7 @@ eth_link_update(struct rte_eth_dev *dev,
 	link.link_duplex = ETH_LINK_FULL_DUPLEX;
 
 	link.link_status = (cgmii_ibuf_is_enabled(ibuf) &&
-			cgmii_ibuf_is_link_up(ibuf)) ? 1 : 0;
+			cgmii_ibuf_is_link_up(ibuf)) ? ETH_LINK_UP : ETH_LINK_DOWN;
 
 	rte_atomic64_cmpset((uint64_t *)dev_link, *(uint64_t *)dev_link,
 			*(uint64_t *)link_ptr);
diff --git a/drivers/net/vhost/rte_eth_vhost.c b/drivers/net/vhost/rte_eth_vhost.c
index ec19c22..4cc6bec 100644
--- a/drivers/net/vhost/rte_eth_vhost.c
+++ b/drivers/net/vhost/rte_eth_vhost.c
@@ -110,7 +110,7 @@ static pthread_t session_th;
 static struct rte_eth_link pmd_link = {
 		.link_speed = 10000,
 		.link_duplex = ETH_LINK_FULL_DUPLEX,
-		.link_status = 0
+		.link_status = ETH_LINK_DOWN
 };
 
 struct rte_vhost_vring_state {
@@ -265,7 +265,7 @@ new_device(struct virtio_net *dev)
 
 	dev->flags |= VIRTIO_DEV_RUNNING;
 	dev->priv = eth_dev;
-	eth_dev->data->dev_link.link_status = 1;
+	eth_dev->data->dev_link.link_status = ETH_LINK_UP;
 
 	for (i = 0; i < eth_dev->data->nb_rx_queues; i++) {
 		vq = eth_dev->data->rx_queues[i];
@@ -323,7 +323,7 @@ destroy_device(volatile struct virtio_net *dev)
 			rte_pause();
 	}
 
-	eth_dev->data->dev_link.link_status = 0;
+	eth_dev->data->dev_link.link_status = ETH_LINK_DOWN;
 
 	dev->priv = NULL;
 	dev->flags &= ~VIRTIO_DEV_RUNNING;
diff --git a/drivers/net/virtio/virtio_ethdev.c b/drivers/net/virtio/virtio_ethdev.c
index 86c96c9..3ebc221 100644
--- a/drivers/net/virtio/virtio_ethdev.c
+++ b/drivers/net/virtio/virtio_ethdev.c
@@ -1410,16 +1410,16 @@ virtio_dev_link_update(struct rte_eth_dev *dev, __rte_unused int wait_to_complet
 				offsetof(struct virtio_net_config, status),
 				&status, sizeof(status));
 		if ((status & VIRTIO_NET_S_LINK_UP) == 0) {
-			link.link_status = 0;
+			link.link_status = ETH_LINK_DOWN;
 			PMD_INIT_LOG(DEBUG, "Port %d is down",
 				     dev->data->port_id);
 		} else {
-			link.link_status = 1;
+			link.link_status = ETH_LINK_UP;
 			PMD_INIT_LOG(DEBUG, "Port %d is up",
 				     dev->data->port_id);
 		}
 	} else {
-		link.link_status = 1;   /* Link up */
+		link.link_status = ETH_LINK_UP;
 	}
 	virtio_dev_atomic_write_link_status(dev, &link);
 
diff --git a/drivers/net/vmxnet3/vmxnet3_ethdev.c b/drivers/net/vmxnet3/vmxnet3_ethdev.c
index b0588ef..b492837 100644
--- a/drivers/net/vmxnet3/vmxnet3_ethdev.c
+++ b/drivers/net/vmxnet3/vmxnet3_ethdev.c
@@ -776,7 +776,7 @@ vmxnet3_dev_link_update(struct rte_eth_dev *dev, __attribute__((unused)) int wai
 	ret = VMXNET3_READ_BAR1_REG(hw, VMXNET3_REG_CMD);
 
 	if (ret & 0x1) {
-		link.link_status = 1;
+		link.link_status = ETH_LINK_UP;
 		link.link_duplex = ETH_LINK_FULL_DUPLEX;
 		link.link_speed = ETH_LINK_SPEED_10000;
 	}
diff --git a/drivers/net/xenvirt/rte_eth_xenvirt.c b/drivers/net/xenvirt/rte_eth_xenvirt.c
index 3f31806..9453a06 100644
--- a/drivers/net/xenvirt/rte_eth_xenvirt.c
+++ b/drivers/net/xenvirt/rte_eth_xenvirt.c
@@ -72,7 +72,7 @@ static const char *drivername = "xen virtio PMD";
 static struct rte_eth_link pmd_link = {
 		.link_speed = 10000,
 		.link_duplex = ETH_LINK_FULL_DUPLEX,
-		.link_status = 0
+		.link_status = ETH_LINK_DOWN,
 };
 
 static void
@@ -290,7 +290,7 @@ eth_dev_start(struct rte_eth_dev *dev)
 	struct pmd_internals *pi = (struct pmd_internals *)dev->data->dev_private;
 	int rv;
 
-	dev->data->dev_link.link_status = 1;
+	dev->data->dev_link.link_status = ETH_LINK_UP;
 	while (!virtqueue_full(rxvq)) {
 		m = rte_rxmbuf_alloc(rxvq->mpool);
 		if (m == NULL)
@@ -318,7 +318,7 @@ eth_dev_stop(struct rte_eth_dev *dev)
 {
 	struct pmd_internals *pi = (struct pmd_internals *)dev->data->dev_private;
 
-	dev->data->dev_link.link_status = 0;
+	dev->data->dev_link.link_status = ETH_LINK_DOWN;
 	dev_stop_notify(pi->virtio_idx);
 }
 
diff --git a/examples/exception_path/main.c b/examples/exception_path/main.c
index b3fe170..bec9804 100644
--- a/examples/exception_path/main.c
+++ b/examples/exception_path/main.c
@@ -485,7 +485,7 @@ check_all_ports_link_status(uint8_t port_num, uint32_t port_mask)
 				continue;
 			}
 			/* clear all_ports_up flag if any link down */
-			if (link.link_status == 0) {
+			if (link.link_status == ETH_LINK_DOWN) {
 				all_ports_up = 0;
 				break;
 			}
diff --git a/examples/ip_fragmentation/main.c b/examples/ip_fragmentation/main.c
index 8021702..81a4918 100644
--- a/examples/ip_fragmentation/main.c
+++ b/examples/ip_fragmentation/main.c
@@ -631,7 +631,7 @@ check_all_ports_link_status(uint8_t port_num, uint32_t port_mask)
 				continue;
 			}
 			/* clear all_ports_up flag if any link down */
-			if (link.link_status == 0) {
+			if (link.link_status == ETH_LINK_DOWN) {
 				all_ports_up = 0;
 				break;
 			}
diff --git a/examples/ip_pipeline/init.c b/examples/ip_pipeline/init.c
index e59a6b4..83422e8 100644
--- a/examples/ip_pipeline/init.c
+++ b/examples/ip_pipeline/init.c
@@ -856,7 +856,7 @@ app_check_link(struct app_params *app)
 			link_params.link_speed / 1000,
 			link_params.link_status ? "UP" : "DOWN");
 
-		if (link_params.link_status == 0)
+		if (link_params.link_status == ETH_LINK_DOWN)
 			all_links_up = 0;
 	}
 
diff --git a/examples/ip_reassembly/main.c b/examples/ip_reassembly/main.c
index 19ec46c..c27e735 100644
--- a/examples/ip_reassembly/main.c
+++ b/examples/ip_reassembly/main.c
@@ -763,7 +763,7 @@ check_all_ports_link_status(uint8_t port_num, uint32_t port_mask)
 				continue;
 			}
 			/* clear all_ports_up flag if any link down */
-			if (link.link_status == 0) {
+			if (link.link_status == ETH_LINK_DOWN) {
 				all_ports_up = 0;
 				break;
 			}
diff --git a/examples/ipsec-secgw/ipsec-secgw.c b/examples/ipsec-secgw/ipsec-secgw.c
index 1d6c81b..00ab2d8 100644
--- a/examples/ipsec-secgw/ipsec-secgw.c
+++ b/examples/ipsec-secgw/ipsec-secgw.c
@@ -947,7 +947,7 @@ check_all_ports_link_status(uint8_t port_num, uint32_t port_mask)
 				continue;
 			}
 			/* clear all_ports_up flag if any link down */
-			if (link.link_status == 0) {
+			if (link.link_status == ETH_LINK_DOWN) {
 				all_ports_up = 0;
 				break;
 			}
diff --git a/examples/ipv4_multicast/main.c b/examples/ipv4_multicast/main.c
index 5dbea1a..96b4157 100644
--- a/examples/ipv4_multicast/main.c
+++ b/examples/ipv4_multicast/main.c
@@ -642,7 +642,7 @@ check_all_ports_link_status(uint8_t port_num, uint32_t port_mask)
 				continue;
 			}
 			/* clear all_ports_up flag if any link down */
-			if (link.link_status == 0) {
+			if (link.link_status == ETH_LINK_DOWN) {
 				all_ports_up = 0;
 				break;
 			}
diff --git a/examples/kni/main.c b/examples/kni/main.c
index 6d434ad..a5297f2 100644
--- a/examples/kni/main.c
+++ b/examples/kni/main.c
@@ -670,7 +670,7 @@ check_all_ports_link_status(uint8_t port_num, uint32_t port_mask)
 				continue;
 			}
 			/* clear all_ports_up flag if any link down */
-			if (link.link_status == 0) {
+			if (link.link_status == ETH_LINK_DOWN) {
 				all_ports_up = 0;
 				break;
 			}
diff --git a/examples/l2fwd-crypto/main.c b/examples/l2fwd-crypto/main.c
index 09a07d3..35171d1 100644
--- a/examples/l2fwd-crypto/main.c
+++ b/examples/l2fwd-crypto/main.c
@@ -1440,7 +1440,7 @@ check_all_ports_link_status(uint8_t port_num, uint32_t port_mask)
 				continue;
 			}
 			/* clear all_ports_up flag if any link down */
-			if (link.link_status == 0) {
+			if (link.link_status == ETH_LINK_DOWN) {
 				all_ports_up = 0;
 				break;
 			}
diff --git a/examples/l2fwd-ivshmem/host/host.c b/examples/l2fwd-ivshmem/host/host.c
index 6e6ed5e..4bd7c41 100644
--- a/examples/l2fwd-ivshmem/host/host.c
+++ b/examples/l2fwd-ivshmem/host/host.c
@@ -371,7 +371,7 @@ check_all_ports_link_status(uint8_t port_num, uint32_t port_mask)
 				continue;
 			}
 			/* clear all_ports_up flag if any link down */
-			if (link.link_status == 0) {
+			if (link.link_status == ETH_LINK_DOWN) {
 				all_ports_up = 0;
 				break;
 			}
diff --git a/examples/l2fwd-jobstats/main.c b/examples/l2fwd-jobstats/main.c
index d1e9bf7..9f3a77d 100644
--- a/examples/l2fwd-jobstats/main.c
+++ b/examples/l2fwd-jobstats/main.c
@@ -746,7 +746,7 @@ check_all_ports_link_status(uint8_t port_num, uint32_t port_mask)
 				continue;
 			}
 			/* clear all_ports_up flag if any link down */
-			if (link.link_status == 0) {
+			if (link.link_status == ETH_LINK_DOWN) {
 				all_ports_up = 0;
 				break;
 			}
diff --git a/examples/l2fwd-keepalive/main.c b/examples/l2fwd-keepalive/main.c
index 94b8677..8da89aa 100644
--- a/examples/l2fwd-keepalive/main.c
+++ b/examples/l2fwd-keepalive/main.c
@@ -499,7 +499,7 @@ check_all_ports_link_status(uint8_t port_num, uint32_t port_mask)
 				continue;
 			}
 			/* clear all_ports_up flag if any link down */
-			if (link.link_status == 0) {
+			if (link.link_status == ETH_LINK_DOWN) {
 				all_ports_up = 0;
 				break;
 			}
diff --git a/examples/l2fwd/main.c b/examples/l2fwd/main.c
index e175681..1ad9488 100644
--- a/examples/l2fwd/main.c
+++ b/examples/l2fwd/main.c
@@ -480,7 +480,7 @@ check_all_ports_link_status(uint8_t port_num, uint32_t port_mask)
 				continue;
 			}
 			/* clear all_ports_up flag if any link down */
-			if (link.link_status == 0) {
+			if (link.link_status == ETH_LINK_DOWN) {
 				all_ports_up = 0;
 				break;
 			}
diff --git a/examples/l3fwd-acl/main.c b/examples/l3fwd-acl/main.c
index 3a895b7..621872f 100644
--- a/examples/l3fwd-acl/main.c
+++ b/examples/l3fwd-acl/main.c
@@ -1858,7 +1858,7 @@ check_all_ports_link_status(uint8_t port_num, uint32_t port_mask)
 				continue;
 			}
 			/* clear all_ports_up flag if any link down */
-			if (link.link_status == 0) {
+			if (link.link_status == ETH_LINK_DOWN) {
 				all_ports_up = 0;
 				break;
 			}
diff --git a/examples/l3fwd-power/main.c b/examples/l3fwd-power/main.c
index e7ebe30..5934efe 100644
--- a/examples/l3fwd-power/main.c
+++ b/examples/l3fwd-power/main.c
@@ -1509,7 +1509,7 @@ check_all_ports_link_status(uint8_t port_num, uint32_t port_mask)
 				continue;
 			}
 			/* clear all_ports_up flag if any link down */
-			if (link.link_status == 0) {
+			if (link.link_status == ETH_LINK_DOWN) {
 				all_ports_up = 0;
 				break;
 			}
diff --git a/examples/l3fwd/main.c b/examples/l3fwd/main.c
index 92fda3b..bf6d885 100644
--- a/examples/l3fwd/main.c
+++ b/examples/l3fwd/main.c
@@ -769,7 +769,7 @@ check_all_ports_link_status(uint8_t port_num, uint32_t port_mask)
 				continue;
 			}
 			/* clear all_ports_up flag if any link down */
-			if (link.link_status == 0) {
+			if (link.link_status == ETH_LINK_DOWN) {
 				all_ports_up = 0;
 				break;
 			}
diff --git a/examples/link_status_interrupt/main.c b/examples/link_status_interrupt/main.c
index cbc29bc..9981598 100644
--- a/examples/link_status_interrupt/main.c
+++ b/examples/link_status_interrupt/main.c
@@ -523,7 +523,7 @@ check_all_ports_link_status(uint8_t port_num, uint32_t port_mask)
 				continue;
 			}
 			/* clear all_ports_up flag if any link down */
-			if (link.link_status == 0) {
+			if (link.link_status == ETH_LINK_DOWN) {
 				all_ports_up = 0;
 				break;
 			}
diff --git a/examples/load_balancer/init.c b/examples/load_balancer/init.c
index a96d778..e07850b 100644
--- a/examples/load_balancer/init.c
+++ b/examples/load_balancer/init.c
@@ -395,7 +395,7 @@ check_all_ports_link_status(uint8_t port_num, uint32_t port_mask)
 				continue;
 			}
 			/* clear all_ports_up flag if any link down */
-			if (link.link_status == 0) {
+			if (link.link_status == ETH_LINK_DOWN) {
 				all_ports_up = 0;
 				break;
 			}
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 1078ffd..ecb61c6 100644
--- a/examples/multi_process/client_server_mp/mp_server/init.c
+++ b/examples/multi_process/client_server_mp/mp_server/init.c
@@ -226,7 +226,7 @@ check_all_ports_link_status(uint8_t port_num, uint32_t port_mask)
 				continue;
 			}
 			/* clear all_ports_up flag if any link down */
-			if (link.link_status == 0) {
+			if (link.link_status == ETH_LINK_DOWN) {
 				all_ports_up = 0;
 				break;
 			}
diff --git a/examples/multi_process/l2fwd_fork/main.c b/examples/multi_process/l2fwd_fork/main.c
index aebf531..2dc8b82 100644
--- a/examples/multi_process/l2fwd_fork/main.c
+++ b/examples/multi_process/l2fwd_fork/main.c
@@ -900,7 +900,7 @@ check_all_ports_link_status(uint8_t port_num, uint32_t port_mask)
 				continue;
 			}
 			/* clear all_ports_up flag if any link down */
-			if (link.link_status == 0) {
+			if (link.link_status == ETH_LINK_DOWN) {
 				all_ports_up = 0;
 				break;
 			}
diff --git a/examples/multi_process/symmetric_mp/main.c b/examples/multi_process/symmetric_mp/main.c
index 72bad54..6bbff07 100644
--- a/examples/multi_process/symmetric_mp/main.c
+++ b/examples/multi_process/symmetric_mp/main.c
@@ -388,7 +388,7 @@ check_all_ports_link_status(uint8_t port_num, uint32_t port_mask)
 				continue;
 			}
 			/* clear all_ports_up flag if any link down */
-			if (link.link_status == 0) {
+			if (link.link_status == ETH_LINK_DOWN) {
 				all_ports_up = 0;
 				break;
 			}
diff --git a/examples/performance-thread/l3fwd-thread/main.c b/examples/performance-thread/l3fwd-thread/main.c
index 61c023e..15c0a4d 100644
--- a/examples/performance-thread/l3fwd-thread/main.c
+++ b/examples/performance-thread/l3fwd-thread/main.c
@@ -3408,7 +3408,7 @@ check_all_ports_link_status(uint8_t port_num, uint32_t port_mask)
 				continue;
 			}
 			/* clear all_ports_up flag if any link down */
-			if (link.link_status == 0) {
+			if (link.link_status == ETH_LINK_DOWN) {
 				all_ports_up = 0;
 				break;
 			}
diff --git a/lib/librte_ether/rte_ethdev.h b/lib/librte_ether/rte_ethdev.h
index e7de34a..c5a215a 100644
--- a/lib/librte_ether/rte_ethdev.h
+++ b/lib/librte_ether/rte_ethdev.h
@@ -247,7 +247,7 @@ struct rte_eth_stats {
 struct rte_eth_link {
 	uint16_t link_speed;      /**< ETH_LINK_SPEED_[10, 100, 1000, 10000] */
 	uint16_t link_duplex;     /**< ETH_LINK_[HALF_DUPLEX, FULL_DUPLEX] */
-	uint8_t  link_status : 1; /**< 1 -> link up, 0 -> link down */
+	uint8_t  link_status : 1; /**< ETH_LINK_[DOWN/UP] */
 }__attribute__((aligned(8)));     /**< aligned for atomic64 read/write */
 
 #define ETH_LINK_SPEED_AUTONEG  0       /**< Auto-negotiate link speed. */
@@ -259,9 +259,12 @@ struct rte_eth_link {
 #define ETH_LINK_SPEED_20G      20000   /**< 20 gigabits/second. */
 #define ETH_LINK_SPEED_40G      40000   /**< 40 gigabits/second. */
 
+/* Utility constants */
 #define ETH_LINK_AUTONEG_DUPLEX 0       /**< Auto-negotiate duplex. */
 #define ETH_LINK_HALF_DUPLEX    1       /**< Half-duplex connection. */
 #define ETH_LINK_FULL_DUPLEX    2       /**< Full-duplex connection. */
+#define ETH_LINK_DOWN           0 /**< Link is down. */
+#define ETH_LINK_UP             1 /**< Link is up. */
 
 /**
  * A structure used to configure the ring threshold registers of an RX/TX
-- 
2.1.4

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

* [PATCH v14 2/8] ethdev: use constants for link duplex
  2016-03-31 22:12                 ` [PATCH v14 " Marc Sune
  2016-03-31 22:12                   ` [PATCH v14 1/8] ethdev: use constants for link state Marc Sune
@ 2016-03-31 22:12                   ` Marc Sune
  2016-03-31 22:12                   ` [PATCH v14 3/8] app/testpmd: move speed and duplex parsing in a function Marc Sune
                                     ` (6 subsequent siblings)
  8 siblings, 0 replies; 167+ messages in thread
From: Marc Sune @ 2016-03-31 22:12 UTC (permalink / raw)
  To: Thomas Monjalon, Xu, Qian Q, Xing, Beilei, dev, Ananyev,
	Konstantin, Lu, Wenzhuo, Richardson, Bruce, Glynn, Michael J
  Cc: Marc Sune

Some duplex values are replaced from 0 to half-duplex when link is down.

Some drivers are still using their own constants for duplex modes.

Signed-off-by: Marc Sune <marcdevel@gmail.com>
---
 drivers/net/e1000/em_ethdev.c      | 2 +-
 drivers/net/e1000/igb_ethdev.c     | 2 +-
 drivers/net/ixgbe/ixgbe_ethdev.c   | 2 +-
 drivers/net/virtio/virtio_ethdev.c | 2 +-
 drivers/net/virtio/virtio_ethdev.h | 2 --
 lib/librte_ether/rte_ethdev.h      | 2 +-
 6 files changed, 5 insertions(+), 7 deletions(-)

diff --git a/drivers/net/e1000/em_ethdev.c b/drivers/net/e1000/em_ethdev.c
index 9c50674..b78ac04 100644
--- a/drivers/net/e1000/em_ethdev.c
+++ b/drivers/net/e1000/em_ethdev.c
@@ -1108,7 +1108,7 @@ eth_em_link_update(struct rte_eth_dev *dev, int wait_to_complete)
 		link.link_status = ETH_LINK_UP;
 	} else if (!link_check && (link.link_status == ETH_LINK_UP)) {
 		link.link_speed = 0;
-		link.link_duplex = 0;
+		link.link_duplex = ETH_LINK_HALF_DUPLEX;
 		link.link_status = ETH_LINK_DOWN;
 	}
 	rte_em_dev_atomic_write_link_status(dev, &link);
diff --git a/drivers/net/e1000/igb_ethdev.c b/drivers/net/e1000/igb_ethdev.c
index 045fc63..4dfa7e3 100644
--- a/drivers/net/e1000/igb_ethdev.c
+++ b/drivers/net/e1000/igb_ethdev.c
@@ -2062,7 +2062,7 @@ eth_igb_link_update(struct rte_eth_dev *dev, int wait_to_complete)
 		link.link_status = ETH_LINK_UP;
 	} else if (!link_check) {
 		link.link_speed = 0;
-		link.link_duplex = 0;
+		link.link_duplex = ETH_LINK_HALF_DUPLEX;
 		link.link_status = ETH_LINK_DOWN;
 	}
 	rte_igb_dev_atomic_write_link_status(dev, &link);
diff --git a/drivers/net/ixgbe/ixgbe_ethdev.c b/drivers/net/ixgbe/ixgbe_ethdev.c
index 8bcd0d8..5721882 100644
--- a/drivers/net/ixgbe/ixgbe_ethdev.c
+++ b/drivers/net/ixgbe/ixgbe_ethdev.c
@@ -3066,7 +3066,7 @@ ixgbe_dev_link_update(struct rte_eth_dev *dev, int wait_to_complete)
 
 	link.link_status = ETH_LINK_DOWN;
 	link.link_speed = 0;
-	link.link_duplex = 0;
+	link.link_duplex = ETH_LINK_HALF_DUPLEX;
 	memset(&old, 0, sizeof(old));
 	rte_ixgbe_dev_atomic_read_link_status(dev, &old);
 
diff --git a/drivers/net/virtio/virtio_ethdev.c b/drivers/net/virtio/virtio_ethdev.c
index 3ebc221..63a368a 100644
--- a/drivers/net/virtio/virtio_ethdev.c
+++ b/drivers/net/virtio/virtio_ethdev.c
@@ -1401,7 +1401,7 @@ virtio_dev_link_update(struct rte_eth_dev *dev, __rte_unused int wait_to_complet
 	memset(&link, 0, sizeof(link));
 	virtio_dev_atomic_read_link_status(dev, &link);
 	old = link;
-	link.link_duplex = FULL_DUPLEX;
+	link.link_duplex = ETH_LINK_FULL_DUPLEX;
 	link.link_speed  = SPEED_10G;
 
 	if (vtpci_with_feature(hw, VIRTIO_NET_F_STATUS)) {
diff --git a/drivers/net/virtio/virtio_ethdev.h b/drivers/net/virtio/virtio_ethdev.h
index fed9571..66423a0 100644
--- a/drivers/net/virtio/virtio_ethdev.h
+++ b/drivers/net/virtio/virtio_ethdev.h
@@ -42,8 +42,6 @@
 #define SPEED_100	100
 #define SPEED_1000	1000
 #define SPEED_10G	10000
-#define HALF_DUPLEX	1
-#define FULL_DUPLEX	2
 
 #ifndef PAGE_SIZE
 #define PAGE_SIZE 4096
diff --git a/lib/librte_ether/rte_ethdev.h b/lib/librte_ether/rte_ethdev.h
index c5a215a..2d13f92 100644
--- a/lib/librte_ether/rte_ethdev.h
+++ b/lib/librte_ether/rte_ethdev.h
@@ -246,7 +246,7 @@ struct rte_eth_stats {
  */
 struct rte_eth_link {
 	uint16_t link_speed;      /**< ETH_LINK_SPEED_[10, 100, 1000, 10000] */
-	uint16_t link_duplex;     /**< ETH_LINK_[HALF_DUPLEX, FULL_DUPLEX] */
+	uint16_t link_duplex;     /**< ETH_LINK_[HALF/FULL]_DUPLEX */
 	uint8_t  link_status : 1; /**< ETH_LINK_[DOWN/UP] */
 }__attribute__((aligned(8)));     /**< aligned for atomic64 read/write */
 
-- 
2.1.4

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

* [PATCH v14 3/8] app/testpmd: move speed and duplex parsing in a function
  2016-03-31 22:12                 ` [PATCH v14 " Marc Sune
  2016-03-31 22:12                   ` [PATCH v14 1/8] ethdev: use constants for link state Marc Sune
  2016-03-31 22:12                   ` [PATCH v14 2/8] ethdev: use constants for link duplex Marc Sune
@ 2016-03-31 22:12                   ` Marc Sune
  2016-03-31 22:12                   ` [PATCH v14 4/8] ethdev: rename link speed constants Marc Sune
                                     ` (5 subsequent siblings)
  8 siblings, 0 replies; 167+ messages in thread
From: Marc Sune @ 2016-03-31 22:12 UTC (permalink / raw)
  To: Thomas Monjalon, Xu, Qian Q, Xing, Beilei, dev, Ananyev,
	Konstantin, Lu, Wenzhuo, Richardson, Bruce, Glynn, Michael J
  Cc: Marc Sune

The code for checking and parsing speed/duplex was duplicated.
The new function is also checking the speed/duplex combination.

Signed-off-by: Marc Sune <marcdevel@gmail.com>
---
 app/test-pmd/cmdline.c | 99 ++++++++++++++++++++++++--------------------------
 1 file changed, 47 insertions(+), 52 deletions(-)

diff --git a/app/test-pmd/cmdline.c b/app/test-pmd/cmdline.c
index 93203f4..eb7bbb4 100644
--- a/app/test-pmd/cmdline.c
+++ b/app/test-pmd/cmdline.c
@@ -988,6 +988,49 @@ struct cmd_config_speed_all {
 	cmdline_fixed_string_t value2;
 };
 
+static int
+parse_and_check_speed_duplex(char *speedstr, char *duplexstr, uint16_t *speed)
+{
+
+	int duplex;
+
+	if (!strcmp(duplexstr, "half")) {
+		duplex = ETH_LINK_HALF_DUPLEX;
+	} else if (!strcmp(duplexstr, "full")) {
+		duplex = ETH_LINK_FULL_DUPLEX;
+	} else if (!strcmp(duplexstr, "auto")) {
+		duplex = ETH_LINK_FULL_DUPLEX;
+	} else {
+		printf("Unknown duplex parameter\n");
+		return -1;
+	}
+
+	if (!strcmp(speedstr, "10")) {
+		*speed = ETH_LINK_SPEED_10;
+	} else if (!strcmp(speedstr, "100")) {
+		*speed = ETH_LINK_SPEED_100;
+	} else {
+		if (duplex != ETH_LINK_FULL_DUPLEX) {
+			printf("Invalid speed/duplex parameters\n");
+			return -1;
+		}
+		if (!strcmp(speedstr, "1000")) {
+			*speed = ETH_LINK_SPEED_1000;
+		} else if (!strcmp(speedstr, "10000")) {
+			*speed = ETH_LINK_SPEED_10G;
+		} else if (!strcmp(speedstr, "40000")) {
+			*speed = ETH_LINK_SPEED_40G;
+		} else if (!strcmp(speedstr, "auto")) {
+			*speed = ETH_LINK_SPEED_AUTONEG;
+		} else {
+			printf("Unknown speed parameter\n");
+			return -1;
+		}
+	}
+
+	return 0;
+}
+
 static void
 cmd_config_speed_all_parsed(void *parsed_result,
 			__attribute__((unused)) struct cmdline *cl,
@@ -1003,33 +1046,9 @@ cmd_config_speed_all_parsed(void *parsed_result,
 		return;
 	}
 
-	if (!strcmp(res->value1, "10"))
-		link_speed = ETH_LINK_SPEED_10;
-	else if (!strcmp(res->value1, "100"))
-		link_speed = ETH_LINK_SPEED_100;
-	else if (!strcmp(res->value1, "1000"))
-		link_speed = ETH_LINK_SPEED_1000;
-	else if (!strcmp(res->value1, "10000"))
-		link_speed = ETH_LINK_SPEED_10G;
-	else if (!strcmp(res->value1, "40000"))
-		link_speed = ETH_LINK_SPEED_40G;
-	else if (!strcmp(res->value1, "auto"))
-		link_speed = ETH_LINK_SPEED_AUTONEG;
-	else {
-		printf("Unknown parameter\n");
+	if (parse_and_check_speed_duplex(res->value1, res->value2,
+			&link_speed) < 0)
 		return;
-	}
-
-	if (!strcmp(res->value2, "half"))
-		link_duplex = ETH_LINK_HALF_DUPLEX;
-	else if (!strcmp(res->value2, "full"))
-		link_duplex = ETH_LINK_FULL_DUPLEX;
-	else if (!strcmp(res->value2, "auto"))
-		link_duplex = ETH_LINK_AUTONEG_DUPLEX;
-	else {
-		printf("Unknown parameter\n");
-		return;
-	}
 
 	FOREACH_PORT(pid, ports) {
 		ports[pid].dev_conf.link_speed = link_speed;
@@ -1102,33 +1121,9 @@ cmd_config_speed_specific_parsed(void *parsed_result,
 	if (port_id_is_invalid(res->id, ENABLED_WARN))
 		return;
 
-	if (!strcmp(res->value1, "10"))
-		link_speed = ETH_LINK_SPEED_10;
-	else if (!strcmp(res->value1, "100"))
-		link_speed = ETH_LINK_SPEED_100;
-	else if (!strcmp(res->value1, "1000"))
-		link_speed = ETH_LINK_SPEED_1000;
-	else if (!strcmp(res->value1, "10000"))
-		link_speed = ETH_LINK_SPEED_10000;
-	else if (!strcmp(res->value1, "40000"))
-		link_speed = ETH_LINK_SPEED_40G;
-	else if (!strcmp(res->value1, "auto"))
-		link_speed = ETH_LINK_SPEED_AUTONEG;
-	else {
-		printf("Unknown parameter\n");
-		return;
-	}
-
-	if (!strcmp(res->value2, "half"))
-		link_duplex = ETH_LINK_HALF_DUPLEX;
-	else if (!strcmp(res->value2, "full"))
-		link_duplex = ETH_LINK_FULL_DUPLEX;
-	else if (!strcmp(res->value2, "auto"))
-		link_duplex = ETH_LINK_AUTONEG_DUPLEX;
-	else {
-		printf("Unknown parameter\n");
+	if (parse_and_check_speed_duplex(res->value1, res->value2,
+			&link_speed) < 0)
 		return;
-	}
 
 	ports[res->id].dev_conf.link_speed = link_speed;
 	ports[res->id].dev_conf.link_duplex = link_duplex;
-- 
2.1.4

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

* [PATCH v14 4/8] ethdev: rename link speed constants
  2016-03-31 22:12                 ` [PATCH v14 " Marc Sune
                                     ` (2 preceding siblings ...)
  2016-03-31 22:12                   ` [PATCH v14 3/8] app/testpmd: move speed and duplex parsing in a function Marc Sune
@ 2016-03-31 22:12                   ` Marc Sune
  2016-03-31 22:12                   ` [PATCH v14 5/8] ethdev: add speed capabilities Marc Sune
                                     ` (4 subsequent siblings)
  8 siblings, 0 replies; 167+ messages in thread
From: Marc Sune @ 2016-03-31 22:12 UTC (permalink / raw)
  To: Thomas Monjalon, Xu, Qian Q, Xing, Beilei, dev, Ananyev,
	Konstantin, Lu, Wenzhuo, Richardson, Bruce, Glynn, Michael J
  Cc: Marc Sune

The speed numbers ETH_LINK_SPEED_ are renamed ETH_SPEED_NUM_.
The prefix ETH_LINK_SPEED_ is kept for AUTONEG and will be used
for bit flags in next patch.

Signed-off-by: Marc Sune <marcdevel@gmail.com>
---
 app/test-pmd/cmdline.c                    | 10 +++++-----
 app/test/virtual_pmd.c                    |  2 +-
 drivers/net/af_packet/rte_eth_af_packet.c |  2 +-
 drivers/net/bonding/rte_eth_bond_8023ad.c | 12 ++++++------
 drivers/net/cxgbe/base/t4_hw.c            |  8 ++++----
 drivers/net/e1000/em_ethdev.c             |  8 ++++----
 drivers/net/e1000/igb_ethdev.c            |  8 ++++----
 drivers/net/ena/ena_ethdev.c              |  2 +-
 drivers/net/i40e/i40e_ethdev.c            | 30 +++++++++++++++---------------
 drivers/net/i40e/i40e_ethdev_vf.c         |  2 +-
 drivers/net/ixgbe/ixgbe_ethdev.c          | 22 +++++++++++-----------
 drivers/net/mpipe/mpipe_tilegx.c          |  4 ++--
 drivers/net/nfp/nfp_net.c                 |  2 +-
 drivers/net/null/rte_eth_null.c           |  2 +-
 drivers/net/pcap/rte_eth_pcap.c           |  2 +-
 drivers/net/ring/rte_eth_ring.c           |  2 +-
 drivers/net/szedata2/rte_eth_szedata2.c   |  8 ++++----
 drivers/net/vmxnet3/vmxnet3_ethdev.c      |  2 +-
 drivers/net/xenvirt/rte_eth_xenvirt.c     |  2 +-
 lib/librte_ether/rte_ethdev.h             | 29 ++++++++++++++++++-----------
 20 files changed, 83 insertions(+), 76 deletions(-)

diff --git a/app/test-pmd/cmdline.c b/app/test-pmd/cmdline.c
index eb7bbb4..815b53b 100644
--- a/app/test-pmd/cmdline.c
+++ b/app/test-pmd/cmdline.c
@@ -1006,20 +1006,20 @@ parse_and_check_speed_duplex(char *speedstr, char *duplexstr, uint16_t *speed)
 	}
 
 	if (!strcmp(speedstr, "10")) {
-		*speed = ETH_LINK_SPEED_10;
+		*speed = ETH_SPEED_NUM_10M;
 	} else if (!strcmp(speedstr, "100")) {
-		*speed = ETH_LINK_SPEED_100;
+		*speed = ETH_SPEED_NUM_100M;
 	} else {
 		if (duplex != ETH_LINK_FULL_DUPLEX) {
 			printf("Invalid speed/duplex parameters\n");
 			return -1;
 		}
 		if (!strcmp(speedstr, "1000")) {
-			*speed = ETH_LINK_SPEED_1000;
+			*speed = ETH_SPEED_NUM_1G;
 		} else if (!strcmp(speedstr, "10000")) {
-			*speed = ETH_LINK_SPEED_10G;
+			*speed = ETH_SPEED_NUM_10G;
 		} else if (!strcmp(speedstr, "40000")) {
-			*speed = ETH_LINK_SPEED_40G;
+			*speed = ETH_SPEED_NUM_40G;
 		} else if (!strcmp(speedstr, "auto")) {
 			*speed = ETH_LINK_SPEED_AUTONEG;
 		} else {
diff --git a/app/test/virtual_pmd.c b/app/test/virtual_pmd.c
index b1d40d7..b4bd2f2 100644
--- a/app/test/virtual_pmd.c
+++ b/app/test/virtual_pmd.c
@@ -604,7 +604,7 @@ virtual_ethdev_create(const char *name, struct ether_addr *mac_addr,
 	TAILQ_INIT(&(eth_dev->link_intr_cbs));
 
 	eth_dev->data->dev_link.link_status = ETH_LINK_DOWN;
-	eth_dev->data->dev_link.link_speed = ETH_LINK_SPEED_10000;
+	eth_dev->data->dev_link.link_speed = ETH_SPEED_NUM_10G;
 	eth_dev->data->dev_link.link_duplex = ETH_LINK_FULL_DUPLEX;
 
 	eth_dev->data->mac_addrs = rte_zmalloc(name, ETHER_ADDR_LEN, 0);
diff --git a/drivers/net/af_packet/rte_eth_af_packet.c b/drivers/net/af_packet/rte_eth_af_packet.c
index dee7b59..641f849 100644
--- a/drivers/net/af_packet/rte_eth_af_packet.c
+++ b/drivers/net/af_packet/rte_eth_af_packet.c
@@ -116,7 +116,7 @@ static const char *valid_arguments[] = {
 static const char *drivername = "AF_PACKET PMD";
 
 static struct rte_eth_link pmd_link = {
-	.link_speed = 10000,
+	.link_speed = ETH_SPEED_NUM_10G,
 	.link_duplex = ETH_LINK_FULL_DUPLEX,
 	.link_status = ETH_LINK_DOWN,
 };
diff --git a/drivers/net/bonding/rte_eth_bond_8023ad.c b/drivers/net/bonding/rte_eth_bond_8023ad.c
index 1b7e93a..ac8306f 100644
--- a/drivers/net/bonding/rte_eth_bond_8023ad.c
+++ b/drivers/net/bonding/rte_eth_bond_8023ad.c
@@ -711,22 +711,22 @@ link_speed_key(uint16_t speed) {
 	case ETH_LINK_SPEED_AUTONEG:
 		key_speed = 0x00;
 		break;
-	case ETH_LINK_SPEED_10:
+	case ETH_SPEED_NUM_10M:
 		key_speed = BOND_LINK_SPEED_KEY_10M;
 		break;
-	case ETH_LINK_SPEED_100:
+	case ETH_SPEED_NUM_100M:
 		key_speed = BOND_LINK_SPEED_KEY_100M;
 		break;
-	case ETH_LINK_SPEED_1000:
+	case ETH_SPEED_NUM_1G:
 		key_speed = BOND_LINK_SPEED_KEY_1000M;
 		break;
-	case ETH_LINK_SPEED_10G:
+	case ETH_SPEED_NUM_10G:
 		key_speed = BOND_LINK_SPEED_KEY_10G;
 		break;
-	case ETH_LINK_SPEED_20G:
+	case ETH_SPEED_NUM_20G:
 		key_speed = BOND_LINK_SPEED_KEY_20G;
 		break;
-	case ETH_LINK_SPEED_40G:
+	case ETH_SPEED_NUM_40G:
 		key_speed = BOND_LINK_SPEED_KEY_40G;
 		break;
 	default:
diff --git a/drivers/net/cxgbe/base/t4_hw.c b/drivers/net/cxgbe/base/t4_hw.c
index 884d2cf..79af806 100644
--- a/drivers/net/cxgbe/base/t4_hw.c
+++ b/drivers/net/cxgbe/base/t4_hw.c
@@ -2159,13 +2159,13 @@ int t4_handle_fw_rpl(struct adapter *adap, const __be64 *rpl)
 		if (stat & F_FW_PORT_CMD_TXPAUSE)
 			fc |= PAUSE_TX;
 		if (stat & V_FW_PORT_CMD_LSPEED(FW_PORT_CAP_SPEED_100M))
-			speed = ETH_LINK_SPEED_100;
+			speed = ETH_SPEED_NUM_100M;
 		else if (stat & V_FW_PORT_CMD_LSPEED(FW_PORT_CAP_SPEED_1G))
-			speed = ETH_LINK_SPEED_1000;
+			speed = ETH_SPEED_NUM_1G;
 		else if (stat & V_FW_PORT_CMD_LSPEED(FW_PORT_CAP_SPEED_10G))
-			speed = ETH_LINK_SPEED_10000;
+			speed = ETH_SPEED_NUM_10G;
 		else if (stat & V_FW_PORT_CMD_LSPEED(FW_PORT_CAP_SPEED_40G))
-			speed = ETH_LINK_SPEED_40G;
+			speed = ETH_SPEED_NUM_40G;
 
 		for_each_port(adap, i) {
 			pi = adap2pinfo(adap, i);
diff --git a/drivers/net/e1000/em_ethdev.c b/drivers/net/e1000/em_ethdev.c
index b78ac04..8e4bd08 100644
--- a/drivers/net/e1000/em_ethdev.c
+++ b/drivers/net/e1000/em_ethdev.c
@@ -625,7 +625,7 @@ eth_em_start(struct rte_eth_dev *dev)
 		else
 			goto error_invalid_config;
 		break;
-	case ETH_LINK_SPEED_10:
+	case ETH_SPEED_NUM_10M:
 		if (dev->data->dev_conf.link_duplex == ETH_LINK_AUTONEG_DUPLEX)
 			hw->phy.autoneg_advertised = E1000_ALL_10_SPEED;
 		else if (dev->data->dev_conf.link_duplex ==
@@ -637,7 +637,7 @@ eth_em_start(struct rte_eth_dev *dev)
 		else
 			goto error_invalid_config;
 		break;
-	case ETH_LINK_SPEED_100:
+	case ETH_SPEED_NUM_100M:
 		if (dev->data->dev_conf.link_duplex == ETH_LINK_AUTONEG_DUPLEX)
 			hw->phy.autoneg_advertised = E1000_ALL_100_SPEED;
 		else if (dev->data->dev_conf.link_duplex ==
@@ -649,7 +649,7 @@ eth_em_start(struct rte_eth_dev *dev)
 		else
 			goto error_invalid_config;
 		break;
-	case ETH_LINK_SPEED_1000:
+	case ETH_SPEED_NUM_1G:
 		if ((dev->data->dev_conf.link_duplex ==
 				ETH_LINK_AUTONEG_DUPLEX) ||
 			(dev->data->dev_conf.link_duplex ==
@@ -658,7 +658,7 @@ eth_em_start(struct rte_eth_dev *dev)
 		else
 			goto error_invalid_config;
 		break;
-	case ETH_LINK_SPEED_10000:
+	case ETH_SPEED_NUM_10G:
 	default:
 		goto error_invalid_config;
 	}
diff --git a/drivers/net/e1000/igb_ethdev.c b/drivers/net/e1000/igb_ethdev.c
index 4dfa7e3..86f25f6 100644
--- a/drivers/net/e1000/igb_ethdev.c
+++ b/drivers/net/e1000/igb_ethdev.c
@@ -1244,7 +1244,7 @@ eth_igb_start(struct rte_eth_dev *dev)
 		else
 			goto error_invalid_config;
 		break;
-	case ETH_LINK_SPEED_10:
+	case ETH_SPEED_NUM_10M:
 		if (dev->data->dev_conf.link_duplex == ETH_LINK_AUTONEG_DUPLEX)
 			hw->phy.autoneg_advertised = E1000_ALL_10_SPEED;
 		else if (dev->data->dev_conf.link_duplex == ETH_LINK_HALF_DUPLEX)
@@ -1254,7 +1254,7 @@ eth_igb_start(struct rte_eth_dev *dev)
 		else
 			goto error_invalid_config;
 		break;
-	case ETH_LINK_SPEED_100:
+	case ETH_SPEED_NUM_100M:
 		if (dev->data->dev_conf.link_duplex == ETH_LINK_AUTONEG_DUPLEX)
 			hw->phy.autoneg_advertised = E1000_ALL_100_SPEED;
 		else if (dev->data->dev_conf.link_duplex == ETH_LINK_HALF_DUPLEX)
@@ -1264,14 +1264,14 @@ eth_igb_start(struct rte_eth_dev *dev)
 		else
 			goto error_invalid_config;
 		break;
-	case ETH_LINK_SPEED_1000:
+	case ETH_SPEED_NUM_1G:
 		if ((dev->data->dev_conf.link_duplex == ETH_LINK_AUTONEG_DUPLEX) ||
 				(dev->data->dev_conf.link_duplex == ETH_LINK_FULL_DUPLEX))
 			hw->phy.autoneg_advertised = ADVERTISE_1000_FULL;
 		else
 			goto error_invalid_config;
 		break;
-	case ETH_LINK_SPEED_10000:
+	case ETH_SPEED_NUM_10G:
 	default:
 		goto error_invalid_config;
 	}
diff --git a/drivers/net/ena/ena_ethdev.c b/drivers/net/ena/ena_ethdev.c
index 325c513..1046286 100644
--- a/drivers/net/ena/ena_ethdev.c
+++ b/drivers/net/ena/ena_ethdev.c
@@ -504,7 +504,7 @@ static int ena_link_update(struct rte_eth_dev *dev,
 	struct rte_eth_link *link = &dev->data->dev_link;
 
 	link->link_status = 1;
-	link->link_speed = ETH_LINK_SPEED_10G;
+	link->link_speed = ETH_SPEED_NUM_10G;
 	link->link_duplex = ETH_LINK_FULL_DUPLEX;
 
 	return 0;
diff --git a/drivers/net/i40e/i40e_ethdev.c b/drivers/net/i40e/i40e_ethdev.c
index 3a6c3aa..988c2de 100644
--- a/drivers/net/i40e/i40e_ethdev.c
+++ b/drivers/net/i40e/i40e_ethdev.c
@@ -1386,19 +1386,19 @@ i40e_parse_link_speed(uint16_t eth_link_speed)
 	uint8_t link_speed = I40E_LINK_SPEED_UNKNOWN;
 
 	switch (eth_link_speed) {
-	case ETH_LINK_SPEED_40G:
+	case ETH_SPEED_NUM_40G:
 		link_speed = I40E_LINK_SPEED_40GB;
 		break;
-	case ETH_LINK_SPEED_20G:
+	case ETH_SPEED_NUM_20G:
 		link_speed = I40E_LINK_SPEED_20GB;
 		break;
-	case ETH_LINK_SPEED_10G:
+	case ETH_SPEED_NUM_10G:
 		link_speed = I40E_LINK_SPEED_10GB;
 		break;
-	case ETH_LINK_SPEED_1000:
+	case ETH_SPEED_NUM_1G:
 		link_speed = I40E_LINK_SPEED_1GB;
 		break;
-	case ETH_LINK_SPEED_100:
+	case ETH_SPEED_NUM_100M:
 		link_speed = I40E_LINK_SPEED_100MB;
 		break;
 	}
@@ -1768,7 +1768,7 @@ i40e_dev_link_update(struct rte_eth_dev *dev,
 		/* Get link status information from hardware */
 		status = i40e_aq_get_link_info(hw, false, &link_status, NULL);
 		if (status != I40E_SUCCESS) {
-			link.link_speed = ETH_LINK_SPEED_100;
+			link.link_speed = ETH_SPEED_NUM_100M;
 			link.link_duplex = ETH_LINK_FULL_DUPLEX;
 			PMD_DRV_LOG(ERR, "Failed to get link info");
 			goto out;
@@ -1790,22 +1790,22 @@ i40e_dev_link_update(struct rte_eth_dev *dev,
 	/* Parse the link status */
 	switch (link_status.link_speed) {
 	case I40E_LINK_SPEED_100MB:
-		link.link_speed = ETH_LINK_SPEED_100;
+		link.link_speed = ETH_SPEED_NUM_100M;
 		break;
 	case I40E_LINK_SPEED_1GB:
-		link.link_speed = ETH_LINK_SPEED_1000;
+		link.link_speed = ETH_SPEED_NUM_1G;
 		break;
 	case I40E_LINK_SPEED_10GB:
-		link.link_speed = ETH_LINK_SPEED_10G;
+		link.link_speed = ETH_SPEED_NUM_10G;
 		break;
 	case I40E_LINK_SPEED_20GB:
-		link.link_speed = ETH_LINK_SPEED_20G;
+		link.link_speed = ETH_SPEED_NUM_20G;
 		break;
 	case I40E_LINK_SPEED_40GB:
-		link.link_speed = ETH_LINK_SPEED_40G;
+		link.link_speed = ETH_SPEED_NUM_40G;
 		break;
 	default:
-		link.link_speed = ETH_LINK_SPEED_100;
+		link.link_speed = ETH_SPEED_NUM_100M;
 		break;
 	}
 
@@ -8158,15 +8158,15 @@ i40e_start_timecounters(struct rte_eth_dev *dev)
 	rte_i40e_dev_atomic_read_link_status(dev, &link);
 
 	switch (link.link_speed) {
-	case ETH_LINK_SPEED_40G:
+	case ETH_SPEED_NUM_40G:
 		tsync_inc_l = I40E_PTP_40GB_INCVAL & 0xFFFFFFFF;
 		tsync_inc_h = I40E_PTP_40GB_INCVAL >> 32;
 		break;
-	case ETH_LINK_SPEED_10G:
+	case ETH_SPEED_NUM_10G:
 		tsync_inc_l = I40E_PTP_10GB_INCVAL & 0xFFFFFFFF;
 		tsync_inc_h = I40E_PTP_10GB_INCVAL >> 32;
 		break;
-	case ETH_LINK_SPEED_1000:
+	case ETH_SPEED_NUM_1G:
 		tsync_inc_l = I40E_PTP_1GB_INCVAL & 0xFFFFFFFF;
 		tsync_inc_h = I40E_PTP_1GB_INCVAL >> 32;
 		break;
diff --git a/drivers/net/i40e/i40e_ethdev_vf.c b/drivers/net/i40e/i40e_ethdev_vf.c
index 91df13b..295dcd2 100644
--- a/drivers/net/i40e/i40e_ethdev_vf.c
+++ b/drivers/net/i40e/i40e_ethdev_vf.c
@@ -2126,7 +2126,7 @@ i40evf_dev_link_update(struct rte_eth_dev *dev,
 	else {
 		/* Always assume it's up, for Linux driver PF host */
 		new_link.link_duplex = ETH_LINK_AUTONEG_DUPLEX;
-		new_link.link_speed  = ETH_LINK_SPEED_10000;
+		new_link.link_speed  = ETH_SPEED_NUM_10G;
 		new_link.link_status = ETH_LINK_UP;
 	}
 	i40evf_dev_atomic_write_link_status(dev, &new_link);
diff --git a/drivers/net/ixgbe/ixgbe_ethdev.c b/drivers/net/ixgbe/ixgbe_ethdev.c
index 5721882..60a9cf4 100644
--- a/drivers/net/ixgbe/ixgbe_ethdev.c
+++ b/drivers/net/ixgbe/ixgbe_ethdev.c
@@ -2204,17 +2204,17 @@ ixgbe_dev_start(struct rte_eth_dev *dev)
 				IXGBE_LINK_SPEED_82599_AUTONEG :
 				IXGBE_LINK_SPEED_82598_AUTONEG;
 		break;
-	case ETH_LINK_SPEED_100:
+	case ETH_SPEED_NUM_100M:
 		/*
 		 * Invalid for 82598 but error will be detected by
 		 * ixgbe_setup_link()
 		 */
 		speed = IXGBE_LINK_SPEED_100_FULL;
 		break;
-	case ETH_LINK_SPEED_1000:
+	case ETH_SPEED_NUM_1G:
 		speed = IXGBE_LINK_SPEED_1GB_FULL;
 		break;
-	case ETH_LINK_SPEED_10000:
+	case ETH_SPEED_NUM_10G:
 		speed = IXGBE_LINK_SPEED_10GB_FULL;
 		break;
 	default:
@@ -3079,7 +3079,7 @@ ixgbe_dev_link_update(struct rte_eth_dev *dev, int wait_to_complete)
 		diag = ixgbe_check_link(hw, &link_speed, &link_up, 1);
 
 	if (diag != 0) {
-		link.link_speed = ETH_LINK_SPEED_100;
+		link.link_speed = ETH_SPEED_NUM_100M;
 		link.link_duplex = ETH_LINK_HALF_DUPLEX;
 		rte_ixgbe_dev_atomic_write_link_status(dev, &link);
 		if (link.link_status == old.link_status)
@@ -3100,19 +3100,19 @@ ixgbe_dev_link_update(struct rte_eth_dev *dev, int wait_to_complete)
 	default:
 	case IXGBE_LINK_SPEED_UNKNOWN:
 		link.link_duplex = ETH_LINK_HALF_DUPLEX;
-		link.link_speed = ETH_LINK_SPEED_100;
+		link.link_speed = ETH_SPEED_NUM_100M;
 		break;
 
 	case IXGBE_LINK_SPEED_100_FULL:
-		link.link_speed = ETH_LINK_SPEED_100;
+		link.link_speed = ETH_SPEED_NUM_100M;
 		break;
 
 	case IXGBE_LINK_SPEED_1GB_FULL:
-		link.link_speed = ETH_LINK_SPEED_1000;
+		link.link_speed = ETH_SPEED_NUM_1G;
 		break;
 
 	case IXGBE_LINK_SPEED_10GB_FULL:
-		link.link_speed = ETH_LINK_SPEED_10000;
+		link.link_speed = ETH_SPEED_NUM_10G;
 		break;
 	}
 	rte_ixgbe_dev_atomic_write_link_status(dev, &link);
@@ -5915,15 +5915,15 @@ ixgbe_start_timecounters(struct rte_eth_dev *dev)
 	rte_ixgbe_dev_atomic_read_link_status(dev, &link);
 
 	switch (link.link_speed) {
-	case ETH_LINK_SPEED_100:
+	case ETH_SPEED_NUM_100M:
 		incval = IXGBE_INCVAL_100;
 		shift = IXGBE_INCVAL_SHIFT_100;
 		break;
-	case ETH_LINK_SPEED_1000:
+	case ETH_SPEED_NUM_1G:
 		incval = IXGBE_INCVAL_1GB;
 		shift = IXGBE_INCVAL_SHIFT_1GB;
 		break;
-	case ETH_LINK_SPEED_10000:
+	case ETH_SPEED_NUM_10G:
 	default:
 		incval = IXGBE_INCVAL_10GB;
 		shift = IXGBE_INCVAL_SHIFT_10GB;
diff --git a/drivers/net/mpipe/mpipe_tilegx.c b/drivers/net/mpipe/mpipe_tilegx.c
index d93ab7e..1a77c7a 100644
--- a/drivers/net/mpipe/mpipe_tilegx.c
+++ b/drivers/net/mpipe/mpipe_tilegx.c
@@ -395,11 +395,11 @@ mpipe_link_update(struct rte_eth_dev *dev, int wait_to_complete)
 		speed = state & GXIO_MPIPE_LINK_SPEED_MASK;
 
 		if (speed == GXIO_MPIPE_LINK_1G) {
-			new.link_speed = ETH_LINK_SPEED_1000;
+			new.link_speed = ETH_SPEED_NUM_1G;
 			new.link_duplex = ETH_LINK_FULL_DUPLEX;
 			new.link_status = ETH_LINK_UP;
 		} else if (speed == GXIO_MPIPE_LINK_10G) {
-			new.link_speed = ETH_LINK_SPEED_10000;
+			new.link_speed = ETH_SPEED_NUM_10G;
 			new.link_duplex = ETH_LINK_FULL_DUPLEX;
 			new.link_status = ETH_LINK_UP;
 		}
diff --git a/drivers/net/nfp/nfp_net.c b/drivers/net/nfp/nfp_net.c
index 0044897..201c38e 100644
--- a/drivers/net/nfp/nfp_net.c
+++ b/drivers/net/nfp/nfp_net.c
@@ -821,7 +821,7 @@ nfp_net_link_update(struct rte_eth_dev *dev, __rte_unused int wait_to_complete)
 
 	link.link_duplex = ETH_LINK_FULL_DUPLEX;
 	/* Other cards can limit the tx and rx rate per VF */
-	link.link_speed = ETH_LINK_SPEED_40G;
+	link.link_speed = ETH_SPEED_NUM_40G;
 
 	if (old.link_status != link.link_status) {
 		nfp_net_dev_atomic_write_link_status(dev, &link);
diff --git a/drivers/net/null/rte_eth_null.c b/drivers/net/null/rte_eth_null.c
index 6adea91..5640585 100644
--- a/drivers/net/null/rte_eth_null.c
+++ b/drivers/net/null/rte_eth_null.c
@@ -89,7 +89,7 @@ struct pmd_internals {
 static struct ether_addr eth_addr = { .addr_bytes = {0} };
 static const char *drivername = "Null PMD";
 static struct rte_eth_link pmd_link = {
-	.link_speed = 10000,
+	.link_speed = ETH_SPEED_NUM_10G,
 	.link_duplex = ETH_LINK_FULL_DUPLEX,
 	.link_status = ETH_LINK_DOWN,
 };
diff --git a/drivers/net/pcap/rte_eth_pcap.c b/drivers/net/pcap/rte_eth_pcap.c
index b90c725..c657951 100644
--- a/drivers/net/pcap/rte_eth_pcap.c
+++ b/drivers/net/pcap/rte_eth_pcap.c
@@ -123,7 +123,7 @@ static int open_single_iface(const char *iface, pcap_t **pcap);
 static struct ether_addr eth_addr = { .addr_bytes = { 0, 0, 0, 0x1, 0x2, 0x3 } };
 static const char *drivername = "Pcap PMD";
 static struct rte_eth_link pmd_link = {
-		.link_speed = 10000,
+		.link_speed = ETH_SPEED_NUM_10G,
 		.link_duplex = ETH_LINK_FULL_DUPLEX,
 		.link_status = ETH_LINK_DOWN,
 };
diff --git a/drivers/net/ring/rte_eth_ring.c b/drivers/net/ring/rte_eth_ring.c
index 4335c6a..58685e9 100644
--- a/drivers/net/ring/rte_eth_ring.c
+++ b/drivers/net/ring/rte_eth_ring.c
@@ -77,7 +77,7 @@ struct pmd_internals {
 
 static const char *drivername = "Rings PMD";
 static struct rte_eth_link pmd_link = {
-		.link_speed = 10000,
+		.link_speed = ETH_SPEED_NUM_10G,
 		.link_duplex = ETH_LINK_FULL_DUPLEX,
 		.link_status = ETH_LINK_DOWN,
 };
diff --git a/drivers/net/szedata2/rte_eth_szedata2.c b/drivers/net/szedata2/rte_eth_szedata2.c
index 47aa7e3..dd1ae9e 100644
--- a/drivers/net/szedata2/rte_eth_szedata2.c
+++ b/drivers/net/szedata2/rte_eth_szedata2.c
@@ -1149,10 +1149,10 @@ eth_link_update(struct rte_eth_dev *dev,
 
 	switch (cgmii_link_speed(ibuf)) {
 	case SZEDATA2_LINK_SPEED_10G:
-		link.link_speed = ETH_LINK_SPEED_10G;
+		link.link_speed = ETH_SPEED_NUM_10G;
 		break;
 	case SZEDATA2_LINK_SPEED_40G:
-		link.link_speed = ETH_LINK_SPEED_40G;
+		link.link_speed = ETH_SPEED_NUM_40G;
 		break;
 	case SZEDATA2_LINK_SPEED_100G:
 		/*
@@ -1161,10 +1161,10 @@ eth_link_update(struct rte_eth_dev *dev,
 		 * will be changed to support 100Gbps speed change
 		 * this value to 100G.
 		 */
-		link.link_speed = ETH_LINK_SPEED_10G;
+		link.link_speed = ETH_SPEED_NUM_10G;
 		break;
 	default:
-		link.link_speed = ETH_LINK_SPEED_10G;
+		link.link_speed = ETH_SPEED_NUM_10G;
 		break;
 	}
 
diff --git a/drivers/net/vmxnet3/vmxnet3_ethdev.c b/drivers/net/vmxnet3/vmxnet3_ethdev.c
index b492837..95d533f 100644
--- a/drivers/net/vmxnet3/vmxnet3_ethdev.c
+++ b/drivers/net/vmxnet3/vmxnet3_ethdev.c
@@ -778,7 +778,7 @@ vmxnet3_dev_link_update(struct rte_eth_dev *dev, __attribute__((unused)) int wai
 	if (ret & 0x1) {
 		link.link_status = ETH_LINK_UP;
 		link.link_duplex = ETH_LINK_FULL_DUPLEX;
-		link.link_speed = ETH_LINK_SPEED_10000;
+		link.link_speed = ETH_SPEED_NUM_10G;
 	}
 
 	vmxnet3_dev_atomic_write_link_status(dev, &link);
diff --git a/drivers/net/xenvirt/rte_eth_xenvirt.c b/drivers/net/xenvirt/rte_eth_xenvirt.c
index 9453a06..77d3ba1 100644
--- a/drivers/net/xenvirt/rte_eth_xenvirt.c
+++ b/drivers/net/xenvirt/rte_eth_xenvirt.c
@@ -70,7 +70,7 @@ static int virtio_idx = 0;
 static const char *drivername = "xen virtio PMD";
 
 static struct rte_eth_link pmd_link = {
-		.link_speed = 10000,
+		.link_speed = ETH_SPEED_NUM_10G,
 		.link_duplex = ETH_LINK_FULL_DUPLEX,
 		.link_status = ETH_LINK_DOWN,
 };
diff --git a/lib/librte_ether/rte_ethdev.h b/lib/librte_ether/rte_ethdev.h
index 2d13f92..bc7d607 100644
--- a/lib/librte_ether/rte_ethdev.h
+++ b/lib/librte_ether/rte_ethdev.h
@@ -242,23 +242,30 @@ struct rte_eth_stats {
 };
 
 /**
+ * Ethernet numeric link speeds in Mbps
+ */
+#define ETH_LINK_SPEED_AUTONEG     0 /**< Auto-negotiate link speed. */
+#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 */
+
+/**
  * A structure used to retrieve link-level information of an Ethernet port.
  */
 struct rte_eth_link {
-	uint16_t link_speed;      /**< ETH_LINK_SPEED_[10, 100, 1000, 10000] */
+	uint16_t link_speed;      /**< ETH_SPEED_NUM_ */
 	uint16_t link_duplex;     /**< ETH_LINK_[HALF/FULL]_DUPLEX */
 	uint8_t  link_status : 1; /**< ETH_LINK_[DOWN/UP] */
 }__attribute__((aligned(8)));     /**< aligned for atomic64 read/write */
 
-#define ETH_LINK_SPEED_AUTONEG  0       /**< Auto-negotiate link speed. */
-#define ETH_LINK_SPEED_10       10      /**< 10 megabits/second. */
-#define ETH_LINK_SPEED_100      100     /**< 100 megabits/second. */
-#define ETH_LINK_SPEED_1000     1000    /**< 1 gigabits/second. */
-#define ETH_LINK_SPEED_10000    10000   /**< 10 gigabits/second. */
-#define ETH_LINK_SPEED_10G      10000   /**< alias of 10 gigabits/second. */
-#define ETH_LINK_SPEED_20G      20000   /**< 20 gigabits/second. */
-#define ETH_LINK_SPEED_40G      40000   /**< 40 gigabits/second. */
-
 /* Utility constants */
 #define ETH_LINK_AUTONEG_DUPLEX 0       /**< Auto-negotiate duplex. */
 #define ETH_LINK_HALF_DUPLEX    1       /**< Half-duplex connection. */
@@ -779,7 +786,7 @@ struct rte_intr_conf {
  */
 struct rte_eth_conf {
 	uint16_t link_speed;
-	/**< ETH_LINK_SPEED_10[0|00|000], or 0 for autonegotation */
+	/**< ETH_SPEED_NUM_ or 0 for autonegotiation */
 	uint16_t link_duplex;
 	/**< ETH_LINK_[HALF_DUPLEX|FULL_DUPLEX], or 0 for autonegotation */
 	struct rte_eth_rxmode rxmode; /**< Port RX configuration. */
-- 
2.1.4

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

* [PATCH v14 5/8] ethdev: add speed capabilities
  2016-03-31 22:12                 ` [PATCH v14 " Marc Sune
                                     ` (3 preceding siblings ...)
  2016-03-31 22:12                   ` [PATCH v14 4/8] ethdev: rename link speed constants Marc Sune
@ 2016-03-31 22:12                   ` Marc Sune
  2016-03-31 22:12                   ` [PATCH v14 6/8] ethdev: redesign link speed config Marc Sune
                                     ` (3 subsequent siblings)
  8 siblings, 0 replies; 167+ messages in thread
From: Marc Sune @ 2016-03-31 22:12 UTC (permalink / raw)
  To: Thomas Monjalon, Xu, Qian Q, Xing, Beilei, dev, Ananyev,
	Konstantin, Lu, Wenzhuo, Richardson, Bruce, Glynn, Michael J
  Cc: Marc Sune

The speed capabilities of a device can be retrieved with
rte_eth_dev_info_get().

The new field speed_capa is initialized in the drivers without
taking care of device characteristics in this patch.
When the capabilities of a driver are accurate, the table in
overview.rst must be filled.

Signed-off-by: Marc Sune <marcdevel@gmail.com>
---
 doc/guides/nics/overview.rst           |  1 +
 doc/guides/rel_notes/release_16_04.rst |  8 ++++++++
 drivers/net/bnx2x/bnx2x_ethdev.c       |  1 +
 drivers/net/cxgbe/cxgbe_ethdev.c       |  1 +
 drivers/net/e1000/em_ethdev.c          |  4 ++++
 drivers/net/e1000/igb_ethdev.c         |  4 ++++
 drivers/net/ena/ena_ethdev.c           |  9 +++++++++
 drivers/net/fm10k/fm10k_ethdev.c       |  4 ++++
 drivers/net/i40e/i40e_ethdev.c         |  8 ++++++++
 drivers/net/ixgbe/ixgbe_ethdev.c       |  8 ++++++++
 drivers/net/mlx4/mlx4.c                |  6 ++++++
 drivers/net/mlx5/mlx5_ethdev.c         |  8 ++++++++
 drivers/net/nfp/nfp_net.c              |  2 ++
 lib/librte_ether/rte_ethdev.h          | 21 +++++++++++++++++++++
 14 files changed, 85 insertions(+)

diff --git a/doc/guides/nics/overview.rst b/doc/guides/nics/overview.rst
index 542479a..62f1868 100644
--- a/doc/guides/nics/overview.rst
+++ b/doc/guides/nics/overview.rst
@@ -86,6 +86,7 @@ Most of these differences are summarized below.
                                           e   e       e   e   e                     e
                                           c   c       c   c   c                     c
    ==================== = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
+   speed capabilities
    link status                  X       X X                                   X X
    link status event                    X X                                     X
    queue status event                                                           X
diff --git a/doc/guides/rel_notes/release_16_04.rst b/doc/guides/rel_notes/release_16_04.rst
index 79d76e1..9e7b0b7 100644
--- a/doc/guides/rel_notes/release_16_04.rst
+++ b/doc/guides/rel_notes/release_16_04.rst
@@ -47,6 +47,11 @@ This section should contain new features added in this release. Sample format:
   A new function ``rte_pktmbuf_alloc_bulk()`` has been added to allow the user
   to allocate a bulk of mbufs.
 
+* **Added device link speed capabilities.**
+
+  The structure ``rte_eth_dev_info`` has now a ``speed_capa`` bitmap, which
+  allows the application to know the supported speeds of each device.
+
 * **Added new poll-mode driver for Amazon Elastic Network Adapters (ENA).**
 
   The driver operates variety of ENA adapters through feature negotiation
@@ -456,6 +461,9 @@ This section should contain API changes. Sample format:
   All drivers are now counting the missed packets only once, i.e. drivers will
   not increment ierrors anymore for missed packets.
 
+* The ethdev structure ``rte_eth_dev_info`` was changed to support device
+  speed capabilities.
+
 * The functions ``rte_eth_dev_udp_tunnel_add`` and ``rte_eth_dev_udp_tunnel_delete``
   have been renamed into ``rte_eth_dev_udp_tunnel_port_add`` and
   ``rte_eth_dev_udp_tunnel_port_delete``.
diff --git a/drivers/net/bnx2x/bnx2x_ethdev.c b/drivers/net/bnx2x/bnx2x_ethdev.c
index a3c6c01..897081f 100644
--- a/drivers/net/bnx2x/bnx2x_ethdev.c
+++ b/drivers/net/bnx2x/bnx2x_ethdev.c
@@ -327,6 +327,7 @@ bnx2x_dev_infos_get(struct rte_eth_dev *dev, __rte_unused struct rte_eth_dev_inf
 	dev_info->min_rx_bufsize = BNX2X_MIN_RX_BUF_SIZE;
 	dev_info->max_rx_pktlen  = BNX2X_MAX_RX_PKT_LEN;
 	dev_info->max_mac_addrs  = BNX2X_MAX_MAC_ADDRS;
+	dev_info->speed_capa = ETH_LINK_SPEED_10G | ETH_LINK_SPEED_20G;
 }
 
 static void
diff --git a/drivers/net/cxgbe/cxgbe_ethdev.c b/drivers/net/cxgbe/cxgbe_ethdev.c
index 8845c76..bb134e5 100644
--- a/drivers/net/cxgbe/cxgbe_ethdev.c
+++ b/drivers/net/cxgbe/cxgbe_ethdev.c
@@ -171,6 +171,7 @@ static void cxgbe_dev_info_get(struct rte_eth_dev *eth_dev,
 
 	device_info->rx_desc_lim = cxgbe_desc_lim;
 	device_info->tx_desc_lim = cxgbe_desc_lim;
+	device_info->speed_capa = ETH_LINK_SPEED_10G | ETH_LINK_SPEED_40G;
 }
 
 static void cxgbe_dev_promiscuous_enable(struct rte_eth_dev *eth_dev)
diff --git a/drivers/net/e1000/em_ethdev.c b/drivers/net/e1000/em_ethdev.c
index 8e4bd08..890c5c3 100644
--- a/drivers/net/e1000/em_ethdev.c
+++ b/drivers/net/e1000/em_ethdev.c
@@ -1055,6 +1055,10 @@ eth_em_infos_get(struct rte_eth_dev *dev, struct rte_eth_dev_info *dev_info)
 		.nb_min = E1000_MIN_RING_DESC,
 		.nb_align = EM_TXD_ALIGN,
 	};
+
+	dev_info->speed_capa = ETH_LINK_SPEED_10M_HD | ETH_LINK_SPEED_10M |
+			ETH_LINK_SPEED_100M_HD | ETH_LINK_SPEED_100M |
+			ETH_LINK_SPEED_1G;
 }
 
 /* return 0 means link status changed, -1 means not changed */
diff --git a/drivers/net/e1000/igb_ethdev.c b/drivers/net/e1000/igb_ethdev.c
index 86f25f6..95d1711 100644
--- a/drivers/net/e1000/igb_ethdev.c
+++ b/drivers/net/e1000/igb_ethdev.c
@@ -1921,6 +1921,10 @@ eth_igb_infos_get(struct rte_eth_dev *dev, struct rte_eth_dev_info *dev_info)
 
 	dev_info->rx_desc_lim = rx_desc_lim;
 	dev_info->tx_desc_lim = tx_desc_lim;
+
+	dev_info->speed_capa = ETH_LINK_SPEED_10M_HD | ETH_LINK_SPEED_10M |
+			ETH_LINK_SPEED_100M_HD | ETH_LINK_SPEED_100M |
+			ETH_LINK_SPEED_1G;
 }
 
 static const uint32_t *
diff --git a/drivers/net/ena/ena_ethdev.c b/drivers/net/ena/ena_ethdev.c
index 1046286..4e403af 100644
--- a/drivers/net/ena/ena_ethdev.c
+++ b/drivers/net/ena/ena_ethdev.c
@@ -1170,6 +1170,15 @@ static void ena_infos_get(struct rte_eth_dev *dev,
 	ena_dev = &adapter->ena_dev;
 	ena_assert_msg(ena_dev != NULL, "Uninitialized device");
 
+	dev_info->speed_capa =
+			ETH_LINK_SPEED_1G   |
+			ETH_LINK_SPEED_2_5G |
+			ETH_LINK_SPEED_5G   |
+			ETH_LINK_SPEED_10G  |
+			ETH_LINK_SPEED_25G  |
+			ETH_LINK_SPEED_40G  |
+			ETH_LINK_SPEED_50G;
+
 	/* Get supported features from HW */
 	rc = ena_com_get_dev_attr_feat(ena_dev, &feat);
 	if (unlikely(rc)) {
diff --git a/drivers/net/fm10k/fm10k_ethdev.c b/drivers/net/fm10k/fm10k_ethdev.c
index b76e9e5..2be297a 100644
--- a/drivers/net/fm10k/fm10k_ethdev.c
+++ b/drivers/net/fm10k/fm10k_ethdev.c
@@ -1412,6 +1412,10 @@ fm10k_dev_infos_get(struct rte_eth_dev *dev,
 		.nb_min = FM10K_MIN_TX_DESC,
 		.nb_align = FM10K_MULT_TX_DESC,
 	};
+
+	dev_info->speed_capa = ETH_LINK_SPEED_1G | ETH_LINK_SPEED_2_5G |
+			ETH_LINK_SPEED_10G | ETH_LINK_SPEED_25G |
+			ETH_LINK_SPEED_40G;
 }
 
 #ifdef RTE_LIBRTE_FM10K_RX_OLFLAGS_ENABLE
diff --git a/drivers/net/i40e/i40e_ethdev.c b/drivers/net/i40e/i40e_ethdev.c
index 988c2de..cde314d 100644
--- a/drivers/net/i40e/i40e_ethdev.c
+++ b/drivers/net/i40e/i40e_ethdev.c
@@ -2287,6 +2287,7 @@ static void
 i40e_dev_info_get(struct rte_eth_dev *dev, struct rte_eth_dev_info *dev_info)
 {
 	struct i40e_pf *pf = I40E_DEV_PRIVATE_TO_PF(dev->data->dev_private);
+	struct i40e_hw *hw = I40E_DEV_PRIVATE_TO_HW(dev->data->dev_private);
 	struct i40e_vsi *vsi = pf->main_vsi;
 
 	dev_info->max_rx_queues = vsi->nb_qps;
@@ -2358,6 +2359,13 @@ i40e_dev_info_get(struct rte_eth_dev *dev, struct rte_eth_dev_info *dev_info)
 		dev_info->max_rx_queues += dev_info->vmdq_queue_num;
 		dev_info->max_tx_queues += dev_info->vmdq_queue_num;
 	}
+
+	if (i40e_is_40G_device(hw->device_id))
+		/* For XL710 */
+		dev_info->speed_capa = ETH_LINK_SPEED_1G | ETH_LINK_SPEED_10G;
+	else
+		/* For X710 */
+		dev_info->speed_capa = ETH_LINK_SPEED_10G | ETH_LINK_SPEED_40G;
 }
 
 static int
diff --git a/drivers/net/ixgbe/ixgbe_ethdev.c b/drivers/net/ixgbe/ixgbe_ethdev.c
index 60a9cf4..894278f 100644
--- a/drivers/net/ixgbe/ixgbe_ethdev.c
+++ b/drivers/net/ixgbe/ixgbe_ethdev.c
@@ -2965,6 +2965,14 @@ ixgbe_dev_info_get(struct rte_eth_dev *dev, struct rte_eth_dev_info *dev_info)
 	dev_info->hash_key_size = IXGBE_HKEY_MAX_INDEX * sizeof(uint32_t);
 	dev_info->reta_size = ixgbe_reta_size_get(hw->mac.type);
 	dev_info->flow_type_rss_offloads = IXGBE_RSS_OFFLOAD_ALL;
+
+	dev_info->speed_capa = ETH_LINK_SPEED_1G | ETH_LINK_SPEED_10G;
+	if (hw->mac.type == ixgbe_mac_X540 ||
+	    hw->mac.type == ixgbe_mac_X540_vf ||
+	    hw->mac.type == ixgbe_mac_X550 ||
+	    hw->mac.type == ixgbe_mac_X550_vf) {
+		dev_info->speed_capa |= ETH_LINK_SPEED_100M;
+	}
 }
 
 static const uint32_t *
diff --git a/drivers/net/mlx4/mlx4.c b/drivers/net/mlx4/mlx4.c
index 5cc995f..ed2f488 100644
--- a/drivers/net/mlx4/mlx4.c
+++ b/drivers/net/mlx4/mlx4.c
@@ -4328,6 +4328,12 @@ mlx4_dev_infos_get(struct rte_eth_dev *dev, struct rte_eth_dev_info *info)
 		 0);
 	if (priv_get_ifname(priv, &ifname) == 0)
 		info->if_index = if_nametoindex(ifname);
+	info->speed_capa =
+			ETH_LINK_SPEED_1G |
+			ETH_LINK_SPEED_10G |
+			ETH_LINK_SPEED_20G |
+			ETH_LINK_SPEED_40G |
+			ETH_LINK_SPEED_56G;
 	priv_unlock(priv);
 }
 
diff --git a/drivers/net/mlx5/mlx5_ethdev.c b/drivers/net/mlx5/mlx5_ethdev.c
index 58bfa16..d7a0eea 100644
--- a/drivers/net/mlx5/mlx5_ethdev.c
+++ b/drivers/net/mlx5/mlx5_ethdev.c
@@ -559,6 +559,14 @@ mlx5_dev_infos_get(struct rte_eth_dev *dev, struct rte_eth_dev_info *info)
 	 * size if it is not fixed.
 	 * The API should be updated to solve this problem. */
 	info->reta_size = priv->ind_table_max_size;
+	info->speed_capa =
+			ETH_LINK_SPEED_1G |
+			ETH_LINK_SPEED_10G |
+			ETH_LINK_SPEED_20G |
+			ETH_LINK_SPEED_25G |
+			ETH_LINK_SPEED_40G |
+			ETH_LINK_SPEED_50G |
+			ETH_LINK_SPEED_56G;
 	priv_unlock(priv);
 }
 
diff --git a/drivers/net/nfp/nfp_net.c b/drivers/net/nfp/nfp_net.c
index 201c38e..dd033f4 100644
--- a/drivers/net/nfp/nfp_net.c
+++ b/drivers/net/nfp/nfp_net.c
@@ -1061,6 +1061,8 @@ nfp_net_infos_get(struct rte_eth_dev *dev, struct rte_eth_dev_info *dev_info)
 
 	dev_info->reta_size = NFP_NET_CFG_RSS_ITBL_SZ;
 	dev_info->hash_key_size = NFP_NET_CFG_RSS_KEY_SZ;
+
+	dev_info->speed_capa = ETH_LINK_SPEED_40G;
 }
 
 static const uint32_t *
diff --git a/lib/librte_ether/rte_ethdev.h b/lib/librte_ether/rte_ethdev.h
index bc7d607..49fdcb7 100644
--- a/lib/librte_ether/rte_ethdev.h
+++ b/lib/librte_ether/rte_ethdev.h
@@ -242,6 +242,23 @@ struct rte_eth_stats {
 };
 
 /**
+ * Device supported speeds bitmap flags
+ */
+#define ETH_LINK_SPEED_10M_HD   (1 <<  1)  /**<  10 Mbps half-duplex */
+#define ETH_LINK_SPEED_10M      (1 <<  2)  /**<  10 Mbps full-duplex */
+#define ETH_LINK_SPEED_100M_HD  (1 <<  3)  /**< 100 Mbps half-duplex */
+#define ETH_LINK_SPEED_100M     (1 <<  4)  /**< 100 Mbps full-duplex */
+#define ETH_LINK_SPEED_1G       (1 <<  5)  /**<   1 Gbps */
+#define ETH_LINK_SPEED_2_5G     (1 <<  6)  /**< 2.5 Gbps */
+#define ETH_LINK_SPEED_5G       (1 <<  7)  /**<   5 Gbps */
+#define ETH_LINK_SPEED_10G      (1 <<  8)  /**<  10 Gbps */
+#define ETH_LINK_SPEED_20G      (1 <<  9)  /**<  20 Gbps */
+#define ETH_LINK_SPEED_25G      (1 << 10)  /**<  25 Gbps */
+#define ETH_LINK_SPEED_40G      (1 << 11)  /**<  40 Gbps */
+#define ETH_LINK_SPEED_50G      (1 << 12)  /**<  50 Gbps */
+#define ETH_LINK_SPEED_56G      (1 << 13)  /**<  56 Gbps */
+
+/**
  * Ethernet numeric link speeds in Mbps
  */
 #define ETH_LINK_SPEED_AUTONEG     0 /**< Auto-negotiate link speed. */
@@ -850,6 +867,9 @@ struct rte_eth_conf {
 #define DEV_TX_OFFLOAD_OUTER_IPV4_CKSUM 0x00000080 /**< Used for tunneling packet. */
 #define DEV_TX_OFFLOAD_QINQ_INSERT 0x00000100
 
+/**
+ * Ethernet device information
+ */
 struct rte_eth_dev_info {
 	struct rte_pci_device *pci_dev; /**< Device PCI information. */
 	const char *driver_name; /**< Device Driver name. */
@@ -878,6 +898,7 @@ struct rte_eth_dev_info {
 	uint16_t vmdq_pool_base;  /**< First ID of VMDQ pools. */
 	struct rte_eth_desc_lim rx_desc_lim;  /**< RX descriptors limits */
 	struct rte_eth_desc_lim tx_desc_lim;  /**< TX descriptors limits */
+	uint32_t speed_capa;  /**< Supported speeds bitmap (ETH_LINK_SPEED_). */
 };
 
 /**
-- 
2.1.4

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

* [PATCH v14 6/8] ethdev: redesign link speed config
  2016-03-31 22:12                 ` [PATCH v14 " Marc Sune
                                     ` (4 preceding siblings ...)
  2016-03-31 22:12                   ` [PATCH v14 5/8] ethdev: add speed capabilities Marc Sune
@ 2016-03-31 22:12                   ` Marc Sune
  2016-03-31 22:12                   ` [PATCH v14 7/8] ethdev: convert speed number to bitmap flag Marc Sune
                                     ` (2 subsequent siblings)
  8 siblings, 0 replies; 167+ messages in thread
From: Marc Sune @ 2016-03-31 22:12 UTC (permalink / raw)
  To: Thomas Monjalon, Xu, Qian Q, Xing, Beilei, dev, Ananyev,
	Konstantin, Lu, Wenzhuo, Richardson, Bruce, Glynn, Michael J
  Cc: Marc Sune

This patch redesigns the API to set the link speed/s configuration
of an ethernet port. Specifically:

- it allows to define a set of advertised speeds for
  auto-negociation.
- it allows to disable link auto-negociation (single fixed speed).
- default: auto-negociate all supported speeds.

A flag autoneg in struct rte_eth_link indicates if link speed was a
result of auto-negociation or was fixed by configuration.

Signed-off-by: Marc Sune <marcdevel@gmail.com>
Tested-by: Nelio Laranjeiro <nelio.laranjeiro@6wind.com>
Signed-off-by: Thomas Monjalon <thomas.monjalon@6wind.com>
---
 app/test-pmd/cmdline.c                    |  26 ++++----
 doc/guides/rel_notes/deprecation.rst      |   3 -
 doc/guides/rel_notes/release_16_04.rst    |   9 +++
 drivers/net/af_packet/rte_eth_af_packet.c |   1 +
 drivers/net/bnx2x/bnx2x_ethdev.c          |   4 +-
 drivers/net/bonding/rte_eth_bond_8023ad.c |   2 +-
 drivers/net/e1000/em_ethdev.c             | 103 +++++++++++++++---------------
 drivers/net/e1000/igb_ethdev.c            |  95 ++++++++++++++-------------
 drivers/net/i40e/i40e_ethdev.c            |  48 +++++++-------
 drivers/net/i40e/i40e_ethdev_vf.c         |   7 +-
 drivers/net/ixgbe/ixgbe_ethdev.c          |  53 ++++++++-------
 drivers/net/mlx4/mlx4.c                   |   2 +
 drivers/net/mlx5/mlx5_ethdev.c            |   2 +
 drivers/net/mpipe/mpipe_tilegx.c          |   2 +
 drivers/net/null/rte_eth_null.c           |   1 +
 drivers/net/pcap/rte_eth_pcap.c           |   1 +
 drivers/net/ring/rte_eth_ring.c           |   1 +
 drivers/net/szedata2/rte_eth_szedata2.c   |   2 +
 drivers/net/vmxnet3/vmxnet3_ethdev.c      |   1 +
 drivers/net/xenvirt/rte_eth_xenvirt.c     |   1 +
 examples/ip_pipeline/config_parse.c       |   3 +-
 lib/librte_ether/rte_ethdev.h             |  31 +++++----
 22 files changed, 213 insertions(+), 185 deletions(-)

diff --git a/app/test-pmd/cmdline.c b/app/test-pmd/cmdline.c
index 815b53b..741cac3 100644
--- a/app/test-pmd/cmdline.c
+++ b/app/test-pmd/cmdline.c
@@ -989,7 +989,7 @@ struct cmd_config_speed_all {
 };
 
 static int
-parse_and_check_speed_duplex(char *speedstr, char *duplexstr, uint16_t *speed)
+parse_and_check_speed_duplex(char *speedstr, char *duplexstr, uint32_t *speed)
 {
 
 	int duplex;
@@ -1006,20 +1006,22 @@ parse_and_check_speed_duplex(char *speedstr, char *duplexstr, uint16_t *speed)
 	}
 
 	if (!strcmp(speedstr, "10")) {
-		*speed = ETH_SPEED_NUM_10M;
+		*speed = (duplex == ETH_LINK_HALF_DUPLEX) ?
+				ETH_LINK_SPEED_10M_HD : ETH_LINK_SPEED_10M;
 	} else if (!strcmp(speedstr, "100")) {
-		*speed = ETH_SPEED_NUM_100M;
+		*speed = (duplex == ETH_LINK_HALF_DUPLEX) ?
+				ETH_LINK_SPEED_100M_HD : ETH_LINK_SPEED_100M;
 	} else {
 		if (duplex != ETH_LINK_FULL_DUPLEX) {
 			printf("Invalid speed/duplex parameters\n");
 			return -1;
 		}
 		if (!strcmp(speedstr, "1000")) {
-			*speed = ETH_SPEED_NUM_1G;
+			*speed = ETH_LINK_SPEED_1G;
 		} else if (!strcmp(speedstr, "10000")) {
-			*speed = ETH_SPEED_NUM_10G;
+			*speed = ETH_LINK_SPEED_10G;
 		} else if (!strcmp(speedstr, "40000")) {
-			*speed = ETH_SPEED_NUM_40G;
+			*speed = ETH_LINK_SPEED_40G;
 		} else if (!strcmp(speedstr, "auto")) {
 			*speed = ETH_LINK_SPEED_AUTONEG;
 		} else {
@@ -1037,8 +1039,7 @@ cmd_config_speed_all_parsed(void *parsed_result,
 			__attribute__((unused)) void *data)
 {
 	struct cmd_config_speed_all *res = parsed_result;
-	uint16_t link_speed = ETH_LINK_SPEED_AUTONEG;
-	uint16_t link_duplex = 0;
+	uint32_t link_speed;
 	portid_t pid;
 
 	if (!all_ports_stopped()) {
@@ -1051,8 +1052,7 @@ cmd_config_speed_all_parsed(void *parsed_result,
 		return;
 
 	FOREACH_PORT(pid, ports) {
-		ports[pid].dev_conf.link_speed = link_speed;
-		ports[pid].dev_conf.link_duplex = link_duplex;
+		ports[pid].dev_conf.link_speeds = link_speed;
 	}
 
 	cmd_reconfig_device_queue(RTE_PORT_ALL, 1, 1);
@@ -1110,8 +1110,7 @@ cmd_config_speed_specific_parsed(void *parsed_result,
 				__attribute__((unused)) void *data)
 {
 	struct cmd_config_speed_specific *res = parsed_result;
-	uint16_t link_speed = ETH_LINK_SPEED_AUTONEG;
-	uint16_t link_duplex = 0;
+	uint32_t link_speed;
 
 	if (!all_ports_stopped()) {
 		printf("Please stop all ports first\n");
@@ -1125,8 +1124,7 @@ cmd_config_speed_specific_parsed(void *parsed_result,
 			&link_speed) < 0)
 		return;
 
-	ports[res->id].dev_conf.link_speed = link_speed;
-	ports[res->id].dev_conf.link_duplex = link_duplex;
+	ports[res->id].dev_conf.link_speeds = link_speed;
 
 	cmd_reconfig_device_queue(RTE_PORT_ALL, 1, 1);
 }
diff --git a/doc/guides/rel_notes/deprecation.rst b/doc/guides/rel_notes/deprecation.rst
index 179e30f..c47610d 100644
--- a/doc/guides/rel_notes/deprecation.rst
+++ b/doc/guides/rel_notes/deprecation.rst
@@ -19,9 +19,6 @@ Deprecation Notices
   ibadcrc, ibadlen, imcasts, fdirmatch, fdirmiss,
   tx_pause_xon, rx_pause_xon, tx_pause_xoff, rx_pause_xoff
 
-* The ethdev structures rte_eth_link, rte_eth_dev_info and rte_eth_conf
-  must be updated to support 100G link and to have a cleaner link speed API.
-
 * ABI changes are planned for adding four new flow types. This impacts
   RTE_ETH_FLOW_MAX. The release 2.2 does not contain these ABI changes,
   but release 2.3 will. [postponed]
diff --git a/doc/guides/rel_notes/release_16_04.rst b/doc/guides/rel_notes/release_16_04.rst
index 9e7b0b7..c891a55 100644
--- a/doc/guides/rel_notes/release_16_04.rst
+++ b/doc/guides/rel_notes/release_16_04.rst
@@ -52,6 +52,12 @@ This section should contain new features added in this release. Sample format:
   The structure ``rte_eth_dev_info`` has now a ``speed_capa`` bitmap, which
   allows the application to know the supported speeds of each device.
 
+* **Added bitmap of link speeds to advertise.**
+
+  Allow defining a set of advertised speeds for auto-negotiation,
+  explicitly disabling link auto-negotiation (single speed)
+  and full auto-negotiation.
+
 * **Added new poll-mode driver for Amazon Elastic Network Adapters (ENA).**
 
   The driver operates variety of ENA adapters through feature negotiation
@@ -464,6 +470,9 @@ This section should contain API changes. Sample format:
 * The ethdev structure ``rte_eth_dev_info`` was changed to support device
   speed capabilities.
 
+* The ethdev structures ``rte_eth_link`` and ``rte_eth_conf`` were changed to
+  support the new link API.
+
 * The functions ``rte_eth_dev_udp_tunnel_add`` and ``rte_eth_dev_udp_tunnel_delete``
   have been renamed into ``rte_eth_dev_udp_tunnel_port_add`` and
   ``rte_eth_dev_udp_tunnel_port_delete``.
diff --git a/drivers/net/af_packet/rte_eth_af_packet.c b/drivers/net/af_packet/rte_eth_af_packet.c
index 641f849..f17bd7e 100644
--- a/drivers/net/af_packet/rte_eth_af_packet.c
+++ b/drivers/net/af_packet/rte_eth_af_packet.c
@@ -119,6 +119,7 @@ static struct rte_eth_link pmd_link = {
 	.link_speed = ETH_SPEED_NUM_10G,
 	.link_duplex = ETH_LINK_FULL_DUPLEX,
 	.link_status = ETH_LINK_DOWN,
+	.link_autoneg = ETH_LINK_SPEED_AUTONEG
 };
 
 static uint16_t
diff --git a/drivers/net/bnx2x/bnx2x_ethdev.c b/drivers/net/bnx2x/bnx2x_ethdev.c
index 897081f..071b44f 100644
--- a/drivers/net/bnx2x/bnx2x_ethdev.c
+++ b/drivers/net/bnx2x/bnx2x_ethdev.c
@@ -44,9 +44,9 @@ bnx2x_link_update(struct rte_eth_dev *dev)
 		case DUPLEX_HALF:
 			dev->data->dev_link.link_duplex = ETH_LINK_HALF_DUPLEX;
 			break;
-		default:
-			dev->data->dev_link.link_duplex = ETH_LINK_AUTONEG_DUPLEX;
 	}
+	dev->data->dev_link.link_autoneg = !(dev->data->dev_conf.link_speeds &
+			ETH_LINK_SPEED_FIXED);
 	dev->data->dev_link.link_status = sc->link_vars.link_up;
 }
 
diff --git a/drivers/net/bonding/rte_eth_bond_8023ad.c b/drivers/net/bonding/rte_eth_bond_8023ad.c
index ac8306f..cca7cc3 100644
--- a/drivers/net/bonding/rte_eth_bond_8023ad.c
+++ b/drivers/net/bonding/rte_eth_bond_8023ad.c
@@ -708,7 +708,7 @@ link_speed_key(uint16_t speed) {
 	uint16_t key_speed;
 
 	switch (speed) {
-	case ETH_LINK_SPEED_AUTONEG:
+	case ETH_SPEED_NUM_NONE:
 		key_speed = 0x00;
 		break;
 	case ETH_SPEED_NUM_10M:
diff --git a/drivers/net/e1000/em_ethdev.c b/drivers/net/e1000/em_ethdev.c
index 890c5c3..653be09 100644
--- a/drivers/net/e1000/em_ethdev.c
+++ b/drivers/net/e1000/em_ethdev.c
@@ -538,6 +538,9 @@ eth_em_start(struct rte_eth_dev *dev)
 	struct rte_intr_handle *intr_handle = &dev->pci_dev->intr_handle;
 	int ret, mask;
 	uint32_t intr_vector = 0;
+	uint32_t *speeds;
+	int num_speeds;
+	bool autoneg;
 
 	PMD_INIT_FUNC_TRACE();
 
@@ -612,56 +615,46 @@ eth_em_start(struct rte_eth_dev *dev)
 	E1000_WRITE_REG(hw, E1000_ITR, UINT16_MAX);
 
 	/* Setup link speed and duplex */
-	switch (dev->data->dev_conf.link_speed) {
-	case ETH_LINK_SPEED_AUTONEG:
-		if (dev->data->dev_conf.link_duplex == ETH_LINK_AUTONEG_DUPLEX)
-			hw->phy.autoneg_advertised = E1000_ALL_SPEED_DUPLEX;
-		else if (dev->data->dev_conf.link_duplex ==
-					ETH_LINK_HALF_DUPLEX)
-			hw->phy.autoneg_advertised = E1000_ALL_HALF_DUPLEX;
-		else if (dev->data->dev_conf.link_duplex ==
-					ETH_LINK_FULL_DUPLEX)
-			hw->phy.autoneg_advertised = E1000_ALL_FULL_DUPLEX;
-		else
-			goto error_invalid_config;
-		break;
-	case ETH_SPEED_NUM_10M:
-		if (dev->data->dev_conf.link_duplex == ETH_LINK_AUTONEG_DUPLEX)
-			hw->phy.autoneg_advertised = E1000_ALL_10_SPEED;
-		else if (dev->data->dev_conf.link_duplex ==
-					ETH_LINK_HALF_DUPLEX)
-			hw->phy.autoneg_advertised = ADVERTISE_10_HALF;
-		else if (dev->data->dev_conf.link_duplex ==
-					ETH_LINK_FULL_DUPLEX)
-			hw->phy.autoneg_advertised = ADVERTISE_10_FULL;
-		else
-			goto error_invalid_config;
-		break;
-	case ETH_SPEED_NUM_100M:
-		if (dev->data->dev_conf.link_duplex == ETH_LINK_AUTONEG_DUPLEX)
-			hw->phy.autoneg_advertised = E1000_ALL_100_SPEED;
-		else if (dev->data->dev_conf.link_duplex ==
-					ETH_LINK_HALF_DUPLEX)
-			hw->phy.autoneg_advertised = ADVERTISE_100_HALF;
-		else if (dev->data->dev_conf.link_duplex ==
-					ETH_LINK_FULL_DUPLEX)
-			hw->phy.autoneg_advertised = ADVERTISE_100_FULL;
-		else
+	speeds = &dev->data->dev_conf.link_speeds;
+	if (*speeds == ETH_LINK_SPEED_AUTONEG) {
+		hw->phy.autoneg_advertised = E1000_ALL_SPEED_DUPLEX;
+	} else {
+		num_speeds = 0;
+		autoneg = (*speeds & ETH_LINK_SPEED_FIXED) == 0;
+
+		/* Reset */
+		hw->phy.autoneg_advertised = 0;
+
+		if (*speeds & ~(ETH_LINK_SPEED_10M_HD | ETH_LINK_SPEED_10M |
+				ETH_LINK_SPEED_100M_HD | ETH_LINK_SPEED_100M |
+				ETH_LINK_SPEED_1G | ETH_LINK_SPEED_FIXED)) {
+			num_speeds = -1;
 			goto error_invalid_config;
-		break;
-	case ETH_SPEED_NUM_1G:
-		if ((dev->data->dev_conf.link_duplex ==
-				ETH_LINK_AUTONEG_DUPLEX) ||
-			(dev->data->dev_conf.link_duplex ==
-					ETH_LINK_FULL_DUPLEX))
-			hw->phy.autoneg_advertised = ADVERTISE_1000_FULL;
-		else
+		}
+		if (*speeds & ETH_LINK_SPEED_10M_HD) {
+			hw->phy.autoneg_advertised |= ADVERTISE_10_HALF;
+			num_speeds++;
+		}
+		if (*speeds & ETH_LINK_SPEED_10M) {
+			hw->phy.autoneg_advertised |= ADVERTISE_10_FULL;
+			num_speeds++;
+		}
+		if (*speeds & ETH_LINK_SPEED_100M_HD) {
+			hw->phy.autoneg_advertised |= ADVERTISE_100_HALF;
+			num_speeds++;
+		}
+		if (*speeds & ETH_LINK_SPEED_100M) {
+			hw->phy.autoneg_advertised |= ADVERTISE_100_FULL;
+			num_speeds++;
+		}
+		if (*speeds & ETH_LINK_SPEED_1G) {
+			hw->phy.autoneg_advertised |= ADVERTISE_1000_FULL;
+			num_speeds++;
+		}
+		if (num_speeds == 0 || (!autoneg && (num_speeds > 1)))
 			goto error_invalid_config;
-		break;
-	case ETH_SPEED_NUM_10G:
-	default:
-		goto error_invalid_config;
 	}
+
 	e1000_setup_link(hw);
 
 	if (rte_intr_allow_others(intr_handle)) {
@@ -695,9 +688,8 @@ eth_em_start(struct rte_eth_dev *dev)
 	return 0;
 
 error_invalid_config:
-	PMD_INIT_LOG(ERR, "Invalid link_speed/link_duplex (%u/%u) for port %u",
-		     dev->data->dev_conf.link_speed,
-		     dev->data->dev_conf.link_duplex, dev->data->port_id);
+	PMD_INIT_LOG(ERR, "Invalid advertised speeds (%u) for port %u",
+		     dev->data->dev_conf.link_speeds, dev->data->port_id);
 	em_dev_clear_queues(dev);
 	return -EINVAL;
 }
@@ -1107,13 +1099,20 @@ eth_em_link_update(struct rte_eth_dev *dev, int wait_to_complete)
 
 	/* Now we check if a transition has happened */
 	if (link_check && (link.link_status == ETH_LINK_DOWN)) {
-		hw->mac.ops.get_link_up_info(hw, &link.link_speed,
-			&link.link_duplex);
+		uint16_t duplex, speed;
+		hw->mac.ops.get_link_up_info(hw, &speed, &duplex);
+		link.link_duplex = (duplex == FULL_DUPLEX) ?
+				ETH_LINK_FULL_DUPLEX :
+				ETH_LINK_HALF_DUPLEX;
+		link.link_speed = speed;
 		link.link_status = ETH_LINK_UP;
+		link.link_autoneg = !(dev->data->dev_conf.link_speeds &
+				ETH_LINK_SPEED_FIXED);
 	} else if (!link_check && (link.link_status == ETH_LINK_UP)) {
 		link.link_speed = 0;
 		link.link_duplex = ETH_LINK_HALF_DUPLEX;
 		link.link_status = ETH_LINK_DOWN;
+		link.link_autoneg = ETH_LINK_SPEED_FIXED;
 	}
 	rte_em_dev_atomic_write_link_status(dev, &link);
 
diff --git a/drivers/net/e1000/igb_ethdev.c b/drivers/net/e1000/igb_ethdev.c
index 95d1711..e0053fe 100644
--- a/drivers/net/e1000/igb_ethdev.c
+++ b/drivers/net/e1000/igb_ethdev.c
@@ -1133,6 +1133,9 @@ eth_igb_start(struct rte_eth_dev *dev)
 	int ret, mask;
 	uint32_t intr_vector = 0;
 	uint32_t ctrl_ext;
+	uint32_t *speeds;
+	int num_speeds;
+	bool autoneg;
 
 	PMD_INIT_FUNC_TRACE();
 
@@ -1233,48 +1236,46 @@ eth_igb_start(struct rte_eth_dev *dev)
 	}
 
 	/* Setup link speed and duplex */
-	switch (dev->data->dev_conf.link_speed) {
-	case ETH_LINK_SPEED_AUTONEG:
-		if (dev->data->dev_conf.link_duplex == ETH_LINK_AUTONEG_DUPLEX)
-			hw->phy.autoneg_advertised = E1000_ALL_SPEED_DUPLEX;
-		else if (dev->data->dev_conf.link_duplex == ETH_LINK_HALF_DUPLEX)
-			hw->phy.autoneg_advertised = E1000_ALL_HALF_DUPLEX;
-		else if (dev->data->dev_conf.link_duplex == ETH_LINK_FULL_DUPLEX)
-			hw->phy.autoneg_advertised = E1000_ALL_FULL_DUPLEX;
-		else
-			goto error_invalid_config;
-		break;
-	case ETH_SPEED_NUM_10M:
-		if (dev->data->dev_conf.link_duplex == ETH_LINK_AUTONEG_DUPLEX)
-			hw->phy.autoneg_advertised = E1000_ALL_10_SPEED;
-		else if (dev->data->dev_conf.link_duplex == ETH_LINK_HALF_DUPLEX)
-			hw->phy.autoneg_advertised = ADVERTISE_10_HALF;
-		else if (dev->data->dev_conf.link_duplex == ETH_LINK_FULL_DUPLEX)
-			hw->phy.autoneg_advertised = ADVERTISE_10_FULL;
-		else
-			goto error_invalid_config;
-		break;
-	case ETH_SPEED_NUM_100M:
-		if (dev->data->dev_conf.link_duplex == ETH_LINK_AUTONEG_DUPLEX)
-			hw->phy.autoneg_advertised = E1000_ALL_100_SPEED;
-		else if (dev->data->dev_conf.link_duplex == ETH_LINK_HALF_DUPLEX)
-			hw->phy.autoneg_advertised = ADVERTISE_100_HALF;
-		else if (dev->data->dev_conf.link_duplex == ETH_LINK_FULL_DUPLEX)
-			hw->phy.autoneg_advertised = ADVERTISE_100_FULL;
-		else
+	speeds = &dev->data->dev_conf.link_speeds;
+	if (*speeds == ETH_LINK_SPEED_AUTONEG) {
+		hw->phy.autoneg_advertised = E1000_ALL_SPEED_DUPLEX;
+	} else {
+		num_speeds = 0;
+		autoneg = (*speeds & ETH_LINK_SPEED_FIXED) == 0;
+
+		/* Reset */
+		hw->phy.autoneg_advertised = 0;
+
+		if (*speeds & ~(ETH_LINK_SPEED_10M_HD | ETH_LINK_SPEED_10M |
+				ETH_LINK_SPEED_100M_HD | ETH_LINK_SPEED_100M |
+				ETH_LINK_SPEED_1G | ETH_LINK_SPEED_FIXED)) {
+			num_speeds = -1;
 			goto error_invalid_config;
-		break;
-	case ETH_SPEED_NUM_1G:
-		if ((dev->data->dev_conf.link_duplex == ETH_LINK_AUTONEG_DUPLEX) ||
-				(dev->data->dev_conf.link_duplex == ETH_LINK_FULL_DUPLEX))
-			hw->phy.autoneg_advertised = ADVERTISE_1000_FULL;
-		else
+		}
+		if (*speeds & ETH_LINK_SPEED_10M_HD) {
+			hw->phy.autoneg_advertised |= ADVERTISE_10_HALF;
+			num_speeds++;
+		}
+		if (*speeds & ETH_LINK_SPEED_10M) {
+			hw->phy.autoneg_advertised |= ADVERTISE_10_FULL;
+			num_speeds++;
+		}
+		if (*speeds & ETH_LINK_SPEED_100M_HD) {
+			hw->phy.autoneg_advertised |= ADVERTISE_100_HALF;
+			num_speeds++;
+		}
+		if (*speeds & ETH_LINK_SPEED_100M) {
+			hw->phy.autoneg_advertised |= ADVERTISE_100_FULL;
+			num_speeds++;
+		}
+		if (*speeds & ETH_LINK_SPEED_1G) {
+			hw->phy.autoneg_advertised |= ADVERTISE_1000_FULL;
+			num_speeds++;
+		}
+		if (num_speeds == 0 || (!autoneg && (num_speeds > 1)))
 			goto error_invalid_config;
-		break;
-	case ETH_SPEED_NUM_10G:
-	default:
-		goto error_invalid_config;
 	}
+
 	e1000_setup_link(hw);
 
 	if (rte_intr_allow_others(intr_handle)) {
@@ -1306,9 +1307,8 @@ eth_igb_start(struct rte_eth_dev *dev)
 	return 0;
 
 error_invalid_config:
-	PMD_INIT_LOG(ERR, "Invalid link_speed/link_duplex (%u/%u) for port %u",
-		     dev->data->dev_conf.link_speed,
-		     dev->data->dev_conf.link_duplex, dev->data->port_id);
+	PMD_INIT_LOG(ERR, "Invalid advertised speeds (%u) for port %u",
+		     dev->data->dev_conf.link_speeds, dev->data->port_id);
 	igb_dev_clear_queues(dev);
 	return -EINVAL;
 }
@@ -2061,13 +2061,20 @@ eth_igb_link_update(struct rte_eth_dev *dev, int wait_to_complete)
 
 	/* Now we check if a transition has happened */
 	if (link_check) {
-		hw->mac.ops.get_link_up_info(hw, &link.link_speed,
-					  &link.link_duplex);
+		uint16_t duplex, speed;
+		hw->mac.ops.get_link_up_info(hw, &speed, &duplex);
+		link.link_duplex = (duplex == FULL_DUPLEX) ?
+				ETH_LINK_FULL_DUPLEX :
+				ETH_LINK_HALF_DUPLEX;
+		link.link_speed = speed;
 		link.link_status = ETH_LINK_UP;
+		link.link_autoneg = !(dev->data->dev_conf.link_speeds &
+				ETH_LINK_SPEED_FIXED);
 	} else if (!link_check) {
 		link.link_speed = 0;
 		link.link_duplex = ETH_LINK_HALF_DUPLEX;
 		link.link_status = ETH_LINK_DOWN;
+		link.link_autoneg = ETH_LINK_SPEED_FIXED;
 	}
 	rte_igb_dev_atomic_write_link_status(dev, &link);
 
diff --git a/drivers/net/i40e/i40e_ethdev.c b/drivers/net/i40e/i40e_ethdev.c
index cde314d..bc28d3c 100644
--- a/drivers/net/i40e/i40e_ethdev.c
+++ b/drivers/net/i40e/i40e_ethdev.c
@@ -1381,27 +1381,20 @@ i40e_vsi_disable_queues_intr(struct i40e_vsi *vsi)
 }
 
 static inline uint8_t
-i40e_parse_link_speed(uint16_t eth_link_speed)
+i40e_parse_link_speeds(uint16_t link_speeds)
 {
 	uint8_t link_speed = I40E_LINK_SPEED_UNKNOWN;
 
-	switch (eth_link_speed) {
-	case ETH_SPEED_NUM_40G:
-		link_speed = I40E_LINK_SPEED_40GB;
-		break;
-	case ETH_SPEED_NUM_20G:
-		link_speed = I40E_LINK_SPEED_20GB;
-		break;
-	case ETH_SPEED_NUM_10G:
-		link_speed = I40E_LINK_SPEED_10GB;
-		break;
-	case ETH_SPEED_NUM_1G:
-		link_speed = I40E_LINK_SPEED_1GB;
-		break;
-	case ETH_SPEED_NUM_100M:
-		link_speed = I40E_LINK_SPEED_100MB;
-		break;
-	}
+	if (link_speeds & ETH_LINK_SPEED_40G)
+		link_speed |= I40E_LINK_SPEED_40GB;
+	if (link_speeds & ETH_LINK_SPEED_20G)
+		link_speed |= I40E_LINK_SPEED_20GB;
+	if (link_speeds & ETH_LINK_SPEED_10G)
+		link_speed |= I40E_LINK_SPEED_10GB;
+	if (link_speeds & ETH_LINK_SPEED_1G)
+		link_speed |= I40E_LINK_SPEED_1GB;
+	if (link_speeds & ETH_LINK_SPEED_100M)
+		link_speed |= I40E_LINK_SPEED_100MB;
 
 	return link_speed;
 }
@@ -1427,9 +1420,9 @@ i40e_apply_link_speed(struct rte_eth_dev *dev)
 	struct i40e_hw *hw = I40E_DEV_PRIVATE_TO_HW(dev->data->dev_private);
 	struct rte_eth_conf *conf = &dev->data->dev_conf;
 
-	speed = i40e_parse_link_speed(conf->link_speed);
+	speed = i40e_parse_link_speeds(conf->link_speeds);
 	abilities |= I40E_AQ_PHY_ENABLE_ATOMIC_LINK;
-	if (conf->link_speed == ETH_LINK_SPEED_AUTONEG)
+	if (!(conf->link_speeds & ETH_LINK_SPEED_FIXED))
 		abilities |= I40E_AQ_PHY_AN_ENABLED;
 	else
 		abilities |= I40E_AQ_PHY_LINK_ENABLED;
@@ -1449,10 +1442,8 @@ i40e_dev_start(struct rte_eth_dev *dev)
 
 	hw->adapter_stopped = 0;
 
-	if ((dev->data->dev_conf.link_duplex != ETH_LINK_AUTONEG_DUPLEX) &&
-		(dev->data->dev_conf.link_duplex != ETH_LINK_FULL_DUPLEX)) {
-		PMD_INIT_LOG(ERR, "Invalid link_duplex (%hu) for port %hhu",
-			     dev->data->dev_conf.link_duplex,
+	if (dev->data->dev_conf.link_speeds & ETH_LINK_SPEED_FIXED) {
+		PMD_INIT_LOG(ERR, "Invalid link_speeds for port %hhu; autonegotiation disabled",
 			     dev->data->port_id);
 		return -EINVAL;
 	}
@@ -1525,6 +1516,12 @@ i40e_dev_start(struct rte_eth_dev *dev)
 	}
 
 	/* Apply link configure */
+	if (dev->data->dev_conf.link_speeds & ~(ETH_LINK_SPEED_100M |
+				ETH_LINK_SPEED_1G | ETH_LINK_SPEED_10G |
+				ETH_LINK_SPEED_20G | ETH_LINK_SPEED_40G)) {
+		PMD_DRV_LOG(ERR, "Invalid link setting");
+		goto err_up;
+	}
 	ret = i40e_apply_link_speed(dev);
 	if (I40E_SUCCESS != ret) {
 		PMD_DRV_LOG(ERR, "Fail to apply link setting");
@@ -1809,6 +1806,9 @@ i40e_dev_link_update(struct rte_eth_dev *dev,
 		break;
 	}
 
+	link.link_autoneg = !(dev->data->dev_conf.link_speeds &
+			ETH_LINK_SPEED_FIXED);
+
 out:
 	rte_i40e_dev_atomic_write_link_status(dev, &link);
 	if (link.link_status == old.link_status)
diff --git a/drivers/net/i40e/i40e_ethdev_vf.c b/drivers/net/i40e/i40e_ethdev_vf.c
index 295dcd2..8cf22ee 100644
--- a/drivers/net/i40e/i40e_ethdev_vf.c
+++ b/drivers/net/i40e/i40e_ethdev_vf.c
@@ -2121,12 +2121,13 @@ i40evf_dev_link_update(struct rte_eth_dev *dev,
 	 * DPDK pf host provide interfacet to acquire link status
 	 * while Linux driver does not
 	 */
-	if (vf->version_major == I40E_DPDK_VERSION_MAJOR)
+	if (vf->version_major == I40E_DPDK_VERSION_MAJOR) {
 		i40evf_get_link_status(dev, &new_link);
-	else {
+	} else {
 		/* Always assume it's up, for Linux driver PF host */
-		new_link.link_duplex = ETH_LINK_AUTONEG_DUPLEX;
 		new_link.link_speed  = ETH_SPEED_NUM_10G;
+		new_link.link_duplex = ETH_LINK_FULL_DUPLEX;
+		new_link.link_autoneg = ETH_LINK_SPEED_AUTONEG;
 		new_link.link_status = ETH_LINK_UP;
 	}
 	i40evf_dev_atomic_write_link_status(dev, &new_link);
diff --git a/drivers/net/ixgbe/ixgbe_ethdev.c b/drivers/net/ixgbe/ixgbe_ethdev.c
index 894278f..3f1ebc1 100644
--- a/drivers/net/ixgbe/ixgbe_ethdev.c
+++ b/drivers/net/ixgbe/ixgbe_ethdev.c
@@ -2094,14 +2094,16 @@ ixgbe_dev_start(struct rte_eth_dev *dev)
 	int mask = 0;
 	int status;
 	uint16_t vf, idx;
+	uint32_t *link_speeds;
 
 	PMD_INIT_FUNC_TRACE();
 
-	/* IXGBE devices don't support half duplex */
-	if ((dev->data->dev_conf.link_duplex != ETH_LINK_AUTONEG_DUPLEX) &&
-			(dev->data->dev_conf.link_duplex != ETH_LINK_FULL_DUPLEX)) {
-		PMD_INIT_LOG(ERR, "Invalid link_duplex (%hu) for port %hhu",
-			     dev->data->dev_conf.link_duplex,
+	/* IXGBE devices don't support:
+	*    - half duplex (checked afterwards for valid speeds)
+	*    - fixed speed: TODO implement
+	*/
+	if (dev->data->dev_conf.link_speeds & ETH_LINK_SPEED_FIXED) {
+		PMD_INIT_LOG(ERR, "Invalid link_speeds for port %hhu; fix speed not supported",
 			     dev->data->port_id);
 		return -EINVAL;
 	}
@@ -2198,30 +2200,25 @@ ixgbe_dev_start(struct rte_eth_dev *dev)
 	if (err)
 		goto error;
 
-	switch(dev->data->dev_conf.link_speed) {
-	case ETH_LINK_SPEED_AUTONEG:
+	link_speeds = &dev->data->dev_conf.link_speeds;
+	if (*link_speeds & ~(ETH_LINK_SPEED_100M | ETH_LINK_SPEED_1G |
+			ETH_LINK_SPEED_10G)) {
+		PMD_INIT_LOG(ERR, "Invalid link setting");
+		goto error;
+	}
+
+	speed = 0x0;
+	if (*link_speeds == ETH_LINK_SPEED_AUTONEG) {
 		speed = (hw->mac.type != ixgbe_mac_82598EB) ?
 				IXGBE_LINK_SPEED_82599_AUTONEG :
 				IXGBE_LINK_SPEED_82598_AUTONEG;
-		break;
-	case ETH_SPEED_NUM_100M:
-		/*
-		 * Invalid for 82598 but error will be detected by
-		 * ixgbe_setup_link()
-		 */
-		speed = IXGBE_LINK_SPEED_100_FULL;
-		break;
-	case ETH_SPEED_NUM_1G:
-		speed = IXGBE_LINK_SPEED_1GB_FULL;
-		break;
-	case ETH_SPEED_NUM_10G:
-		speed = IXGBE_LINK_SPEED_10GB_FULL;
-		break;
-	default:
-		PMD_INIT_LOG(ERR, "Invalid link_speed (%hu) for port %hhu",
-			     dev->data->dev_conf.link_speed,
-			     dev->data->port_id);
-		goto error;
+	} else {
+		if (*link_speeds & ETH_LINK_SPEED_10G)
+			speed |= IXGBE_LINK_SPEED_10GB_FULL;
+		if (*link_speeds & ETH_LINK_SPEED_1G)
+			speed |= IXGBE_LINK_SPEED_1GB_FULL;
+		if (*link_speeds & ETH_LINK_SPEED_100M)
+			speed |= IXGBE_LINK_SPEED_100_FULL;
 	}
 
 	err = ixgbe_setup_link(hw, speed, link_up);
@@ -3088,7 +3085,7 @@ ixgbe_dev_link_update(struct rte_eth_dev *dev, int wait_to_complete)
 
 	if (diag != 0) {
 		link.link_speed = ETH_SPEED_NUM_100M;
-		link.link_duplex = ETH_LINK_HALF_DUPLEX;
+		link.link_duplex = ETH_LINK_FULL_DUPLEX;
 		rte_ixgbe_dev_atomic_write_link_status(dev, &link);
 		if (link.link_status == old.link_status)
 			return -1;
@@ -3107,7 +3104,7 @@ ixgbe_dev_link_update(struct rte_eth_dev *dev, int wait_to_complete)
 	switch (link_speed) {
 	default:
 	case IXGBE_LINK_SPEED_UNKNOWN:
-		link.link_duplex = ETH_LINK_HALF_DUPLEX;
+		link.link_duplex = ETH_LINK_FULL_DUPLEX;
 		link.link_speed = ETH_SPEED_NUM_100M;
 		break;
 
diff --git a/drivers/net/mlx4/mlx4.c b/drivers/net/mlx4/mlx4.c
index ed2f488..4f21dbe 100644
--- a/drivers/net/mlx4/mlx4.c
+++ b/drivers/net/mlx4/mlx4.c
@@ -4736,6 +4736,8 @@ mlx4_link_update_unlocked(struct rte_eth_dev *dev, int wait_to_complete)
 		dev_link.link_speed = link_speed;
 	dev_link.link_duplex = ((edata.duplex == DUPLEX_HALF) ?
 				ETH_LINK_HALF_DUPLEX : ETH_LINK_FULL_DUPLEX);
+	dev_link.link_autoneg = !(dev->data->dev_conf.link_speeds &
+			ETH_LINK_SPEED_FIXED);
 	if (memcmp(&dev_link, &dev->data->dev_link, sizeof(dev_link))) {
 		/* Link status changed. */
 		dev->data->dev_link = dev_link;
diff --git a/drivers/net/mlx5/mlx5_ethdev.c b/drivers/net/mlx5/mlx5_ethdev.c
index d7a0eea..beecc63 100644
--- a/drivers/net/mlx5/mlx5_ethdev.c
+++ b/drivers/net/mlx5/mlx5_ethdev.c
@@ -629,6 +629,8 @@ mlx5_link_update_unlocked(struct rte_eth_dev *dev, int wait_to_complete)
 		dev_link.link_speed = link_speed;
 	dev_link.link_duplex = ((edata.duplex == DUPLEX_HALF) ?
 				ETH_LINK_HALF_DUPLEX : ETH_LINK_FULL_DUPLEX);
+	dev_link.link_autoneg = !(dev->data->dev_conf.link_speeds &
+			ETH_LINK_SPEED_FIXED);
 	if (memcmp(&dev_link, &dev->data->dev_link, sizeof(dev_link))) {
 		/* Link status changed. */
 		dev->data->dev_link = dev_link;
diff --git a/drivers/net/mpipe/mpipe_tilegx.c b/drivers/net/mpipe/mpipe_tilegx.c
index 1a77c7a..adcbc19 100644
--- a/drivers/net/mpipe/mpipe_tilegx.c
+++ b/drivers/net/mpipe/mpipe_tilegx.c
@@ -394,6 +394,8 @@ mpipe_link_update(struct rte_eth_dev *dev, int wait_to_complete)
 
 		speed = state & GXIO_MPIPE_LINK_SPEED_MASK;
 
+		new.link_autoneg = (dev->data->dev_conf.link_speeds &
+				ETH_LINK_SPEED_AUTONEG);
 		if (speed == GXIO_MPIPE_LINK_1G) {
 			new.link_speed = ETH_SPEED_NUM_1G;
 			new.link_duplex = ETH_LINK_FULL_DUPLEX;
diff --git a/drivers/net/null/rte_eth_null.c b/drivers/net/null/rte_eth_null.c
index 5640585..5e8e203 100644
--- a/drivers/net/null/rte_eth_null.c
+++ b/drivers/net/null/rte_eth_null.c
@@ -92,6 +92,7 @@ static struct rte_eth_link pmd_link = {
 	.link_speed = ETH_SPEED_NUM_10G,
 	.link_duplex = ETH_LINK_FULL_DUPLEX,
 	.link_status = ETH_LINK_DOWN,
+	.link_autoneg = ETH_LINK_SPEED_AUTONEG,
 };
 
 static uint16_t
diff --git a/drivers/net/pcap/rte_eth_pcap.c b/drivers/net/pcap/rte_eth_pcap.c
index c657951..c98e234 100644
--- a/drivers/net/pcap/rte_eth_pcap.c
+++ b/drivers/net/pcap/rte_eth_pcap.c
@@ -126,6 +126,7 @@ static struct rte_eth_link pmd_link = {
 		.link_speed = ETH_SPEED_NUM_10G,
 		.link_duplex = ETH_LINK_FULL_DUPLEX,
 		.link_status = ETH_LINK_DOWN,
+		.link_autoneg = ETH_LINK_SPEED_FIXED,
 };
 
 static int
diff --git a/drivers/net/ring/rte_eth_ring.c b/drivers/net/ring/rte_eth_ring.c
index 58685e9..b1783c3 100644
--- a/drivers/net/ring/rte_eth_ring.c
+++ b/drivers/net/ring/rte_eth_ring.c
@@ -80,6 +80,7 @@ static struct rte_eth_link pmd_link = {
 		.link_speed = ETH_SPEED_NUM_10G,
 		.link_duplex = ETH_LINK_FULL_DUPLEX,
 		.link_status = ETH_LINK_DOWN,
+		.link_autoneg = ETH_LINK_SPEED_AUTONEG
 };
 
 static uint16_t
diff --git a/drivers/net/szedata2/rte_eth_szedata2.c b/drivers/net/szedata2/rte_eth_szedata2.c
index dd1ae9e..ee97a4e 100644
--- a/drivers/net/szedata2/rte_eth_szedata2.c
+++ b/drivers/net/szedata2/rte_eth_szedata2.c
@@ -1174,6 +1174,8 @@ eth_link_update(struct rte_eth_dev *dev,
 	link.link_status = (cgmii_ibuf_is_enabled(ibuf) &&
 			cgmii_ibuf_is_link_up(ibuf)) ? ETH_LINK_UP : ETH_LINK_DOWN;
 
+	link.link_autoneg = ETH_LINK_SPEED_FIXED;
+
 	rte_atomic64_cmpset((uint64_t *)dev_link, *(uint64_t *)dev_link,
 			*(uint64_t *)link_ptr);
 
diff --git a/drivers/net/vmxnet3/vmxnet3_ethdev.c b/drivers/net/vmxnet3/vmxnet3_ethdev.c
index 95d533f..bd7a2bb 100644
--- a/drivers/net/vmxnet3/vmxnet3_ethdev.c
+++ b/drivers/net/vmxnet3/vmxnet3_ethdev.c
@@ -779,6 +779,7 @@ vmxnet3_dev_link_update(struct rte_eth_dev *dev, __attribute__((unused)) int wai
 		link.link_status = ETH_LINK_UP;
 		link.link_duplex = ETH_LINK_FULL_DUPLEX;
 		link.link_speed = ETH_SPEED_NUM_10G;
+		link.link_autoneg = ETH_LINK_SPEED_FIXED;
 	}
 
 	vmxnet3_dev_atomic_write_link_status(dev, &link);
diff --git a/drivers/net/xenvirt/rte_eth_xenvirt.c b/drivers/net/xenvirt/rte_eth_xenvirt.c
index 77d3ba1..b9638d9 100644
--- a/drivers/net/xenvirt/rte_eth_xenvirt.c
+++ b/drivers/net/xenvirt/rte_eth_xenvirt.c
@@ -73,6 +73,7 @@ static struct rte_eth_link pmd_link = {
 		.link_speed = ETH_SPEED_NUM_10G,
 		.link_duplex = ETH_LINK_FULL_DUPLEX,
 		.link_status = ETH_LINK_DOWN,
+		.link_autoneg = ETH_LINK_SPEED_FIXED
 };
 
 static void
diff --git a/examples/ip_pipeline/config_parse.c b/examples/ip_pipeline/config_parse.c
index 152889d..2cd5707 100644
--- a/examples/ip_pipeline/config_parse.c
+++ b/examples/ip_pipeline/config_parse.c
@@ -87,8 +87,7 @@ static const struct app_link_params link_params_default = {
 	.pci_bdf = {0},
 
 	.conf = {
-		.link_speed = 0,
-		.link_duplex = 0,
+		.link_speeds = 0,
 		.rxmode = {
 			.mq_mode = ETH_MQ_RX_NONE,
 
diff --git a/lib/librte_ether/rte_ethdev.h b/lib/librte_ether/rte_ethdev.h
index 49fdcb7..b88300d 100644
--- a/lib/librte_ether/rte_ethdev.h
+++ b/lib/librte_ether/rte_ethdev.h
@@ -244,6 +244,8 @@ struct rte_eth_stats {
 /**
  * Device supported speeds bitmap flags
  */
+#define ETH_LINK_SPEED_AUTONEG  (0 <<  0)  /**< Autonegotiate (all speeds) */
+#define ETH_LINK_SPEED_FIXED    (1 <<  0)  /**< Disable autoneg (fixed speed) */
 #define ETH_LINK_SPEED_10M_HD   (1 <<  1)  /**<  10 Mbps half-duplex */
 #define ETH_LINK_SPEED_10M      (1 <<  2)  /**<  10 Mbps full-duplex */
 #define ETH_LINK_SPEED_100M_HD  (1 <<  3)  /**< 100 Mbps half-duplex */
@@ -261,7 +263,7 @@ struct rte_eth_stats {
 /**
  * Ethernet numeric link speeds in Mbps
  */
-#define ETH_LINK_SPEED_AUTONEG     0 /**< Auto-negotiate link speed. */
+#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 */
@@ -278,17 +280,19 @@ struct rte_eth_stats {
  * A structure used to retrieve link-level information of an Ethernet port.
  */
 struct rte_eth_link {
-	uint16_t link_speed;      /**< ETH_SPEED_NUM_ */
-	uint16_t link_duplex;     /**< ETH_LINK_[HALF/FULL]_DUPLEX */
-	uint8_t  link_status : 1; /**< ETH_LINK_[DOWN/UP] */
-}__attribute__((aligned(8)));     /**< aligned for atomic64 read/write */
+	uint16_t link_speed;        /**< ETH_SPEED_NUM_ */
+	uint16_t link_duplex  : 1;  /**< ETH_LINK_[HALF/FULL]_DUPLEX */
+	uint16_t link_autoneg : 1;  /**< ETH_LINK_SPEED_[AUTONEG/FIXED] */
+	uint16_t link_status  : 1;  /**< ETH_LINK_[DOWN/UP] */
+} __attribute__((aligned(8)));      /**< aligned for atomic64 read/write */
 
 /* Utility constants */
-#define ETH_LINK_AUTONEG_DUPLEX 0       /**< Auto-negotiate duplex. */
-#define ETH_LINK_HALF_DUPLEX    1       /**< Half-duplex connection. */
-#define ETH_LINK_FULL_DUPLEX    2       /**< Full-duplex connection. */
+#define ETH_LINK_HALF_DUPLEX    0 /**< Half-duplex connection. */
+#define ETH_LINK_FULL_DUPLEX    1 /**< Full-duplex connection. */
 #define ETH_LINK_DOWN           0 /**< Link is down. */
 #define ETH_LINK_UP             1 /**< Link is up. */
+#define ETH_LINK_FIXED          0 /**< No autonegotiation. */
+#define ETH_LINK_AUTONEG        1 /**< Autonegotiated. */
 
 /**
  * A structure used to configure the ring threshold registers of an RX/TX
@@ -802,10 +806,13 @@ struct rte_intr_conf {
  * configuration settings may be needed.
  */
 struct rte_eth_conf {
-	uint16_t link_speed;
-	/**< ETH_SPEED_NUM_ or 0 for autonegotiation */
-	uint16_t link_duplex;
-	/**< ETH_LINK_[HALF_DUPLEX|FULL_DUPLEX], or 0 for autonegotation */
+	uint32_t link_speeds; /**< bitmap of ETH_LINK_SPEED_XXX of speeds to be
+				used. ETH_LINK_SPEED_FIXED disables link
+				autonegotiation, and a unique speed shall be
+				set. Otherwise, the bitmap defines the set of
+				speeds to be advertised. If the special value
+				ETH_LINK_SPEED_AUTONEG (0) is used, all speeds
+				supported are advertised. */
 	struct rte_eth_rxmode rxmode; /**< Port RX configuration. */
 	struct rte_eth_txmode txmode; /**< Port TX configuration. */
 	uint32_t lpbk_mode; /**< Loopback operation mode. By default the value
-- 
2.1.4

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

* [PATCH v14 7/8] ethdev: convert speed number to bitmap flag
  2016-03-31 22:12                 ` [PATCH v14 " Marc Sune
                                     ` (5 preceding siblings ...)
  2016-03-31 22:12                   ` [PATCH v14 6/8] ethdev: redesign link speed config Marc Sune
@ 2016-03-31 22:12                   ` Marc Sune
  2016-03-31 22:12                   ` [PATCH v14 8/8] ethdev: add 100G link speed Marc Sune
  2016-04-01 19:38                   ` [PATCH v14 0/8] ethdev: 100G and link speed API refactoring Thomas Monjalon
  8 siblings, 0 replies; 167+ messages in thread
From: Marc Sune @ 2016-03-31 22:12 UTC (permalink / raw)
  To: Thomas Monjalon, Xu, Qian Q, Xing, Beilei, dev, Ananyev,
	Konstantin, Lu, Wenzhuo, Richardson, Bruce, Glynn, Michael J
  Cc: Marc Sune

It is a helper for the bitmap configuration.

Signed-off-by: Marc Sune <marcdevel@gmail.com>
Signed-off-by: Thomas Monjalon <thomas.monjalon@6wind.com>
---
 lib/librte_ether/rte_ethdev.c          | 31 +++++++++++++++++++++++++++++++
 lib/librte_ether/rte_ethdev.h          | 13 +++++++++++++
 lib/librte_ether/rte_ether_version.map |  1 +
 3 files changed, 45 insertions(+)

diff --git a/lib/librte_ether/rte_ethdev.c b/lib/librte_ether/rte_ethdev.c
index 76a30fd..695b475 100644
--- a/lib/librte_ether/rte_ethdev.c
+++ b/lib/librte_ether/rte_ethdev.c
@@ -866,6 +866,37 @@ rte_eth_dev_tx_queue_config(struct rte_eth_dev *dev, uint16_t nb_queues)
 	return 0;
 }
 
+uint32_t
+rte_eth_speed_bitflag(uint32_t speed, int duplex)
+{
+	switch (speed) {
+	case ETH_SPEED_NUM_10M:
+		return duplex ? ETH_LINK_SPEED_10M : ETH_LINK_SPEED_10M_HD;
+	case ETH_SPEED_NUM_100M:
+		return duplex ? ETH_LINK_SPEED_100M : ETH_LINK_SPEED_100M_HD;
+	case ETH_SPEED_NUM_1G:
+		return ETH_LINK_SPEED_1G;
+	case ETH_SPEED_NUM_2_5G:
+		return ETH_LINK_SPEED_2_5G;
+	case ETH_SPEED_NUM_5G:
+		return ETH_LINK_SPEED_5G;
+	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;
+	default:
+		return 0;
+	}
+}
+
 int
 rte_eth_dev_configure(uint8_t port_id, uint16_t nb_rx_q, uint16_t nb_tx_q,
 		      const struct rte_eth_conf *dev_conf)
diff --git a/lib/librte_ether/rte_ethdev.h b/lib/librte_ether/rte_ethdev.h
index b88300d..1342b3a 100644
--- a/lib/librte_ether/rte_ethdev.h
+++ b/lib/librte_ether/rte_ethdev.h
@@ -1878,6 +1878,19 @@ struct eth_driver {
 void rte_eth_driver_register(struct eth_driver *eth_drv);
 
 /**
+ * Convert a numerical speed in Mbps to a bitmap flag that can be used in
+ * the bitmap link_speeds of the struct rte_eth_conf
+ *
+ * @param speed
+ *   Numerical speed value in Mbps
+ * @param duplex
+ *   ETH_LINK_[HALF/FULL]_DUPLEX (only for 10/100M speeds)
+ * @return
+ *   0 if the speed cannot be mapped
+ */
+uint32_t rte_eth_speed_bitflag(uint32_t speed, int duplex);
+
+/**
  * Configure an Ethernet device.
  * This function must be invoked first before any other function in the
  * Ethernet API. This function can also be re-invoked when a device is in the
diff --git a/lib/librte_ether/rte_ether_version.map b/lib/librte_ether/rte_ether_version.map
index b1f4475..214ecc7 100644
--- a/lib/librte_ether/rte_ether_version.map
+++ b/lib/librte_ether/rte_ether_version.map
@@ -125,6 +125,7 @@ DPDK_16.04 {
 	rte_eth_dev_set_vlan_ether_type;
 	rte_eth_dev_udp_tunnel_port_add;
 	rte_eth_dev_udp_tunnel_port_delete;
+	rte_eth_speed_bitflag;
 	rte_eth_tx_buffer_count_callback;
 	rte_eth_tx_buffer_drop_callback;
 	rte_eth_tx_buffer_init;
-- 
2.1.4

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

* [PATCH v14 8/8] ethdev: add 100G link speed
  2016-03-31 22:12                 ` [PATCH v14 " Marc Sune
                                     ` (6 preceding siblings ...)
  2016-03-31 22:12                   ` [PATCH v14 7/8] ethdev: convert speed number to bitmap flag Marc Sune
@ 2016-03-31 22:12                   ` Marc Sune
  2016-04-01 19:38                   ` [PATCH v14 0/8] ethdev: 100G and link speed API refactoring Thomas Monjalon
  8 siblings, 0 replies; 167+ messages in thread
From: Marc Sune @ 2016-03-31 22:12 UTC (permalink / raw)
  To: Thomas Monjalon, Xu, Qian Q, Xing, Beilei, dev, Ananyev,
	Konstantin, Lu, Wenzhuo, Richardson, Bruce, Glynn, Michael J
  Cc: Marc Sune

From: Thomas Monjalon <thomas.monjalon@6wind.com>

The link speed configuration is now done with bitmaps so 100G speed
requires only a new bit flag.
The actual link speed is a number so its size must be increased from
16-bit to 32-bit.

Signed-off-by: Marc Sune <marcdevel@gmail.com>
Signed-off-by: Thomas Monjalon <thomas.monjalon@6wind.com>
Tested-by: Nelio Laranjeiro <nelio.laranjeiro@6wind.com>
Tested-by: Matej Vido <vido@cesnet.cz>
---
 app/test-pmd/cmdline.c                      | 12 +++++++-----
 doc/guides/nics/szedata2.rst                |  6 ------
 doc/guides/rel_notes/release_16_04.rst      |  5 +++++
 doc/guides/testpmd_app_ug/testpmd_funcs.rst |  2 +-
 drivers/net/ena/ena_ethdev.c                |  3 ++-
 drivers/net/fm10k/fm10k_ethdev.c            |  2 +-
 drivers/net/mlx5/mlx5_ethdev.c              |  3 ++-
 drivers/net/nfp/nfp_net.c                   |  2 +-
 drivers/net/szedata2/rte_eth_szedata2.c     |  9 ++-------
 lib/librte_ether/rte_ethdev.c               |  2 ++
 lib/librte_ether/rte_ethdev.h               |  4 +++-
 11 files changed, 26 insertions(+), 24 deletions(-)

diff --git a/app/test-pmd/cmdline.c b/app/test-pmd/cmdline.c
index 741cac3..c5b9479 100644
--- a/app/test-pmd/cmdline.c
+++ b/app/test-pmd/cmdline.c
@@ -549,7 +549,7 @@ static void cmd_help_long_parsed(void *parsed_result,
 			"    Detach physical or virtual dev by port_id\n\n"
 
 			"port config (port_id|all)"
-			" speed (10|100|1000|10000|40000|auto)"
+			" speed (10|100|1000|10000|40000|100000|auto)"
 			" duplex (half|full|auto)\n"
 			"    Set speed and duplex for all ports or port_id\n\n"
 
@@ -1022,6 +1022,8 @@ parse_and_check_speed_duplex(char *speedstr, char *duplexstr, uint32_t *speed)
 			*speed = ETH_LINK_SPEED_10G;
 		} else if (!strcmp(speedstr, "40000")) {
 			*speed = ETH_LINK_SPEED_40G;
+		} else if (!strcmp(speedstr, "100000")) {
+			*speed = ETH_LINK_SPEED_100G;
 		} else if (!strcmp(speedstr, "auto")) {
 			*speed = ETH_LINK_SPEED_AUTONEG;
 		} else {
@@ -1069,7 +1071,7 @@ cmdline_parse_token_string_t cmd_config_speed_all_item1 =
 	TOKEN_STRING_INITIALIZER(struct cmd_config_speed_all, item1, "speed");
 cmdline_parse_token_string_t cmd_config_speed_all_value1 =
 	TOKEN_STRING_INITIALIZER(struct cmd_config_speed_all, value1,
-						"10#100#1000#10000#40000#auto");
+						"10#100#1000#10000#40000#100000#auto");
 cmdline_parse_token_string_t cmd_config_speed_all_item2 =
 	TOKEN_STRING_INITIALIZER(struct cmd_config_speed_all, item2, "duplex");
 cmdline_parse_token_string_t cmd_config_speed_all_value2 =
@@ -1079,7 +1081,7 @@ cmdline_parse_token_string_t cmd_config_speed_all_value2 =
 cmdline_parse_inst_t cmd_config_speed_all = {
 	.f = cmd_config_speed_all_parsed,
 	.data = NULL,
-	.help_str = "port config all speed 10|100|1000|10000|40000|auto duplex "
+	.help_str = "port config all speed 10|100|1000|10000|40000|100000|auto duplex "
 							"half|full|auto",
 	.tokens = {
 		(void *)&cmd_config_speed_all_port,
@@ -1143,7 +1145,7 @@ cmdline_parse_token_string_t cmd_config_speed_specific_item1 =
 								"speed");
 cmdline_parse_token_string_t cmd_config_speed_specific_value1 =
 	TOKEN_STRING_INITIALIZER(struct cmd_config_speed_specific, value1,
-						"10#100#1000#10000#40000#auto");
+						"10#100#1000#10000#40000#100000#auto");
 cmdline_parse_token_string_t cmd_config_speed_specific_item2 =
 	TOKEN_STRING_INITIALIZER(struct cmd_config_speed_specific, item2,
 								"duplex");
@@ -1154,7 +1156,7 @@ cmdline_parse_token_string_t cmd_config_speed_specific_value2 =
 cmdline_parse_inst_t cmd_config_speed_specific = {
 	.f = cmd_config_speed_specific_parsed,
 	.data = NULL,
-	.help_str = "port config X speed 10|100|1000|10000|40000|auto duplex "
+	.help_str = "port config X speed 10|100|1000|10000|40000|100000|auto duplex "
 							"half|full|auto",
 	.tokens = {
 		(void *)&cmd_config_speed_specific_port,
diff --git a/doc/guides/nics/szedata2.rst b/doc/guides/nics/szedata2.rst
index 77c15b3..741b400 100644
--- a/doc/guides/nics/szedata2.rst
+++ b/doc/guides/nics/szedata2.rst
@@ -148,9 +148,3 @@ Example output:
      TX threshold registers: pthresh=0 hthresh=0 wthresh=0
      TX RS bit threshold=0 - TXQ flags=0x0
    testpmd>
-
-.. note::
-
-   Link speed API currently supports speeds up to 40 Gbps.
-   Therefore there is used 10G constant for 100 Gbps cards until the link speed
-   API is not changed.
diff --git a/doc/guides/rel_notes/release_16_04.rst b/doc/guides/rel_notes/release_16_04.rst
index c891a55..a0fc02d 100644
--- a/doc/guides/rel_notes/release_16_04.rst
+++ b/doc/guides/rel_notes/release_16_04.rst
@@ -320,6 +320,11 @@ EAL
 Drivers
 ~~~~~~~
 
+* **ethdev: Fixed overflow for 100Gbps.**
+
+  100Gbps in Mbps (100000) was exceeding 16-bit max value of ``link_speed``
+  in ``rte_eth_link``.
+
 * **ethdev: Fixed byte order consistency between fdir flow and mask.**
 
   Fixed issue in ethdev library that the structure for setting
diff --git a/doc/guides/testpmd_app_ug/testpmd_funcs.rst b/doc/guides/testpmd_app_ug/testpmd_funcs.rst
index 94fba6a..aed5e47 100644
--- a/doc/guides/testpmd_app_ug/testpmd_funcs.rst
+++ b/doc/guides/testpmd_app_ug/testpmd_funcs.rst
@@ -1155,7 +1155,7 @@ port config - speed
 
 Set the speed and duplex mode for all ports or a specific port::
 
-   testpmd> port config (port_id|all) speed (10|100|1000|10000|auto) \
+   testpmd> port config (port_id|all) speed (10|100|1000|10000|40000|100000|auto) \
             duplex (half|full|auto)
 
 port config - queues/descriptors
diff --git a/drivers/net/ena/ena_ethdev.c b/drivers/net/ena/ena_ethdev.c
index 4e403af..02af67a 100644
--- a/drivers/net/ena/ena_ethdev.c
+++ b/drivers/net/ena/ena_ethdev.c
@@ -1177,7 +1177,8 @@ static void ena_infos_get(struct rte_eth_dev *dev,
 			ETH_LINK_SPEED_10G  |
 			ETH_LINK_SPEED_25G  |
 			ETH_LINK_SPEED_40G  |
-			ETH_LINK_SPEED_50G;
+			ETH_LINK_SPEED_50G  |
+			ETH_LINK_SPEED_100G;
 
 	/* Get supported features from HW */
 	rc = ena_com_get_dev_attr_feat(ena_dev, &feat);
diff --git a/drivers/net/fm10k/fm10k_ethdev.c b/drivers/net/fm10k/fm10k_ethdev.c
index 2be297a..c2d377f 100644
--- a/drivers/net/fm10k/fm10k_ethdev.c
+++ b/drivers/net/fm10k/fm10k_ethdev.c
@@ -1415,7 +1415,7 @@ fm10k_dev_infos_get(struct rte_eth_dev *dev,
 
 	dev_info->speed_capa = ETH_LINK_SPEED_1G | ETH_LINK_SPEED_2_5G |
 			ETH_LINK_SPEED_10G | ETH_LINK_SPEED_25G |
-			ETH_LINK_SPEED_40G;
+			ETH_LINK_SPEED_40G | ETH_LINK_SPEED_100G;
 }
 
 #ifdef RTE_LIBRTE_FM10K_RX_OLFLAGS_ENABLE
diff --git a/drivers/net/mlx5/mlx5_ethdev.c b/drivers/net/mlx5/mlx5_ethdev.c
index beecc63..36b369e 100644
--- a/drivers/net/mlx5/mlx5_ethdev.c
+++ b/drivers/net/mlx5/mlx5_ethdev.c
@@ -566,7 +566,8 @@ mlx5_dev_infos_get(struct rte_eth_dev *dev, struct rte_eth_dev_info *info)
 			ETH_LINK_SPEED_25G |
 			ETH_LINK_SPEED_40G |
 			ETH_LINK_SPEED_50G |
-			ETH_LINK_SPEED_56G;
+			ETH_LINK_SPEED_56G |
+			ETH_LINK_SPEED_100G;
 	priv_unlock(priv);
 }
 
diff --git a/drivers/net/nfp/nfp_net.c b/drivers/net/nfp/nfp_net.c
index dd033f4..bcf5fa9 100644
--- a/drivers/net/nfp/nfp_net.c
+++ b/drivers/net/nfp/nfp_net.c
@@ -1062,7 +1062,7 @@ nfp_net_infos_get(struct rte_eth_dev *dev, struct rte_eth_dev_info *dev_info)
 	dev_info->reta_size = NFP_NET_CFG_RSS_ITBL_SZ;
 	dev_info->hash_key_size = NFP_NET_CFG_RSS_KEY_SZ;
 
-	dev_info->speed_capa = ETH_LINK_SPEED_40G;
+	dev_info->speed_capa = ETH_LINK_SPEED_40G | ETH_LINK_SPEED_100G;
 }
 
 static const uint32_t *
diff --git a/drivers/net/szedata2/rte_eth_szedata2.c b/drivers/net/szedata2/rte_eth_szedata2.c
index ee97a4e..78c43b0 100644
--- a/drivers/net/szedata2/rte_eth_szedata2.c
+++ b/drivers/net/szedata2/rte_eth_szedata2.c
@@ -1036,6 +1036,7 @@ eth_dev_info(struct rte_eth_dev *dev,
 	dev_info->max_rx_queues = internals->max_rx_queues;
 	dev_info->max_tx_queues = internals->max_tx_queues;
 	dev_info->min_rx_bufsize = 0;
+	dev_info->speed_capa = ETH_LINK_SPEED_100G;
 }
 
 static void
@@ -1155,13 +1156,7 @@ eth_link_update(struct rte_eth_dev *dev,
 		link.link_speed = ETH_SPEED_NUM_40G;
 		break;
 	case SZEDATA2_LINK_SPEED_100G:
-		/*
-		 * TODO
-		 * If link_speed value from rte_eth_link structure
-		 * will be changed to support 100Gbps speed change
-		 * this value to 100G.
-		 */
-		link.link_speed = ETH_SPEED_NUM_10G;
+		link.link_speed = ETH_SPEED_NUM_100G;
 		break;
 	default:
 		link.link_speed = ETH_SPEED_NUM_10G;
diff --git a/lib/librte_ether/rte_ethdev.c b/lib/librte_ether/rte_ethdev.c
index 695b475..fd49b26 100644
--- a/lib/librte_ether/rte_ethdev.c
+++ b/lib/librte_ether/rte_ethdev.c
@@ -892,6 +892,8 @@ rte_eth_speed_bitflag(uint32_t speed, int duplex)
 		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;
 	}
diff --git a/lib/librte_ether/rte_ethdev.h b/lib/librte_ether/rte_ethdev.h
index 1342b3a..37ddd51 100644
--- a/lib/librte_ether/rte_ethdev.h
+++ b/lib/librte_ether/rte_ethdev.h
@@ -259,6 +259,7 @@ struct rte_eth_stats {
 #define ETH_LINK_SPEED_40G      (1 << 11)  /**<  40 Gbps */
 #define ETH_LINK_SPEED_50G      (1 << 12)  /**<  50 Gbps */
 #define ETH_LINK_SPEED_56G      (1 << 13)  /**<  56 Gbps */
+#define ETH_LINK_SPEED_100G     (1 << 14)  /**< 100 Gbps */
 
 /**
  * Ethernet numeric link speeds in Mbps
@@ -275,12 +276,13 @@ struct rte_eth_stats {
 #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 */
 
 /**
  * A structure used to retrieve link-level information of an Ethernet port.
  */
 struct rte_eth_link {
-	uint16_t link_speed;        /**< ETH_SPEED_NUM_ */
+	uint32_t link_speed;        /**< ETH_SPEED_NUM_ */
 	uint16_t link_duplex  : 1;  /**< ETH_LINK_[HALF/FULL]_DUPLEX */
 	uint16_t link_autoneg : 1;  /**< ETH_LINK_SPEED_[AUTONEG/FIXED] */
 	uint16_t link_status  : 1;  /**< ETH_LINK_[DOWN/UP] */
-- 
2.1.4

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

* Re: [PATCH v13 6/8] ethdev: redesign link speed config
  2016-03-31 12:28                         ` Thomas Monjalon
@ 2016-04-01  9:53                           ` Xing, Beilei
  0 siblings, 0 replies; 167+ messages in thread
From: Xing, Beilei @ 2016-04-01  9:53 UTC (permalink / raw)
  To: Thomas Monjalon
  Cc: dev, Marc, Xu, Qian Q, Ananyev, Konstantin, Lu, Wenzhuo,
	Richardson, Bruce, Glynn, Michael J

> -----Original Message-----
> From: Thomas Monjalon [mailto:thomas.monjalon@6wind.com]
> Sent: Thursday, March 31, 2016 8:29 PM
> To: Xing, Beilei <beilei.xing@intel.com>
> Cc: dev@dpdk.org; Marc <marcdevel@gmail.com>; Xu, Qian Q
> <qian.q.xu@intel.com>; Ananyev, Konstantin <konstantin.ananyev@intel.com>;
> Lu, Wenzhuo <wenzhuo.lu@intel.com>; Richardson, Bruce
> <bruce.richardson@intel.com>; Glynn, Michael J <michael.j.glynn@intel.com>
> Subject: Re: [dpdk-dev] [PATCH v13 6/8] ethdev: redesign link speed config
> 
> 2016-03-31 00:57, Xing, Beilei:
> > I’ve verified v13 + the modification, and it works.
> 
> Please, what have you tested? Which drivers? Which configurations?
> 
> It is important to test several uses of rte_eth_conf.link_speeds:
> - ETH_LINK_SPEED_AUTONEG (all speeds)
> - ETH_LINK_SPEED_FIXED (only one speed)
> - a subset of speeds to advertise and negotiate

I tested basic tx/rx on ixgbe and autoneg only on ixgbe.
I'll comment in another mail later, sorry for inconvenience.

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

* Re: [PATCH v14 0/8] ethdev: 100G and link speed API refactoring
  2016-03-31 22:12                 ` [PATCH v14 " Marc Sune
                                     ` (7 preceding siblings ...)
  2016-03-31 22:12                   ` [PATCH v14 8/8] ethdev: add 100G link speed Marc Sune
@ 2016-04-01 19:38                   ` Thomas Monjalon
  8 siblings, 0 replies; 167+ messages in thread
From: Thomas Monjalon @ 2016-04-01 19:38 UTC (permalink / raw)
  To: Marc Sune
  Cc: Xu, Qian Q, Xing, Beilei, dev, Ananyev, Konstantin, Lu, Wenzhuo,
	Richardson, Bruce, Glynn, Michael J, Marc Sune

2016-04-01 00:12, Marc Sune:
> From: Marc Sune <marc@voltanet.io>
> 
> This series of patches adds the following capabilities:
> 
> * speed_capa bitmap in rte_eth_dev_info, which is filled by the PMDs
>   according to the physical device capabilities.
> * refactors link API in ethdev to allow the definition of the advertised
>   link speeds, fix speed (no auto-negociation) or advertise all supported
>   speeds (default).

The few feedbacks look good.
Applied, thanks.

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

* Re: [PATCH v13 4/8] ethdev: rename link speed constants
  2016-03-26  1:27                 ` [PATCH v13 4/8] ethdev: rename link speed constants Marc Sune
@ 2016-04-06  8:34                   ` Weglicki, MichalX
  2016-04-06  8:52                     ` Thomas Monjalon
  0 siblings, 1 reply; 167+ messages in thread
From: Weglicki, MichalX @ 2016-04-06  8:34 UTC (permalink / raw)
  To: Marc Sune, Thomas Monjalon, Xu, Qian Q, Xing, Beilei, dev,
	Ananyev, Konstantin, Lu, Wenzhuo, Richardson, Bruce, Glynn,
	Michael J, Gray, Mark D

Hello, 

I have a question about this patch. 

As far as I see changing ETH_LINK_SPEED_ to ETH_SPEED_NUM_ is rather cosmetic change, am I right? 

Disadvantage of that is that it breaks compatibility with OVS (compilation) and thus it also breaks backward compatibility between OVS & DPDK. Is it really necessary? 

It would be great to keep ABI & API stable if possible. 

Br, 
Michal. 

-----Original Message-----
From: dev [mailto:dev-bounces@dpdk.org] On Behalf Of Marc Sune
Sent: Saturday, March 26, 2016 1:27 AM
To: Thomas Monjalon <thomas.monjalon@6wind.com>; Xu, Qian Q <qian.q.xu@intel.com>; Xing, Beilei <beilei.xing@intel.com>; dev@dpdk.org; Ananyev, Konstantin <konstantin.ananyev@intel.com>; Lu, Wenzhuo <wenzhuo.lu@intel.com>; Richardson, Bruce <bruce.richardson@intel.com>; Glynn, Michael J <michael.j.glynn@intel.com>
Cc: Marc Sune <marcdevel@gmail.com>
Subject: [dpdk-dev] [PATCH v13 4/8] ethdev: rename link speed constants

The speed numbers ETH_LINK_SPEED_ are renamed ETH_SPEED_NUM_.
The prefix ETH_LINK_SPEED_ is kept for AUTONEG and will be used
for bit flags in next patch.

Signed-off-by: Marc Sune <marcdevel@gmail.com>
---
 app/test-pmd/cmdline.c                    | 10 +++++-----
 app/test/virtual_pmd.c                    |  2 +-
 drivers/net/af_packet/rte_eth_af_packet.c |  2 +-
 drivers/net/bonding/rte_eth_bond_8023ad.c | 12 ++++++------
 drivers/net/cxgbe/base/t4_hw.c            |  8 ++++----
 drivers/net/e1000/em_ethdev.c             |  8 ++++----
 drivers/net/e1000/igb_ethdev.c            |  8 ++++----
 drivers/net/ena/ena_ethdev.c              |  2 +-
 drivers/net/i40e/i40e_ethdev.c            | 30 +++++++++++++++---------------
 drivers/net/i40e/i40e_ethdev_vf.c         |  2 +-
 drivers/net/ixgbe/ixgbe_ethdev.c          | 22 +++++++++++-----------
 drivers/net/mpipe/mpipe_tilegx.c          |  4 ++--
 drivers/net/nfp/nfp_net.c                 |  2 +-
 drivers/net/null/rte_eth_null.c           |  2 +-
 drivers/net/pcap/rte_eth_pcap.c           |  2 +-
 drivers/net/ring/rte_eth_ring.c           |  2 +-
 drivers/net/szedata2/rte_eth_szedata2.c   |  8 ++++----
 drivers/net/vmxnet3/vmxnet3_ethdev.c      |  2 +-
 drivers/net/xenvirt/rte_eth_xenvirt.c     |  2 +-
 lib/librte_ether/rte_ethdev.h             | 29 ++++++++++++++++++-----------
 20 files changed, 83 insertions(+), 76 deletions(-)

diff --git a/app/test-pmd/cmdline.c b/app/test-pmd/cmdline.c
index eb7bbb4..815b53b 100644
--- a/app/test-pmd/cmdline.c
+++ b/app/test-pmd/cmdline.c
@@ -1006,20 +1006,20 @@ parse_and_check_speed_duplex(char *speedstr, char *duplexstr, uint16_t *speed)
 	}
 
 	if (!strcmp(speedstr, "10")) {
-		*speed = ETH_LINK_SPEED_10;
+		*speed = ETH_SPEED_NUM_10M;
 	} else if (!strcmp(speedstr, "100")) {
-		*speed = ETH_LINK_SPEED_100;
+		*speed = ETH_SPEED_NUM_100M;
 	} else {
 		if (duplex != ETH_LINK_FULL_DUPLEX) {
 			printf("Invalid speed/duplex parameters\n");
 			return -1;
 		}
 		if (!strcmp(speedstr, "1000")) {
-			*speed = ETH_LINK_SPEED_1000;
+			*speed = ETH_SPEED_NUM_1G;
 		} else if (!strcmp(speedstr, "10000")) {
-			*speed = ETH_LINK_SPEED_10G;
+			*speed = ETH_SPEED_NUM_10G;
 		} else if (!strcmp(speedstr, "40000")) {
-			*speed = ETH_LINK_SPEED_40G;
+			*speed = ETH_SPEED_NUM_40G;
 		} else if (!strcmp(speedstr, "auto")) {
 			*speed = ETH_LINK_SPEED_AUTONEG;
 		} else {
diff --git a/app/test/virtual_pmd.c b/app/test/virtual_pmd.c
index b1d40d7..b4bd2f2 100644
--- a/app/test/virtual_pmd.c
+++ b/app/test/virtual_pmd.c
@@ -604,7 +604,7 @@ virtual_ethdev_create(const char *name, struct ether_addr *mac_addr,
 	TAILQ_INIT(&(eth_dev->link_intr_cbs));
 
 	eth_dev->data->dev_link.link_status = ETH_LINK_DOWN;
-	eth_dev->data->dev_link.link_speed = ETH_LINK_SPEED_10000;
+	eth_dev->data->dev_link.link_speed = ETH_SPEED_NUM_10G;
 	eth_dev->data->dev_link.link_duplex = ETH_LINK_FULL_DUPLEX;
 
 	eth_dev->data->mac_addrs = rte_zmalloc(name, ETHER_ADDR_LEN, 0);
diff --git a/drivers/net/af_packet/rte_eth_af_packet.c b/drivers/net/af_packet/rte_eth_af_packet.c
index dee7b59..641f849 100644
--- a/drivers/net/af_packet/rte_eth_af_packet.c
+++ b/drivers/net/af_packet/rte_eth_af_packet.c
@@ -116,7 +116,7 @@ static const char *valid_arguments[] = {
 static const char *drivername = "AF_PACKET PMD";
 
 static struct rte_eth_link pmd_link = {
-	.link_speed = 10000,
+	.link_speed = ETH_SPEED_NUM_10G,
 	.link_duplex = ETH_LINK_FULL_DUPLEX,
 	.link_status = ETH_LINK_DOWN,
 };
diff --git a/drivers/net/bonding/rte_eth_bond_8023ad.c b/drivers/net/bonding/rte_eth_bond_8023ad.c
index 1b7e93a..ac8306f 100644
--- a/drivers/net/bonding/rte_eth_bond_8023ad.c
+++ b/drivers/net/bonding/rte_eth_bond_8023ad.c
@@ -711,22 +711,22 @@ link_speed_key(uint16_t speed) {
 	case ETH_LINK_SPEED_AUTONEG:
 		key_speed = 0x00;
 		break;
-	case ETH_LINK_SPEED_10:
+	case ETH_SPEED_NUM_10M:
 		key_speed = BOND_LINK_SPEED_KEY_10M;
 		break;
-	case ETH_LINK_SPEED_100:
+	case ETH_SPEED_NUM_100M:
 		key_speed = BOND_LINK_SPEED_KEY_100M;
 		break;
-	case ETH_LINK_SPEED_1000:
+	case ETH_SPEED_NUM_1G:
 		key_speed = BOND_LINK_SPEED_KEY_1000M;
 		break;
-	case ETH_LINK_SPEED_10G:
+	case ETH_SPEED_NUM_10G:
 		key_speed = BOND_LINK_SPEED_KEY_10G;
 		break;
-	case ETH_LINK_SPEED_20G:
+	case ETH_SPEED_NUM_20G:
 		key_speed = BOND_LINK_SPEED_KEY_20G;
 		break;
-	case ETH_LINK_SPEED_40G:
+	case ETH_SPEED_NUM_40G:
 		key_speed = BOND_LINK_SPEED_KEY_40G;
 		break;
 	default:
diff --git a/drivers/net/cxgbe/base/t4_hw.c b/drivers/net/cxgbe/base/t4_hw.c
index 884d2cf..79af806 100644
--- a/drivers/net/cxgbe/base/t4_hw.c
+++ b/drivers/net/cxgbe/base/t4_hw.c
@@ -2159,13 +2159,13 @@ int t4_handle_fw_rpl(struct adapter *adap, const __be64 *rpl)
 		if (stat & F_FW_PORT_CMD_TXPAUSE)
 			fc |= PAUSE_TX;
 		if (stat & V_FW_PORT_CMD_LSPEED(FW_PORT_CAP_SPEED_100M))
-			speed = ETH_LINK_SPEED_100;
+			speed = ETH_SPEED_NUM_100M;
 		else if (stat & V_FW_PORT_CMD_LSPEED(FW_PORT_CAP_SPEED_1G))
-			speed = ETH_LINK_SPEED_1000;
+			speed = ETH_SPEED_NUM_1G;
 		else if (stat & V_FW_PORT_CMD_LSPEED(FW_PORT_CAP_SPEED_10G))
-			speed = ETH_LINK_SPEED_10000;
+			speed = ETH_SPEED_NUM_10G;
 		else if (stat & V_FW_PORT_CMD_LSPEED(FW_PORT_CAP_SPEED_40G))
-			speed = ETH_LINK_SPEED_40G;
+			speed = ETH_SPEED_NUM_40G;
 
 		for_each_port(adap, i) {
 			pi = adap2pinfo(adap, i);
diff --git a/drivers/net/e1000/em_ethdev.c b/drivers/net/e1000/em_ethdev.c
index fad8f2f..473d77f 100644
--- a/drivers/net/e1000/em_ethdev.c
+++ b/drivers/net/e1000/em_ethdev.c
@@ -625,7 +625,7 @@ eth_em_start(struct rte_eth_dev *dev)
 		else
 			goto error_invalid_config;
 		break;
-	case ETH_LINK_SPEED_10:
+	case ETH_SPEED_NUM_10M:
 		if (dev->data->dev_conf.link_duplex == ETH_LINK_AUTONEG_DUPLEX)
 			hw->phy.autoneg_advertised = E1000_ALL_10_SPEED;
 		else if (dev->data->dev_conf.link_duplex ==
@@ -637,7 +637,7 @@ eth_em_start(struct rte_eth_dev *dev)
 		else
 			goto error_invalid_config;
 		break;
-	case ETH_LINK_SPEED_100:
+	case ETH_SPEED_NUM_100M:
 		if (dev->data->dev_conf.link_duplex == ETH_LINK_AUTONEG_DUPLEX)
 			hw->phy.autoneg_advertised = E1000_ALL_100_SPEED;
 		else if (dev->data->dev_conf.link_duplex ==
@@ -649,7 +649,7 @@ eth_em_start(struct rte_eth_dev *dev)
 		else
 			goto error_invalid_config;
 		break;
-	case ETH_LINK_SPEED_1000:
+	case ETH_SPEED_NUM_1G:
 		if ((dev->data->dev_conf.link_duplex ==
 				ETH_LINK_AUTONEG_DUPLEX) ||
 			(dev->data->dev_conf.link_duplex ==
@@ -658,7 +658,7 @@ eth_em_start(struct rte_eth_dev *dev)
 		else
 			goto error_invalid_config;
 		break;
-	case ETH_LINK_SPEED_10000:
+	case ETH_SPEED_NUM_10G:
 	default:
 		goto error_invalid_config;
 	}
diff --git a/drivers/net/e1000/igb_ethdev.c b/drivers/net/e1000/igb_ethdev.c
index 4dfa7e3..86f25f6 100644
--- a/drivers/net/e1000/igb_ethdev.c
+++ b/drivers/net/e1000/igb_ethdev.c
@@ -1244,7 +1244,7 @@ eth_igb_start(struct rte_eth_dev *dev)
 		else
 			goto error_invalid_config;
 		break;
-	case ETH_LINK_SPEED_10:
+	case ETH_SPEED_NUM_10M:
 		if (dev->data->dev_conf.link_duplex == ETH_LINK_AUTONEG_DUPLEX)
 			hw->phy.autoneg_advertised = E1000_ALL_10_SPEED;
 		else if (dev->data->dev_conf.link_duplex == ETH_LINK_HALF_DUPLEX)
@@ -1254,7 +1254,7 @@ eth_igb_start(struct rte_eth_dev *dev)
 		else
 			goto error_invalid_config;
 		break;
-	case ETH_LINK_SPEED_100:
+	case ETH_SPEED_NUM_100M:
 		if (dev->data->dev_conf.link_duplex == ETH_LINK_AUTONEG_DUPLEX)
 			hw->phy.autoneg_advertised = E1000_ALL_100_SPEED;
 		else if (dev->data->dev_conf.link_duplex == ETH_LINK_HALF_DUPLEX)
@@ -1264,14 +1264,14 @@ eth_igb_start(struct rte_eth_dev *dev)
 		else
 			goto error_invalid_config;
 		break;
-	case ETH_LINK_SPEED_1000:
+	case ETH_SPEED_NUM_1G:
 		if ((dev->data->dev_conf.link_duplex == ETH_LINK_AUTONEG_DUPLEX) ||
 				(dev->data->dev_conf.link_duplex == ETH_LINK_FULL_DUPLEX))
 			hw->phy.autoneg_advertised = ADVERTISE_1000_FULL;
 		else
 			goto error_invalid_config;
 		break;
-	case ETH_LINK_SPEED_10000:
+	case ETH_SPEED_NUM_10G:
 	default:
 		goto error_invalid_config;
 	}
diff --git a/drivers/net/ena/ena_ethdev.c b/drivers/net/ena/ena_ethdev.c
index 325c513..1046286 100644
--- a/drivers/net/ena/ena_ethdev.c
+++ b/drivers/net/ena/ena_ethdev.c
@@ -504,7 +504,7 @@ static int ena_link_update(struct rte_eth_dev *dev,
 	struct rte_eth_link *link = &dev->data->dev_link;
 
 	link->link_status = 1;
-	link->link_speed = ETH_LINK_SPEED_10G;
+	link->link_speed = ETH_SPEED_NUM_10G;
 	link->link_duplex = ETH_LINK_FULL_DUPLEX;
 
 	return 0;
diff --git a/drivers/net/i40e/i40e_ethdev.c b/drivers/net/i40e/i40e_ethdev.c
index 05126e8..cce9e6f 100644
--- a/drivers/net/i40e/i40e_ethdev.c
+++ b/drivers/net/i40e/i40e_ethdev.c
@@ -1386,19 +1386,19 @@ i40e_parse_link_speed(uint16_t eth_link_speed)
 	uint8_t link_speed = I40E_LINK_SPEED_UNKNOWN;
 
 	switch (eth_link_speed) {
-	case ETH_LINK_SPEED_40G:
+	case ETH_SPEED_NUM_40G:
 		link_speed = I40E_LINK_SPEED_40GB;
 		break;
-	case ETH_LINK_SPEED_20G:
+	case ETH_SPEED_NUM_20G:
 		link_speed = I40E_LINK_SPEED_20GB;
 		break;
-	case ETH_LINK_SPEED_10G:
+	case ETH_SPEED_NUM_10G:
 		link_speed = I40E_LINK_SPEED_10GB;
 		break;
-	case ETH_LINK_SPEED_1000:
+	case ETH_SPEED_NUM_1G:
 		link_speed = I40E_LINK_SPEED_1GB;
 		break;
-	case ETH_LINK_SPEED_100:
+	case ETH_SPEED_NUM_100M:
 		link_speed = I40E_LINK_SPEED_100MB;
 		break;
 	}
@@ -1768,7 +1768,7 @@ i40e_dev_link_update(struct rte_eth_dev *dev,
 		/* Get link status information from hardware */
 		status = i40e_aq_get_link_info(hw, false, &link_status, NULL);
 		if (status != I40E_SUCCESS) {
-			link.link_speed = ETH_LINK_SPEED_100;
+			link.link_speed = ETH_SPEED_NUM_100M;
 			link.link_duplex = ETH_LINK_FULL_DUPLEX;
 			PMD_DRV_LOG(ERR, "Failed to get link info");
 			goto out;
@@ -1790,22 +1790,22 @@ i40e_dev_link_update(struct rte_eth_dev *dev,
 	/* Parse the link status */
 	switch (link_status.link_speed) {
 	case I40E_LINK_SPEED_100MB:
-		link.link_speed = ETH_LINK_SPEED_100;
+		link.link_speed = ETH_SPEED_NUM_100M;
 		break;
 	case I40E_LINK_SPEED_1GB:
-		link.link_speed = ETH_LINK_SPEED_1000;
+		link.link_speed = ETH_SPEED_NUM_1G;
 		break;
 	case I40E_LINK_SPEED_10GB:
-		link.link_speed = ETH_LINK_SPEED_10G;
+		link.link_speed = ETH_SPEED_NUM_10G;
 		break;
 	case I40E_LINK_SPEED_20GB:
-		link.link_speed = ETH_LINK_SPEED_20G;
+		link.link_speed = ETH_SPEED_NUM_20G;
 		break;
 	case I40E_LINK_SPEED_40GB:
-		link.link_speed = ETH_LINK_SPEED_40G;
+		link.link_speed = ETH_SPEED_NUM_40G;
 		break;
 	default:
-		link.link_speed = ETH_LINK_SPEED_100;
+		link.link_speed = ETH_SPEED_NUM_100M;
 		break;
 	}
 
@@ -8158,15 +8158,15 @@ i40e_start_timecounters(struct rte_eth_dev *dev)
 	rte_i40e_dev_atomic_read_link_status(dev, &link);
 
 	switch (link.link_speed) {
-	case ETH_LINK_SPEED_40G:
+	case ETH_SPEED_NUM_40G:
 		tsync_inc_l = I40E_PTP_40GB_INCVAL & 0xFFFFFFFF;
 		tsync_inc_h = I40E_PTP_40GB_INCVAL >> 32;
 		break;
-	case ETH_LINK_SPEED_10G:
+	case ETH_SPEED_NUM_10G:
 		tsync_inc_l = I40E_PTP_10GB_INCVAL & 0xFFFFFFFF;
 		tsync_inc_h = I40E_PTP_10GB_INCVAL >> 32;
 		break;
-	case ETH_LINK_SPEED_1000:
+	case ETH_SPEED_NUM_1G:
 		tsync_inc_l = I40E_PTP_1GB_INCVAL & 0xFFFFFFFF;
 		tsync_inc_h = I40E_PTP_1GB_INCVAL >> 32;
 		break;
diff --git a/drivers/net/i40e/i40e_ethdev_vf.c b/drivers/net/i40e/i40e_ethdev_vf.c
index 91df13b..295dcd2 100644
--- a/drivers/net/i40e/i40e_ethdev_vf.c
+++ b/drivers/net/i40e/i40e_ethdev_vf.c
@@ -2126,7 +2126,7 @@ i40evf_dev_link_update(struct rte_eth_dev *dev,
 	else {
 		/* Always assume it's up, for Linux driver PF host */
 		new_link.link_duplex = ETH_LINK_AUTONEG_DUPLEX;
-		new_link.link_speed  = ETH_LINK_SPEED_10000;
+		new_link.link_speed  = ETH_SPEED_NUM_10G;
 		new_link.link_status = ETH_LINK_UP;
 	}
 	i40evf_dev_atomic_write_link_status(dev, &new_link);
diff --git a/drivers/net/ixgbe/ixgbe_ethdev.c b/drivers/net/ixgbe/ixgbe_ethdev.c
index 21a3b8c..a0179d2 100644
--- a/drivers/net/ixgbe/ixgbe_ethdev.c
+++ b/drivers/net/ixgbe/ixgbe_ethdev.c
@@ -2199,17 +2199,17 @@ ixgbe_dev_start(struct rte_eth_dev *dev)
 				IXGBE_LINK_SPEED_82599_AUTONEG :
 				IXGBE_LINK_SPEED_82598_AUTONEG;
 		break;
-	case ETH_LINK_SPEED_100:
+	case ETH_SPEED_NUM_100M:
 		/*
 		 * Invalid for 82598 but error will be detected by
 		 * ixgbe_setup_link()
 		 */
 		speed = IXGBE_LINK_SPEED_100_FULL;
 		break;
-	case ETH_LINK_SPEED_1000:
+	case ETH_SPEED_NUM_1G:
 		speed = IXGBE_LINK_SPEED_1GB_FULL;
 		break;
-	case ETH_LINK_SPEED_10000:
+	case ETH_SPEED_NUM_10G:
 		speed = IXGBE_LINK_SPEED_10GB_FULL;
 		break;
 	default:
@@ -3074,7 +3074,7 @@ ixgbe_dev_link_update(struct rte_eth_dev *dev, int wait_to_complete)
 		diag = ixgbe_check_link(hw, &link_speed, &link_up, 1);
 
 	if (diag != 0) {
-		link.link_speed = ETH_LINK_SPEED_100;
+		link.link_speed = ETH_SPEED_NUM_100M;
 		link.link_duplex = ETH_LINK_HALF_DUPLEX;
 		rte_ixgbe_dev_atomic_write_link_status(dev, &link);
 		if (link.link_status == old.link_status)
@@ -3095,19 +3095,19 @@ ixgbe_dev_link_update(struct rte_eth_dev *dev, int wait_to_complete)
 	default:
 	case IXGBE_LINK_SPEED_UNKNOWN:
 		link.link_duplex = ETH_LINK_HALF_DUPLEX;
-		link.link_speed = ETH_LINK_SPEED_100;
+		link.link_speed = ETH_SPEED_NUM_100M;
 		break;
 
 	case IXGBE_LINK_SPEED_100_FULL:
-		link.link_speed = ETH_LINK_SPEED_100;
+		link.link_speed = ETH_SPEED_NUM_100M;
 		break;
 
 	case IXGBE_LINK_SPEED_1GB_FULL:
-		link.link_speed = ETH_LINK_SPEED_1000;
+		link.link_speed = ETH_SPEED_NUM_1G;
 		break;
 
 	case IXGBE_LINK_SPEED_10GB_FULL:
-		link.link_speed = ETH_LINK_SPEED_10000;
+		link.link_speed = ETH_SPEED_NUM_10G;
 		break;
 	}
 	rte_ixgbe_dev_atomic_write_link_status(dev, &link);
@@ -5909,15 +5909,15 @@ ixgbe_start_timecounters(struct rte_eth_dev *dev)
 	rte_ixgbe_dev_atomic_read_link_status(dev, &link);
 
 	switch (link.link_speed) {
-	case ETH_LINK_SPEED_100:
+	case ETH_SPEED_NUM_100M:
 		incval = IXGBE_INCVAL_100;
 		shift = IXGBE_INCVAL_SHIFT_100;
 		break;
-	case ETH_LINK_SPEED_1000:
+	case ETH_SPEED_NUM_1G:
 		incval = IXGBE_INCVAL_1GB;
 		shift = IXGBE_INCVAL_SHIFT_1GB;
 		break;
-	case ETH_LINK_SPEED_10000:
+	case ETH_SPEED_NUM_10G:
 	default:
 		incval = IXGBE_INCVAL_10GB;
 		shift = IXGBE_INCVAL_SHIFT_10GB;
diff --git a/drivers/net/mpipe/mpipe_tilegx.c b/drivers/net/mpipe/mpipe_tilegx.c
index d93ab7e..1a77c7a 100644
--- a/drivers/net/mpipe/mpipe_tilegx.c
+++ b/drivers/net/mpipe/mpipe_tilegx.c
@@ -395,11 +395,11 @@ mpipe_link_update(struct rte_eth_dev *dev, int wait_to_complete)
 		speed = state & GXIO_MPIPE_LINK_SPEED_MASK;
 
 		if (speed == GXIO_MPIPE_LINK_1G) {
-			new.link_speed = ETH_LINK_SPEED_1000;
+			new.link_speed = ETH_SPEED_NUM_1G;
 			new.link_duplex = ETH_LINK_FULL_DUPLEX;
 			new.link_status = ETH_LINK_UP;
 		} else if (speed == GXIO_MPIPE_LINK_10G) {
-			new.link_speed = ETH_LINK_SPEED_10000;
+			new.link_speed = ETH_SPEED_NUM_10G;
 			new.link_duplex = ETH_LINK_FULL_DUPLEX;
 			new.link_status = ETH_LINK_UP;
 		}
diff --git a/drivers/net/nfp/nfp_net.c b/drivers/net/nfp/nfp_net.c
index 80dda85..18ea0f4 100644
--- a/drivers/net/nfp/nfp_net.c
+++ b/drivers/net/nfp/nfp_net.c
@@ -821,7 +821,7 @@ nfp_net_link_update(struct rte_eth_dev *dev, __rte_unused int wait_to_complete)
 
 	link.link_duplex = ETH_LINK_FULL_DUPLEX;
 	/* Other cards can limit the tx and rx rate per VF */
-	link.link_speed = ETH_LINK_SPEED_40G;
+	link.link_speed = ETH_SPEED_NUM_40G;
 
 	if (old.link_status != link.link_status) {
 		nfp_net_dev_atomic_write_link_status(dev, &link);
diff --git a/drivers/net/null/rte_eth_null.c b/drivers/net/null/rte_eth_null.c
index 6adea91..5640585 100644
--- a/drivers/net/null/rte_eth_null.c
+++ b/drivers/net/null/rte_eth_null.c
@@ -89,7 +89,7 @@ struct pmd_internals {
 static struct ether_addr eth_addr = { .addr_bytes = {0} };
 static const char *drivername = "Null PMD";
 static struct rte_eth_link pmd_link = {
-	.link_speed = 10000,
+	.link_speed = ETH_SPEED_NUM_10G,
 	.link_duplex = ETH_LINK_FULL_DUPLEX,
 	.link_status = ETH_LINK_DOWN,
 };
diff --git a/drivers/net/pcap/rte_eth_pcap.c b/drivers/net/pcap/rte_eth_pcap.c
index b90c725..c657951 100644
--- a/drivers/net/pcap/rte_eth_pcap.c
+++ b/drivers/net/pcap/rte_eth_pcap.c
@@ -123,7 +123,7 @@ static int open_single_iface(const char *iface, pcap_t **pcap);
 static struct ether_addr eth_addr = { .addr_bytes = { 0, 0, 0, 0x1, 0x2, 0x3 } };
 static const char *drivername = "Pcap PMD";
 static struct rte_eth_link pmd_link = {
-		.link_speed = 10000,
+		.link_speed = ETH_SPEED_NUM_10G,
 		.link_duplex = ETH_LINK_FULL_DUPLEX,
 		.link_status = ETH_LINK_DOWN,
 };
diff --git a/drivers/net/ring/rte_eth_ring.c b/drivers/net/ring/rte_eth_ring.c
index 4335c6a..58685e9 100644
--- a/drivers/net/ring/rte_eth_ring.c
+++ b/drivers/net/ring/rte_eth_ring.c
@@ -77,7 +77,7 @@ struct pmd_internals {
 
 static const char *drivername = "Rings PMD";
 static struct rte_eth_link pmd_link = {
-		.link_speed = 10000,
+		.link_speed = ETH_SPEED_NUM_10G,
 		.link_duplex = ETH_LINK_FULL_DUPLEX,
 		.link_status = ETH_LINK_DOWN,
 };
diff --git a/drivers/net/szedata2/rte_eth_szedata2.c b/drivers/net/szedata2/rte_eth_szedata2.c
index 47aa7e3..dd1ae9e 100644
--- a/drivers/net/szedata2/rte_eth_szedata2.c
+++ b/drivers/net/szedata2/rte_eth_szedata2.c
@@ -1149,10 +1149,10 @@ eth_link_update(struct rte_eth_dev *dev,
 
 	switch (cgmii_link_speed(ibuf)) {
 	case SZEDATA2_LINK_SPEED_10G:
-		link.link_speed = ETH_LINK_SPEED_10G;
+		link.link_speed = ETH_SPEED_NUM_10G;
 		break;
 	case SZEDATA2_LINK_SPEED_40G:
-		link.link_speed = ETH_LINK_SPEED_40G;
+		link.link_speed = ETH_SPEED_NUM_40G;
 		break;
 	case SZEDATA2_LINK_SPEED_100G:
 		/*
@@ -1161,10 +1161,10 @@ eth_link_update(struct rte_eth_dev *dev,
 		 * will be changed to support 100Gbps speed change
 		 * this value to 100G.
 		 */
-		link.link_speed = ETH_LINK_SPEED_10G;
+		link.link_speed = ETH_SPEED_NUM_10G;
 		break;
 	default:
-		link.link_speed = ETH_LINK_SPEED_10G;
+		link.link_speed = ETH_SPEED_NUM_10G;
 		break;
 	}
 
diff --git a/drivers/net/vmxnet3/vmxnet3_ethdev.c b/drivers/net/vmxnet3/vmxnet3_ethdev.c
index 3f26217..6afa14e 100644
--- a/drivers/net/vmxnet3/vmxnet3_ethdev.c
+++ b/drivers/net/vmxnet3/vmxnet3_ethdev.c
@@ -779,7 +779,7 @@ vmxnet3_dev_link_update(struct rte_eth_dev *dev, __attribute__((unused)) int wai
 	if (ret & 0x1) {
 		link.link_status = ETH_LINK_UP;
 		link.link_duplex = ETH_LINK_FULL_DUPLEX;
-		link.link_speed = ETH_LINK_SPEED_10000;
+		link.link_speed = ETH_SPEED_NUM_10G;
 	}
 
 	vmxnet3_dev_atomic_write_link_status(dev, &link);
diff --git a/drivers/net/xenvirt/rte_eth_xenvirt.c b/drivers/net/xenvirt/rte_eth_xenvirt.c
index 9453a06..77d3ba1 100644
--- a/drivers/net/xenvirt/rte_eth_xenvirt.c
+++ b/drivers/net/xenvirt/rte_eth_xenvirt.c
@@ -70,7 +70,7 @@ static int virtio_idx = 0;
 static const char *drivername = "xen virtio PMD";
 
 static struct rte_eth_link pmd_link = {
-		.link_speed = 10000,
+		.link_speed = ETH_SPEED_NUM_10G,
 		.link_duplex = ETH_LINK_FULL_DUPLEX,
 		.link_status = ETH_LINK_DOWN,
 };
diff --git a/lib/librte_ether/rte_ethdev.h b/lib/librte_ether/rte_ethdev.h
index 2d13f92..bc7d607 100644
--- a/lib/librte_ether/rte_ethdev.h
+++ b/lib/librte_ether/rte_ethdev.h
@@ -242,23 +242,30 @@ struct rte_eth_stats {
 };
 
 /**
+ * Ethernet numeric link speeds in Mbps
+ */
+#define ETH_LINK_SPEED_AUTONEG     0 /**< Auto-negotiate link speed. */
+#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 */
+
+/**
  * A structure used to retrieve link-level information of an Ethernet port.
  */
 struct rte_eth_link {
-	uint16_t link_speed;      /**< ETH_LINK_SPEED_[10, 100, 1000, 10000] */
+	uint16_t link_speed;      /**< ETH_SPEED_NUM_ */
 	uint16_t link_duplex;     /**< ETH_LINK_[HALF/FULL]_DUPLEX */
 	uint8_t  link_status : 1; /**< ETH_LINK_[DOWN/UP] */
 }__attribute__((aligned(8)));     /**< aligned for atomic64 read/write */
 
-#define ETH_LINK_SPEED_AUTONEG  0       /**< Auto-negotiate link speed. */
-#define ETH_LINK_SPEED_10       10      /**< 10 megabits/second. */
-#define ETH_LINK_SPEED_100      100     /**< 100 megabits/second. */
-#define ETH_LINK_SPEED_1000     1000    /**< 1 gigabits/second. */
-#define ETH_LINK_SPEED_10000    10000   /**< 10 gigabits/second. */
-#define ETH_LINK_SPEED_10G      10000   /**< alias of 10 gigabits/second. */
-#define ETH_LINK_SPEED_20G      20000   /**< 20 gigabits/second. */
-#define ETH_LINK_SPEED_40G      40000   /**< 40 gigabits/second. */
-
 /* Utility constants */
 #define ETH_LINK_AUTONEG_DUPLEX 0       /**< Auto-negotiate duplex. */
 #define ETH_LINK_HALF_DUPLEX    1       /**< Half-duplex connection. */
@@ -779,7 +786,7 @@ struct rte_intr_conf {
  */
 struct rte_eth_conf {
 	uint16_t link_speed;
-	/**< ETH_LINK_SPEED_10[0|00|000], or 0 for autonegotation */
+	/**< ETH_SPEED_NUM_ or 0 for autonegotiation */
 	uint16_t link_duplex;
 	/**< ETH_LINK_[HALF_DUPLEX|FULL_DUPLEX], or 0 for autonegotation */
 	struct rte_eth_rxmode rxmode; /**< Port RX configuration. */
-- 
2.1.4

--------------------------------------------------------------
Intel Research and Development Ireland Limited
Registered in Ireland
Registered Office: Collinstown Industrial Park, Leixlip, County Kildare
Registered Number: 308263


This e-mail and any attachments may contain confidential material for the sole
use of the intended recipient(s). Any review or distribution by others is
strictly prohibited. If you are not the intended recipient, please contact the
sender and delete all copies.

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

* Re: [PATCH v13 4/8] ethdev: rename link speed constants
  2016-04-06  8:34                   ` Weglicki, MichalX
@ 2016-04-06  8:52                     ` Thomas Monjalon
  2016-04-06  9:16                       ` Weglicki, MichalX
  0 siblings, 1 reply; 167+ messages in thread
From: Thomas Monjalon @ 2016-04-06  8:52 UTC (permalink / raw)
  To: Weglicki, MichalX
  Cc: Marc Sune, Xu, Qian Q, Xing, Beilei, dev, Ananyev, Konstantin,
	Lu, Wenzhuo, Richardson, Bruce, Glynn, Michael J, Gray, Mark D

2016-04-06 08:34, Weglicki, MichalX:
> Hello, 
> 
> I have a question about this patch. 
> 
> As far as I see changing ETH_LINK_SPEED_ to ETH_SPEED_NUM_ is rather cosmetic change, am I right? 

No.
ETH_LINK_SPEED was used for configuration and reported speed.
Now the configuration is done with a bitmap filled with new ETH_LINK_SPEED
and the old numerical values are kept for other usages as ETH_SPEED_NUM.

> Disadvantage of that is that it breaks compatibility with OVS (compilation) and thus it also breaks backward compatibility between OVS & DPDK. Is it really necessary? 

Yes that's why this change was discussed 9 months ago and announced in the
previous release notes.

> It would be great to keep ABI & API stable if possible.

We try to keep it stable when possible and continue to bring some improvements.

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

* Re: [PATCH v13 4/8] ethdev: rename link speed constants
  2016-04-06  8:52                     ` Thomas Monjalon
@ 2016-04-06  9:16                       ` Weglicki, MichalX
  2016-04-06  9:34                         ` Thomas Monjalon
  0 siblings, 1 reply; 167+ messages in thread
From: Weglicki, MichalX @ 2016-04-06  9:16 UTC (permalink / raw)
  To: Thomas Monjalon
  Cc: Marc Sune, Xu, Qian Q, Xing, Beilei, dev, Ananyev, Konstantin,
	Lu, Wenzhuo, Richardson, Bruce, Glynn, Michael J, Gray, Mark D

Hello, 

Thank you for your answer. 

I didn't mention that patch is cosmetic, rather naming. 

But all clear, I somehow missed it 9 months ago, and couldn't find it. 

Is there any official place where I can find upcoming ABI & API changes, or I have to dig through mailing list? 

Thank you in advance. 

Br, 
Michal. 

-----Original Message-----
From: Thomas Monjalon [mailto:thomas.monjalon@6wind.com] 
Sent: Wednesday, April 6, 2016 9:53 AM
To: Weglicki, MichalX <michalx.weglicki@intel.com>
Cc: Marc Sune <marcdevel@gmail.com>; Xu, Qian Q <qian.q.xu@intel.com>; Xing, Beilei <beilei.xing@intel.com>; dev@dpdk.org; Ananyev, Konstantin <konstantin.ananyev@intel.com>; Lu, Wenzhuo <wenzhuo.lu@intel.com>; Richardson, Bruce <bruce.richardson@intel.com>; Glynn, Michael J <michael.j.glynn@intel.com>; Gray, Mark D <mark.d.gray@intel.com>
Subject: Re: [dpdk-dev] [PATCH v13 4/8] ethdev: rename link speed constants

2016-04-06 08:34, Weglicki, MichalX:
> Hello, 
> 
> I have a question about this patch. 
> 
> As far as I see changing ETH_LINK_SPEED_ to ETH_SPEED_NUM_ is rather cosmetic change, am I right? 

No.
ETH_LINK_SPEED was used for configuration and reported speed.
Now the configuration is done with a bitmap filled with new ETH_LINK_SPEED
and the old numerical values are kept for other usages as ETH_SPEED_NUM.

> Disadvantage of that is that it breaks compatibility with OVS (compilation) and thus it also breaks backward compatibility between OVS & DPDK. Is it really necessary? 

Yes that's why this change was discussed 9 months ago and announced in the
previous release notes.

> It would be great to keep ABI & API stable if possible.

We try to keep it stable when possible and continue to bring some improvements.

--------------------------------------------------------------
Intel Research and Development Ireland Limited
Registered in Ireland
Registered Office: Collinstown Industrial Park, Leixlip, County Kildare
Registered Number: 308263


This e-mail and any attachments may contain confidential material for the sole
use of the intended recipient(s). Any review or distribution by others is
strictly prohibited. If you are not the intended recipient, please contact the
sender and delete all copies.

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

* Re: [PATCH v13 4/8] ethdev: rename link speed constants
  2016-04-06  9:16                       ` Weglicki, MichalX
@ 2016-04-06  9:34                         ` Thomas Monjalon
  0 siblings, 0 replies; 167+ messages in thread
From: Thomas Monjalon @ 2016-04-06  9:34 UTC (permalink / raw)
  To: Weglicki, MichalX
  Cc: Marc Sune, Xu, Qian Q, Xing, Beilei, dev, Ananyev, Konstantin,
	Lu, Wenzhuo, Richardson, Bruce, Glynn, Michael J, Gray, Mark D

2016-04-06 09:16, Weglicki, MichalX:
> Hello, 
> 
> Thank you for your answer. 
> 
> I didn't mention that patch is cosmetic, rather naming. 
> 
> But all clear, I somehow missed it 9 months ago, and couldn't find it. 
> 
> Is there any official place where I can find upcoming ABI & API changes, or I have to dig through mailing list? 

Yes, the API and ABI changes are described in the release notes:
	http://dpdk.org/browse/dpdk/tree/doc/guides/rel_notes/release_16_04.rst#n471
And the next deprecations are announced in another section:
	http://dpdk.org/browse/dpdk/tree/doc/guides/rel_notes/deprecation.rst

PS: please answer inline

-----------------
> From: Thomas Monjalon [mailto:thomas.monjalon@6wind.com] 
> 2016-04-06 08:34, Weglicki, MichalX:
> > Hello, 
> > 
> > I have a question about this patch. 
> > 
> > As far as I see changing ETH_LINK_SPEED_ to ETH_SPEED_NUM_ is rather cosmetic change, am I right? 
> 
> No.
> ETH_LINK_SPEED was used for configuration and reported speed.
> Now the configuration is done with a bitmap filled with new ETH_LINK_SPEED
> and the old numerical values are kept for other usages as ETH_SPEED_NUM.
> 
> > Disadvantage of that is that it breaks compatibility with OVS (compilation) and thus it also breaks backward compatibility between OVS & DPDK. Is it really necessary? 
> 
> Yes that's why this change was discussed 9 months ago and announced in the
> previous release notes.
> 
> > It would be great to keep ABI & API stable if possible.
> 
> We try to keep it stable when possible and continue to bring some improvements.

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

end of thread, other threads:[~2016-04-06  9:35 UTC | newest]

Thread overview: 167+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
     [not found] <1443993003-1059-1-git-send-email-marcdevel@gmail.com>
2015-10-25 21:59 ` [PATCH v6 0/5] ethdev: add speed capabilities and refactor link API Marc Sune
2015-10-25 21:59   ` [PATCH v6 1/5] ethdev: Added ETH_SPEED_CAP bitmap for ports Marc Sune
2015-11-01 22:11     ` Thomas Monjalon
2015-11-18 23:08       ` Marc Sune
2015-10-25 21:59   ` [PATCH v6 2/5] ethdev: Fill speed capability bitmaps in the PMDs Marc Sune
2015-10-25 21:59   ` [PATCH v6 3/5] ethdev: redesign link speed config API Marc Sune
2015-10-25 22:03     ` Marc Sune
2015-11-01 22:16     ` Thomas Monjalon
2015-11-18 22:59       ` Marc Sune
2015-10-25 21:59   ` [PATCH v6 4/5] doc: update with link changes Marc Sune
2015-10-25 22:00   ` [PATCH v6 5/5] ethdev: add rte_eth_speed_to_bm_flag() to ver. map Marc Sune
2015-12-16 20:37   ` [PATCH v6 0/5] ethdev: add speed capabilities and refactor link API Marc Sune
2015-12-16 20:44     ` Olga Shern
2016-01-29  0:42   ` [PATCH v7 " Marc Sune
2016-01-29  0:42     ` [PATCH v7 1/5] ethdev: Added ETH_SPEED_CAP bitmap for ports Marc Sune
2016-01-29  0:42     ` [PATCH v7 2/5] ethdev: Fill speed capability bitmaps in the PMDs Marc Sune
2016-01-29  0:42     ` [PATCH v7 3/5] ethdev: redesign link speed config API Marc Sune
2016-01-29  9:24       ` Ananyev, Konstantin
2016-01-29  9:37         ` Thomas Monjalon
2016-01-29  9:47           ` Ananyev, Konstantin
2016-01-29  9:53             ` Thomas Monjalon
2016-01-29 10:17               ` Ananyev, Konstantin
2016-01-29 12:40                 ` Marc
2016-02-01  0:40                 ` Zhang, Helin
2016-02-02  0:04                   ` Marc
2016-02-02  0:45                     ` FW: " Zhang, Helin
2016-01-29 16:16       ` Nélio Laranjeiro
2016-01-31 21:24         ` Marc
2016-01-29  0:42     ` [PATCH v7 4/5] doc: update with link changes Marc Sune
2016-01-29  0:42     ` [PATCH v7 5/5] ethdev: add rte_eth_speed_to_bm_flag() to ver. map Marc Sune
2016-01-29 13:05       ` Panu Matilainen
2016-01-31 21:21         ` Marc
2016-02-14 22:17     ` [PATCH v8 0/4] ethdev: add speed capabilities and refactor link API Marc Sune
2016-02-14 22:17       ` [PATCH v8 1/4] ethdev: Added ETH_SPEED_CAP bitmap for ports Marc Sune
2016-02-16 20:42         ` Stephen Hemminger
2016-02-14 22:17       ` [PATCH v8 2/4] ethdev: Fill speed capability bitmaps in the PMDs Marc Sune
2016-02-15  8:43         ` Nélio Laranjeiro
2016-02-15  9:17           ` Chen, Jing D
2016-02-15 14:43         ` Rahul Lakkireddy
2016-02-15 17:14           ` Marc
2016-02-16 15:25             ` Nélio Laranjeiro
2016-02-16 22:49               ` Marc
2016-02-14 22:17       ` [PATCH v8 3/4] ethdev: redesign link speed config API Marc Sune
2016-02-15  8:46         ` Nélio Laranjeiro
2016-02-15 11:00           ` Marc
2016-02-15 11:39             ` Olga Shern
2016-02-16 10:28         ` Matej Vido
2016-02-16 22:55           ` Marc
2016-02-14 22:17       ` [PATCH v8 4/4] doc: update with link changes Marc Sune
2016-02-18 18:14         ` Mcnamara, John
2016-02-28 22:17           ` Marc
2016-03-01  0:45       ` [PATCH v9 0/4] ethdev: add speed capabilities and refactor link API Marc Sune
2016-03-01  0:45         ` [PATCH v9 1/4] ethdev: Added ETH_SPEED_CAP bitmap for ports Marc Sune
2016-03-01  0:45         ` [PATCH v9 2/4] ethdev: Fill speed capability bitmaps in the PMDs Marc Sune
2016-03-01  0:45         ` [PATCH v9 3/4] ethdev: redesign link speed config API Marc Sune
2016-03-09  8:45           ` Nélio Laranjeiro
2016-03-09 10:09             ` Marc
2016-03-09 10:20               ` Nélio Laranjeiro
2016-03-01  0:45         ` [PATCH v9 4/4] doc: update with link changes Marc Sune
2016-03-08 15:00         ` [PATCH v9 0/4] ethdev: add speed capabilities and refactor link API Marc Sune
2016-03-08 16:53           ` Nélio Laranjeiro
2016-03-09  9:29             ` Nélio Laranjeiro
2016-03-09 10:09               ` Nélio Laranjeiro
2016-03-09 20:57                 ` Marc
2016-03-14 21:55         ` [PATCH v10 0/8] ethdev: 100G and link speed API refactoring Thomas Monjalon
2016-03-14 21:55           ` [PATCH v10 1/8] ethdev: use constants for link state Thomas Monjalon
2016-03-15  1:26             ` Zhang, Helin
2016-03-14 21:55           ` [PATCH v10 2/8] ethdev: use constants for link duplex Thomas Monjalon
2016-03-14 21:55           ` [PATCH v10 3/8] app/testpmd: move speed and duplex parsing in a function Thomas Monjalon
2016-03-14 21:55           ` [PATCH v10 4/8] ethdev: rename link speed constants Thomas Monjalon
2016-03-14 21:55           ` [PATCH v10 5/8] ethdev: add speed capabilities Thomas Monjalon
2016-03-14 21:55           ` [PATCH v10 6/8] ethdev: redesign link speed config Thomas Monjalon
2016-03-14 21:55           ` [PATCH v10 7/8] ethdev: convert speed number to bitmap flag Thomas Monjalon
2016-03-14 21:55           ` [PATCH v10 8/8] ethdev: add 100G link speed Thomas Monjalon
2016-03-15  0:04           ` [PATCH v10 0/8] ethdev: 100G and link speed API refactoring Matej Vido
2016-03-15  7:12             ` Thomas Monjalon
2016-03-15  7:45               ` Matej Vido
2016-03-15  8:38           ` Nélio Laranjeiro
2016-03-15 13:12           ` [PATCH 0/4] szedata2: " Matej Vido
2016-03-15 13:12             ` [PATCH 1/4] szedata2: use constants for link state Matej Vido
2016-03-15 13:12             ` [PATCH 2/4] szedata2: rename link speed constants Matej Vido
2016-03-15 13:12             ` [PATCH 3/4] szedata2: redesign link speed config Matej Vido
2016-03-15 13:12             ` [PATCH 4/4] szedata2: add 100G link speed Matej Vido
2016-03-15 13:41               ` Thomas Monjalon
2016-03-15 13:47                 ` Matej Vido
2016-03-15 13:50                 ` Matej Vido
2016-03-15 20:51                   ` Thomas Monjalon
2016-03-17 18:08           ` [PATCH v11 0/8] ethdev: 100G and link speed API refactoring Thomas Monjalon
2016-03-17 18:08             ` [PATCH v11 1/8] ethdev: use constants for link state Thomas Monjalon
2016-03-17 18:08             ` [PATCH v11 2/8] ethdev: use constants for link duplex Thomas Monjalon
2016-03-23  2:44               ` Zhang, Helin
2016-03-23  8:34                 ` Thomas Monjalon
2016-03-17 18:09             ` [PATCH v11 3/8] app/testpmd: move speed and duplex parsing in a function Thomas Monjalon
2016-03-17 18:09             ` [PATCH v11 4/8] ethdev: rename link speed constants Thomas Monjalon
2016-03-23  2:52               ` Zhang, Helin
2016-03-23  8:31                 ` Thomas Monjalon
2016-03-17 18:09             ` [PATCH v11 5/8] ethdev: add speed capabilities Thomas Monjalon
2016-03-18  5:18               ` Chen, Jing D
2016-03-18  8:06                 ` Thomas Monjalon
2016-03-18  9:28               ` Adrien Mazarguil
2016-03-18 10:12                 ` Thomas Monjalon
2016-03-17 18:09             ` [PATCH v11 6/8] ethdev: redesign link speed config Thomas Monjalon
2016-03-17 18:09             ` [PATCH v11 7/8] ethdev: convert speed number to bitmap flag Thomas Monjalon
2016-03-17 18:09             ` [PATCH v11 8/8] ethdev: add 100G link speed Thomas Monjalon
2016-03-22 19:58             ` [PATCH v11 0/8] ethdev: 100G and link speed API refactoring Thomas Monjalon
2016-03-23  1:18               ` Xu, Qian Q
2016-03-23  8:39                 ` Thomas Monjalon
2016-03-23 20:54                 ` Marc
2016-03-24  6:21                   ` Xu, Qian Q
2016-03-24  7:47                     ` Marc
2016-03-25  1:02                       ` Xu, Qian Q
2016-03-25  9:35                         ` Thomas Monjalon
2016-03-25 15:07                           ` Zhang, Helin
2016-03-25 15:32                             ` Thomas Monjalon
2016-03-25 20:41                             ` Marc
2016-03-25 21:30                               ` Marc
2016-03-26  1:25                                 ` Marc
2016-03-26  8:08                                 ` Thomas Monjalon
2016-03-26 10:24                                   ` Marc
2016-03-27  9:53                                     ` Thomas Monjalon
2016-03-27 19:39                                       ` Marc
2016-03-28 13:42                                         ` Thomas Monjalon
2016-03-28 19:11                                           ` Marc
2016-03-24 17:32             ` Matej Vido
2016-03-25 19:42             ` [PATCH v12 " Thomas Monjalon
2016-03-25 19:42               ` [PATCH v12 1/8] ethdev: use constants for link state Thomas Monjalon
2016-03-25 19:42               ` [PATCH v12 2/8] ethdev: use constants for link duplex Thomas Monjalon
2016-03-25 19:42               ` [PATCH v12 3/8] app/testpmd: move speed and duplex parsing in a function Thomas Monjalon
2016-03-25 19:42               ` [PATCH v12 4/8] ethdev: rename link speed constants Thomas Monjalon
2016-03-25 19:42               ` [PATCH v12 5/8] ethdev: add speed capabilities Thomas Monjalon
2016-03-25 19:42               ` [PATCH v12 6/8] ethdev: redesign link speed config Thomas Monjalon
2016-03-25 19:42               ` [PATCH v12 7/8] ethdev: convert speed number to bitmap flag Thomas Monjalon
2016-03-25 19:42               ` [PATCH v12 8/8] ethdev: add 100G link speed Thomas Monjalon
2016-03-26  1:27               ` [PATCH v13 0/8] ethdev: 100G and link speed API refactoring Marc Sune
2016-03-26  1:27                 ` [PATCH v13 1/8] ethdev: use constants for link state Marc Sune
2016-03-26  1:27                 ` [PATCH v13 2/8] ethdev: use constants for link duplex Marc Sune
2016-03-26  1:27                 ` [PATCH v13 3/8] app/testpmd: move speed and duplex parsing in a function Marc Sune
2016-03-26  1:27                 ` [PATCH v13 4/8] ethdev: rename link speed constants Marc Sune
2016-04-06  8:34                   ` Weglicki, MichalX
2016-04-06  8:52                     ` Thomas Monjalon
2016-04-06  9:16                       ` Weglicki, MichalX
2016-04-06  9:34                         ` Thomas Monjalon
2016-03-26  1:27                 ` [PATCH v13 5/8] ethdev: add speed capabilities Marc Sune
2016-03-29 13:31                   ` Alejandro Lucero
2016-03-30  8:06                     ` Marc
2016-03-26  1:27                 ` [PATCH v13 6/8] ethdev: redesign link speed config Marc Sune
2016-03-29  6:18                   ` Xing, Beilei
2016-03-30  7:59                     ` Marc
2016-03-31  0:57                       ` Xing, Beilei
2016-03-31 12:28                         ` Thomas Monjalon
2016-04-01  9:53                           ` Xing, Beilei
2016-03-26  1:27                 ` [PATCH v13 7/8] ethdev: convert speed number to bitmap flag Marc Sune
2016-03-26  1:27                 ` [PATCH v13 8/8] ethdev: add 100G link speed Marc Sune
2016-03-26  8:11                 ` [PATCH v13 0/8] ethdev: 100G and link speed API refactoring Thomas Monjalon
2016-03-31 16:17                   ` Adrien Mazarguil
2016-03-30  9:23                 ` Thomas Monjalon
2016-03-31  6:25                   ` Lu, Wenzhuo
2016-03-31 22:12                 ` [PATCH v14 " Marc Sune
2016-03-31 22:12                   ` [PATCH v14 1/8] ethdev: use constants for link state Marc Sune
2016-03-31 22:12                   ` [PATCH v14 2/8] ethdev: use constants for link duplex Marc Sune
2016-03-31 22:12                   ` [PATCH v14 3/8] app/testpmd: move speed and duplex parsing in a function Marc Sune
2016-03-31 22:12                   ` [PATCH v14 4/8] ethdev: rename link speed constants Marc Sune
2016-03-31 22:12                   ` [PATCH v14 5/8] ethdev: add speed capabilities Marc Sune
2016-03-31 22:12                   ` [PATCH v14 6/8] ethdev: redesign link speed config Marc Sune
2016-03-31 22:12                   ` [PATCH v14 7/8] ethdev: convert speed number to bitmap flag Marc Sune
2016-03-31 22:12                   ` [PATCH v14 8/8] ethdev: add 100G link speed Marc Sune
2016-04-01 19:38                   ` [PATCH v14 0/8] ethdev: 100G and link speed API refactoring Thomas Monjalon

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.