get:
Show a patch.

patch:
Update a patch.

put:
Update a patch.

GET /api/patches/11738/?format=api
HTTP 200 OK
Allow: GET, PUT, PATCH, HEAD, OPTIONS
Content-Type: application/json
Vary: Accept

{
    "id": 11738,
    "url": "http://patches.dpdk.org/api/patches/11738/?format=api",
    "web_url": "http://patches.dpdk.org/project/dpdk/patch/1458934950-23333-7-git-send-email-thomas.monjalon@6wind.com/",
    "project": {
        "id": 1,
        "url": "http://patches.dpdk.org/api/projects/1/?format=api",
        "name": "DPDK",
        "link_name": "dpdk",
        "list_id": "dev.dpdk.org",
        "list_email": "dev@dpdk.org",
        "web_url": "http://core.dpdk.org",
        "scm_url": "git://dpdk.org/dpdk",
        "webscm_url": "http://git.dpdk.org/dpdk",
        "list_archive_url": "https://inbox.dpdk.org/dev",
        "list_archive_url_format": "https://inbox.dpdk.org/dev/{}",
        "commit_url_format": ""
    },
    "msgid": "<1458934950-23333-7-git-send-email-thomas.monjalon@6wind.com>",
    "list_archive_url": "https://inbox.dpdk.org/dev/1458934950-23333-7-git-send-email-thomas.monjalon@6wind.com",
    "date": "2016-03-25T19:42:28",
    "name": "[dpdk-dev,v12,6/8] ethdev: redesign link speed config",
    "commit_ref": null,
    "pull_url": null,
    "state": "superseded",
    "archived": true,
    "hash": "375b061927dffdf30cf1ae0226c8375adc97bc1e",
    "submitter": {
        "id": 1,
        "url": "http://patches.dpdk.org/api/people/1/?format=api",
        "name": "Thomas Monjalon",
        "email": "thomas.monjalon@6wind.com"
    },
    "delegate": {
        "id": 1,
        "url": "http://patches.dpdk.org/api/users/1/?format=api",
        "username": "tmonjalo",
        "first_name": "Thomas",
        "last_name": "Monjalon",
        "email": "thomas@monjalon.net"
    },
    "mbox": "http://patches.dpdk.org/project/dpdk/patch/1458934950-23333-7-git-send-email-thomas.monjalon@6wind.com/mbox/",
    "series": [],
    "comments": "http://patches.dpdk.org/api/patches/11738/comments/",
    "check": "pending",
    "checks": "http://patches.dpdk.org/api/patches/11738/checks/",
    "tags": {},
    "related": [],
    "headers": {
        "Return-Path": "<dev-bounces@dpdk.org>",
        "X-Original-To": "patchwork@dpdk.org",
        "Delivered-To": "patchwork@dpdk.org",
        "Received": [
            "from [92.243.14.124] (localhost [IPv6:::1])\n\tby dpdk.org (Postfix) with ESMTP id 6F1F95962;\n\tFri, 25 Mar 2016 20:44:51 +0100 (CET)",
            "from mail-wm0-f49.google.com (mail-wm0-f49.google.com\n\t[74.125.82.49]) by dpdk.org (Postfix) with ESMTP id 9739058D8\n\tfor <dev@dpdk.org>; Fri, 25 Mar 2016 20:44:45 +0100 (CET)",
            "by mail-wm0-f49.google.com with SMTP id l68so32763356wml.1\n\tfor <dev@dpdk.org>; Fri, 25 Mar 2016 12:44:45 -0700 (PDT)",
            "from XPS13.localdomain (91.111.75.86.rev.sfr.net. [86.75.111.91])\n\tby smtp.gmail.com with ESMTPSA id\n\tu4sm13240660wjz.4.2016.03.25.12.44.42\n\t(version=TLSv1/SSLv3 cipher=OTHER);\n\tFri, 25 Mar 2016 12:44:44 -0700 (PDT)"
        ],
        "DKIM-Signature": "v=1; a=rsa-sha256; c=relaxed/relaxed;\n\td=6wind-com.20150623.gappssmtp.com; s=20150623;\n\th=from:to:cc:subject:date:message-id:in-reply-to:references;\n\tbh=9q53QeWDzz2mP/5IALYka3AUOlnQjgeI2QBqCvNtCHg=;\n\tb=KP4sZE2uRtsA0d4qtHY543jbWP0fioMQ1PX8azUZ56YBpr9LtPNQYSuXnQSlojr0O2\n\tDPi1Rmzwko3MWt5cQPx6xxo/xkBiEQnPJqK45XqaDldN5idVYeOAjDHUvlZ6o++hL9PO\n\tLXUfNxF3bLVeI7j/1DNnfB9XRXGwIaYtF//PmjIvDjvjJgPeJqJtVXxbyOO+8psHR3S6\n\tHuq/wgXiG/a02z25Zi3fQGAKlKDDkZ+ZlykiJE/3fcGOdVftUNG+N3mOwMw59V2Prscl\n\tBAD4MJZRsu0e7z7buQ33JtnTUrhu6j5EGJ9NSCybnRZKcxW4fSmJEQx8Pn8WVDNnRyi5\n\txvbQ==",
        "X-Google-DKIM-Signature": "v=1; a=rsa-sha256; c=relaxed/relaxed;\n\td=1e100.net; s=20130820;\n\th=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to\n\t:references;\n\tbh=9q53QeWDzz2mP/5IALYka3AUOlnQjgeI2QBqCvNtCHg=;\n\tb=dQ23oqQRvGhK1RUT2IwpQHQVkGNNvEwSc+N6TX52nHX2GwuV+9yTuxSeS55rhcQ32l\n\thlROFxGaBPpPQcZkAl6+6ByBk4fGvRoqh+Wwi7kcHpGI0vy/HniVdOKlKTZv/CjRzHoN\n\tQRHwKsrT8TAAV775EbKTyUAKnKdaVglkF9rNzeYambj1slM7lS5Cln/V04dc7evvyA10\n\tZ2igy8M7QD781qkBhAiXYkSEJSMB+pUtZQyK44UWa+10s1+dNNKa3qYl5CI4TwOHWLjI\n\tzkQ0i6hIpqDIEXFlMKfRsDNhgb3ES8TQQbUHo2D3xWbBcu0ZkwgZdSx0EG1BA7u4dOGv\n\tVXPg==",
        "X-Gm-Message-State": "AD7BkJJ2k/TjgEHluQih5KQVDKwaEASBnSplYgQDbomJ0Pe5zZA5XVZjjuKSfte8HjOQxVTL",
        "X-Received": "by 10.28.52.197 with SMTP id b188mr170243wma.77.1458935085483;\n\tFri, 25 Mar 2016 12:44:45 -0700 (PDT)",
        "From": "Thomas Monjalon <thomas.monjalon@6wind.com>",
        "To": "marcdevel@gmail.com, bruce.richardson@intel.com, declan.doherty@intel.com,\n\tkonstantin.ananyev@intel.com, wenzhuo.lu@intel.com,\n\thelin.zhang@intel.com, jing.d.chen@intel.com, harish.patil@qlogic.com,\n\trahul.lakkireddy@chelsio.com, johndale@cisco.com, vido@cesnet.cz,\n\tadrien.mazarguil@6wind.com, alejandro.lucero@netronome.com",
        "Cc": "dev@dpdk.org",
        "Date": "Fri, 25 Mar 2016 20:42:28 +0100",
        "Message-Id": "<1458934950-23333-7-git-send-email-thomas.monjalon@6wind.com>",
        "X-Mailer": "git-send-email 2.7.0",
        "In-Reply-To": "<1458934950-23333-1-git-send-email-thomas.monjalon@6wind.com>",
        "References": "<1458238145-7496-1-git-send-email-thomas.monjalon@6wind.com>\n\t<1458934950-23333-1-git-send-email-thomas.monjalon@6wind.com>",
        "Subject": "[dpdk-dev] [PATCH v12 6/8] ethdev: redesign link speed config",
        "X-BeenThere": "dev@dpdk.org",
        "X-Mailman-Version": "2.1.15",
        "Precedence": "list",
        "List-Id": "patches and discussions about DPDK <dev.dpdk.org>",
        "List-Unsubscribe": "<http://dpdk.org/ml/options/dev>,\n\t<mailto:dev-request@dpdk.org?subject=unsubscribe>",
        "List-Archive": "<http://dpdk.org/ml/archives/dev/>",
        "List-Post": "<mailto:dev@dpdk.org>",
        "List-Help": "<mailto:dev-request@dpdk.org?subject=help>",
        "List-Subscribe": "<http://dpdk.org/ml/listinfo/dev>,\n\t<mailto:dev-request@dpdk.org?subject=subscribe>",
        "Errors-To": "dev-bounces@dpdk.org",
        "Sender": "\"dev\" <dev-bounces@dpdk.org>"
    },
    "content": "From: Marc Sune <marcdevel@gmail.com>\n\nThis patch redesigns the API to set the link speed/s configuration\nof an ethernet port. Specifically:\n\n- it allows to define a set of advertised speeds for\n  auto-negociation.\n- it allows to disable link auto-negociation (single fixed speed).\n- default: auto-negociate all supported speeds.\n\nA flag autoneg in struct rte_eth_link indicates if link speed was a\nresult of auto-negociation or was fixed by configuration.\n\nSigned-off-by: Marc Sune <marcdevel@gmail.com>\nTested-by: Nelio Laranjeiro <nelio.laranjeiro@6wind.com>\nSigned-off-by: Thomas Monjalon <thomas.monjalon@6wind.com>\n---\n\nPLEASE REVIEW CAREFULLY THIS PATCH\n\n app/test-pmd/cmdline.c                    | 26 ++++----\n doc/guides/rel_notes/deprecation.rst      |  3 -\n doc/guides/rel_notes/release_16_04.rst    |  9 +++\n drivers/net/af_packet/rte_eth_af_packet.c |  1 +\n drivers/net/bnx2x/bnx2x_ethdev.c          |  4 +-\n drivers/net/bonding/rte_eth_bond_8023ad.c |  2 +-\n drivers/net/e1000/em_ethdev.c             | 99 +++++++++++++++----------------\n drivers/net/e1000/igb_ethdev.c            | 94 +++++++++++++++--------------\n drivers/net/i40e/i40e_ethdev.c            | 48 +++++++--------\n drivers/net/i40e/i40e_ethdev_vf.c         |  7 ++-\n drivers/net/ixgbe/ixgbe_ethdev.c          | 46 ++++++--------\n drivers/net/mlx4/mlx4.c                   |  2 +\n drivers/net/mpipe/mpipe_tilegx.c          |  2 +\n drivers/net/null/rte_eth_null.c           |  1 +\n drivers/net/pcap/rte_eth_pcap.c           |  1 +\n drivers/net/ring/rte_eth_ring.c           |  1 +\n drivers/net/szedata2/rte_eth_szedata2.c   |  2 +\n drivers/net/vmxnet3/vmxnet3_ethdev.c      |  1 +\n drivers/net/xenvirt/rte_eth_xenvirt.c     |  1 +\n examples/ip_pipeline/config_parse.c       |  3 +-\n lib/librte_ether/rte_ethdev.h             | 29 +++++----\n 21 files changed, 196 insertions(+), 186 deletions(-)",
    "diff": "diff --git a/app/test-pmd/cmdline.c b/app/test-pmd/cmdline.c\nindex 815b53b..741cac3 100644\n--- a/app/test-pmd/cmdline.c\n+++ b/app/test-pmd/cmdline.c\n@@ -989,7 +989,7 @@ struct cmd_config_speed_all {\n };\n \n static int\n-parse_and_check_speed_duplex(char *speedstr, char *duplexstr, uint16_t *speed)\n+parse_and_check_speed_duplex(char *speedstr, char *duplexstr, uint32_t *speed)\n {\n \n \tint duplex;\n@@ -1006,20 +1006,22 @@ parse_and_check_speed_duplex(char *speedstr, char *duplexstr, uint16_t *speed)\n \t}\n \n \tif (!strcmp(speedstr, \"10\")) {\n-\t\t*speed = ETH_SPEED_NUM_10M;\n+\t\t*speed = (duplex == ETH_LINK_HALF_DUPLEX) ?\n+\t\t\t\tETH_LINK_SPEED_10M_HD : ETH_LINK_SPEED_10M;\n \t} else if (!strcmp(speedstr, \"100\")) {\n-\t\t*speed = ETH_SPEED_NUM_100M;\n+\t\t*speed = (duplex == ETH_LINK_HALF_DUPLEX) ?\n+\t\t\t\tETH_LINK_SPEED_100M_HD : ETH_LINK_SPEED_100M;\n \t} else {\n \t\tif (duplex != ETH_LINK_FULL_DUPLEX) {\n \t\t\tprintf(\"Invalid speed/duplex parameters\\n\");\n \t\t\treturn -1;\n \t\t}\n \t\tif (!strcmp(speedstr, \"1000\")) {\n-\t\t\t*speed = ETH_SPEED_NUM_1G;\n+\t\t\t*speed = ETH_LINK_SPEED_1G;\n \t\t} else if (!strcmp(speedstr, \"10000\")) {\n-\t\t\t*speed = ETH_SPEED_NUM_10G;\n+\t\t\t*speed = ETH_LINK_SPEED_10G;\n \t\t} else if (!strcmp(speedstr, \"40000\")) {\n-\t\t\t*speed = ETH_SPEED_NUM_40G;\n+\t\t\t*speed = ETH_LINK_SPEED_40G;\n \t\t} else if (!strcmp(speedstr, \"auto\")) {\n \t\t\t*speed = ETH_LINK_SPEED_AUTONEG;\n \t\t} else {\n@@ -1037,8 +1039,7 @@ cmd_config_speed_all_parsed(void *parsed_result,\n \t\t\t__attribute__((unused)) void *data)\n {\n \tstruct cmd_config_speed_all *res = parsed_result;\n-\tuint16_t link_speed = ETH_LINK_SPEED_AUTONEG;\n-\tuint16_t link_duplex = 0;\n+\tuint32_t link_speed;\n \tportid_t pid;\n \n \tif (!all_ports_stopped()) {\n@@ -1051,8 +1052,7 @@ cmd_config_speed_all_parsed(void *parsed_result,\n \t\treturn;\n \n \tFOREACH_PORT(pid, ports) {\n-\t\tports[pid].dev_conf.link_speed = link_speed;\n-\t\tports[pid].dev_conf.link_duplex = link_duplex;\n+\t\tports[pid].dev_conf.link_speeds = link_speed;\n \t}\n \n \tcmd_reconfig_device_queue(RTE_PORT_ALL, 1, 1);\n@@ -1110,8 +1110,7 @@ cmd_config_speed_specific_parsed(void *parsed_result,\n \t\t\t\t__attribute__((unused)) void *data)\n {\n \tstruct cmd_config_speed_specific *res = parsed_result;\n-\tuint16_t link_speed = ETH_LINK_SPEED_AUTONEG;\n-\tuint16_t link_duplex = 0;\n+\tuint32_t link_speed;\n \n \tif (!all_ports_stopped()) {\n \t\tprintf(\"Please stop all ports first\\n\");\n@@ -1125,8 +1124,7 @@ cmd_config_speed_specific_parsed(void *parsed_result,\n \t\t\t&link_speed) < 0)\n \t\treturn;\n \n-\tports[res->id].dev_conf.link_speed = link_speed;\n-\tports[res->id].dev_conf.link_duplex = link_duplex;\n+\tports[res->id].dev_conf.link_speeds = link_speed;\n \n \tcmd_reconfig_device_queue(RTE_PORT_ALL, 1, 1);\n }\ndiff --git a/doc/guides/rel_notes/deprecation.rst b/doc/guides/rel_notes/deprecation.rst\nindex 179e30f..c47610d 100644\n--- a/doc/guides/rel_notes/deprecation.rst\n+++ b/doc/guides/rel_notes/deprecation.rst\n@@ -19,9 +19,6 @@ Deprecation Notices\n   ibadcrc, ibadlen, imcasts, fdirmatch, fdirmiss,\n   tx_pause_xon, rx_pause_xon, tx_pause_xoff, rx_pause_xoff\n \n-* The ethdev structures rte_eth_link, rte_eth_dev_info and rte_eth_conf\n-  must be updated to support 100G link and to have a cleaner link speed API.\n-\n * ABI changes are planned for adding four new flow types. This impacts\n   RTE_ETH_FLOW_MAX. The release 2.2 does not contain these ABI changes,\n   but release 2.3 will. [postponed]\ndiff --git a/doc/guides/rel_notes/release_16_04.rst b/doc/guides/rel_notes/release_16_04.rst\nindex 9e7b0b7..c891a55 100644\n--- a/doc/guides/rel_notes/release_16_04.rst\n+++ b/doc/guides/rel_notes/release_16_04.rst\n@@ -52,6 +52,12 @@ This section should contain new features added in this release. Sample format:\n   The structure ``rte_eth_dev_info`` has now a ``speed_capa`` bitmap, which\n   allows the application to know the supported speeds of each device.\n \n+* **Added bitmap of link speeds to advertise.**\n+\n+  Allow defining a set of advertised speeds for auto-negotiation,\n+  explicitly disabling link auto-negotiation (single speed)\n+  and full auto-negotiation.\n+\n * **Added new poll-mode driver for Amazon Elastic Network Adapters (ENA).**\n \n   The driver operates variety of ENA adapters through feature negotiation\n@@ -464,6 +470,9 @@ This section should contain API changes. Sample format:\n * The ethdev structure ``rte_eth_dev_info`` was changed to support device\n   speed capabilities.\n \n+* The ethdev structures ``rte_eth_link`` and ``rte_eth_conf`` were changed to\n+  support the new link API.\n+\n * The functions ``rte_eth_dev_udp_tunnel_add`` and ``rte_eth_dev_udp_tunnel_delete``\n   have been renamed into ``rte_eth_dev_udp_tunnel_port_add`` and\n   ``rte_eth_dev_udp_tunnel_port_delete``.\ndiff --git a/drivers/net/af_packet/rte_eth_af_packet.c b/drivers/net/af_packet/rte_eth_af_packet.c\nindex 641f849..f17bd7e 100644\n--- a/drivers/net/af_packet/rte_eth_af_packet.c\n+++ b/drivers/net/af_packet/rte_eth_af_packet.c\n@@ -119,6 +119,7 @@ static struct rte_eth_link pmd_link = {\n \t.link_speed = ETH_SPEED_NUM_10G,\n \t.link_duplex = ETH_LINK_FULL_DUPLEX,\n \t.link_status = ETH_LINK_DOWN,\n+\t.link_autoneg = ETH_LINK_SPEED_AUTONEG\n };\n \n static uint16_t\ndiff --git a/drivers/net/bnx2x/bnx2x_ethdev.c b/drivers/net/bnx2x/bnx2x_ethdev.c\nindex 897081f..af84175 100644\n--- a/drivers/net/bnx2x/bnx2x_ethdev.c\n+++ b/drivers/net/bnx2x/bnx2x_ethdev.c\n@@ -44,9 +44,9 @@ bnx2x_link_update(struct rte_eth_dev *dev)\n \t\tcase DUPLEX_HALF:\n \t\t\tdev->data->dev_link.link_duplex = ETH_LINK_HALF_DUPLEX;\n \t\t\tbreak;\n-\t\tdefault:\n-\t\t\tdev->data->dev_link.link_duplex = ETH_LINK_AUTONEG_DUPLEX;\n \t}\n+\tdev->data->dev_link.link_autoneg = (dev->data->dev_conf.link_speeds &\n+\t\t\tETH_LINK_SPEED_AUTONEG);\n \tdev->data->dev_link.link_status = sc->link_vars.link_up;\n }\n \ndiff --git a/drivers/net/bonding/rte_eth_bond_8023ad.c b/drivers/net/bonding/rte_eth_bond_8023ad.c\nindex ac8306f..cca7cc3 100644\n--- a/drivers/net/bonding/rte_eth_bond_8023ad.c\n+++ b/drivers/net/bonding/rte_eth_bond_8023ad.c\n@@ -708,7 +708,7 @@ link_speed_key(uint16_t speed) {\n \tuint16_t key_speed;\n \n \tswitch (speed) {\n-\tcase ETH_LINK_SPEED_AUTONEG:\n+\tcase ETH_SPEED_NUM_NONE:\n \t\tkey_speed = 0x00;\n \t\tbreak;\n \tcase ETH_SPEED_NUM_10M:\ndiff --git a/drivers/net/e1000/em_ethdev.c b/drivers/net/e1000/em_ethdev.c\nindex d5f8c7f..3e26ab0 100644\n--- a/drivers/net/e1000/em_ethdev.c\n+++ b/drivers/net/e1000/em_ethdev.c\n@@ -538,6 +538,9 @@ eth_em_start(struct rte_eth_dev *dev)\n \tstruct rte_intr_handle *intr_handle = &dev->pci_dev->intr_handle;\n \tint ret, mask;\n \tuint32_t intr_vector = 0;\n+\tuint32_t *speeds;\n+\tint num_speeds;\n+\tbool autoneg;\n \n \tPMD_INIT_FUNC_TRACE();\n \n@@ -612,56 +615,46 @@ eth_em_start(struct rte_eth_dev *dev)\n \tE1000_WRITE_REG(hw, E1000_ITR, UINT16_MAX);\n \n \t/* Setup link speed and duplex */\n-\tswitch (dev->data->dev_conf.link_speed) {\n-\tcase ETH_LINK_SPEED_AUTONEG:\n-\t\tif (dev->data->dev_conf.link_duplex == ETH_LINK_AUTONEG_DUPLEX)\n-\t\t\thw->phy.autoneg_advertised = E1000_ALL_SPEED_DUPLEX;\n-\t\telse if (dev->data->dev_conf.link_duplex ==\n-\t\t\t\t\tETH_LINK_HALF_DUPLEX)\n-\t\t\thw->phy.autoneg_advertised = E1000_ALL_HALF_DUPLEX;\n-\t\telse if (dev->data->dev_conf.link_duplex ==\n-\t\t\t\t\tETH_LINK_FULL_DUPLEX)\n-\t\t\thw->phy.autoneg_advertised = E1000_ALL_FULL_DUPLEX;\n-\t\telse\n-\t\t\tgoto error_invalid_config;\n-\t\tbreak;\n-\tcase ETH_SPEED_NUM_10M:\n-\t\tif (dev->data->dev_conf.link_duplex == ETH_LINK_AUTONEG_DUPLEX)\n-\t\t\thw->phy.autoneg_advertised = E1000_ALL_10_SPEED;\n-\t\telse if (dev->data->dev_conf.link_duplex ==\n-\t\t\t\t\tETH_LINK_HALF_DUPLEX)\n-\t\t\thw->phy.autoneg_advertised = ADVERTISE_10_HALF;\n-\t\telse if (dev->data->dev_conf.link_duplex ==\n-\t\t\t\t\tETH_LINK_FULL_DUPLEX)\n-\t\t\thw->phy.autoneg_advertised = ADVERTISE_10_FULL;\n-\t\telse\n-\t\t\tgoto error_invalid_config;\n-\t\tbreak;\n-\tcase ETH_SPEED_NUM_100M:\n-\t\tif (dev->data->dev_conf.link_duplex == ETH_LINK_AUTONEG_DUPLEX)\n-\t\t\thw->phy.autoneg_advertised = E1000_ALL_100_SPEED;\n-\t\telse if (dev->data->dev_conf.link_duplex ==\n-\t\t\t\t\tETH_LINK_HALF_DUPLEX)\n-\t\t\thw->phy.autoneg_advertised = ADVERTISE_100_HALF;\n-\t\telse if (dev->data->dev_conf.link_duplex ==\n-\t\t\t\t\tETH_LINK_FULL_DUPLEX)\n-\t\t\thw->phy.autoneg_advertised = ADVERTISE_100_FULL;\n-\t\telse\n+\tspeeds = &dev->data->dev_conf.link_speeds;\n+\tif (*speeds == ETH_LINK_SPEED_AUTONEG) {\n+\t\thw->phy.autoneg_advertised = E1000_ALL_SPEED_DUPLEX;\n+\t} else {\n+\t\tnum_speeds = 0;\n+\t\tautoneg = (*speeds & ETH_LINK_SPEED_AUTONEG);\n+\n+\t\t/* Reset */\n+\t\thw->phy.autoneg_advertised = 0;\n+\n+\t\tif (*speeds & ~(ETH_LINK_SPEED_10M_HD | ETH_LINK_SPEED_10M |\n+\t\t\t\tETH_LINK_SPEED_100M_HD | ETH_LINK_SPEED_100M |\n+\t\t\t\tETH_LINK_SPEED_1G)) {\n+\t\t\tnum_speeds = -1;\n \t\t\tgoto error_invalid_config;\n-\t\tbreak;\n-\tcase ETH_SPEED_NUM_1G:\n-\t\tif ((dev->data->dev_conf.link_duplex ==\n-\t\t\t\tETH_LINK_AUTONEG_DUPLEX) ||\n-\t\t\t(dev->data->dev_conf.link_duplex ==\n-\t\t\t\t\tETH_LINK_FULL_DUPLEX))\n-\t\t\thw->phy.autoneg_advertised = ADVERTISE_1000_FULL;\n-\t\telse\n+\t\t}\n+\t\tif (*speeds & ETH_LINK_SPEED_10M_HD) {\n+\t\t\thw->phy.autoneg_advertised |= ADVERTISE_10_HALF;\n+\t\t\tnum_speeds++;\n+\t\t}\n+\t\tif (*speeds & ETH_LINK_SPEED_10M) {\n+\t\t\thw->phy.autoneg_advertised |= ADVERTISE_10_FULL;\n+\t\t\tnum_speeds++;\n+\t\t}\n+\t\tif (*speeds & ETH_LINK_SPEED_100M_HD) {\n+\t\t\thw->phy.autoneg_advertised |= ADVERTISE_100_HALF;\n+\t\t\tnum_speeds++;\n+\t\t}\n+\t\tif (*speeds & ETH_LINK_SPEED_100M) {\n+\t\t\thw->phy.autoneg_advertised |= ADVERTISE_100_FULL;\n+\t\t\tnum_speeds++;\n+\t\t}\n+\t\tif (*speeds & ETH_LINK_SPEED_1G) {\n+\t\t\thw->phy.autoneg_advertised |= ADVERTISE_1000_FULL;\n+\t\t\tnum_speeds++;\n+\t\t}\n+\t\tif (num_speeds == 0 || (!autoneg && (num_speeds > 2)))\n \t\t\tgoto error_invalid_config;\n-\t\tbreak;\n-\tcase ETH_SPEED_NUM_10G:\n-\tdefault:\n-\t\tgoto error_invalid_config;\n \t}\n+\n \te1000_setup_link(hw);\n \n \tif (rte_intr_allow_others(intr_handle)) {\n@@ -694,9 +687,8 @@ eth_em_start(struct rte_eth_dev *dev)\n \treturn 0;\n \n error_invalid_config:\n-\tPMD_INIT_LOG(ERR, \"Invalid link_speed/link_duplex (%u/%u) for port %u\",\n-\t\t     dev->data->dev_conf.link_speed,\n-\t\t     dev->data->dev_conf.link_duplex, dev->data->port_id);\n+\tPMD_INIT_LOG(ERR, \"Invalid advertised speeds (%u) for port %u\",\n+\t\t     dev->data->dev_conf.link_speeds, dev->data->port_id);\n \tem_dev_clear_queues(dev);\n \treturn -EINVAL;\n }\n@@ -1106,8 +1098,11 @@ eth_em_link_update(struct rte_eth_dev *dev, int wait_to_complete)\n \n \t/* Now we check if a transition has happened */\n \tif (link_check && (link.link_status == ETH_LINK_DOWN)) {\n-\t\thw->mac.ops.get_link_up_info(hw, &link.link_speed,\n-\t\t\t&link.link_duplex);\n+\t\tuint16_t duplex, speed;\n+\t\thw->mac.ops.get_link_up_info(hw, &speed, &duplex);\n+\t\tlink.link_duplex = duplex ? ETH_LINK_FULL_DUPLEX :\n+\t\t\t\tETH_LINK_HALF_DUPLEX;\n+\t\tlink.link_speed = speed;\n \t\tlink.link_status = ETH_LINK_UP;\n \t} else if (!link_check && (link.link_status == ETH_LINK_UP)) {\n \t\tlink.link_speed = 0;\ndiff --git a/drivers/net/e1000/igb_ethdev.c b/drivers/net/e1000/igb_ethdev.c\nindex 95d1711..ced864c 100644\n--- a/drivers/net/e1000/igb_ethdev.c\n+++ b/drivers/net/e1000/igb_ethdev.c\n@@ -1133,6 +1133,9 @@ eth_igb_start(struct rte_eth_dev *dev)\n \tint ret, mask;\n \tuint32_t intr_vector = 0;\n \tuint32_t ctrl_ext;\n+\tuint32_t *speeds;\n+\tint num_speeds;\n+\tbool autoneg;\n \n \tPMD_INIT_FUNC_TRACE();\n \n@@ -1233,48 +1236,46 @@ eth_igb_start(struct rte_eth_dev *dev)\n \t}\n \n \t/* Setup link speed and duplex */\n-\tswitch (dev->data->dev_conf.link_speed) {\n-\tcase ETH_LINK_SPEED_AUTONEG:\n-\t\tif (dev->data->dev_conf.link_duplex == ETH_LINK_AUTONEG_DUPLEX)\n-\t\t\thw->phy.autoneg_advertised = E1000_ALL_SPEED_DUPLEX;\n-\t\telse if (dev->data->dev_conf.link_duplex == ETH_LINK_HALF_DUPLEX)\n-\t\t\thw->phy.autoneg_advertised = E1000_ALL_HALF_DUPLEX;\n-\t\telse if (dev->data->dev_conf.link_duplex == ETH_LINK_FULL_DUPLEX)\n-\t\t\thw->phy.autoneg_advertised = E1000_ALL_FULL_DUPLEX;\n-\t\telse\n-\t\t\tgoto error_invalid_config;\n-\t\tbreak;\n-\tcase ETH_SPEED_NUM_10M:\n-\t\tif (dev->data->dev_conf.link_duplex == ETH_LINK_AUTONEG_DUPLEX)\n-\t\t\thw->phy.autoneg_advertised = E1000_ALL_10_SPEED;\n-\t\telse if (dev->data->dev_conf.link_duplex == ETH_LINK_HALF_DUPLEX)\n-\t\t\thw->phy.autoneg_advertised = ADVERTISE_10_HALF;\n-\t\telse if (dev->data->dev_conf.link_duplex == ETH_LINK_FULL_DUPLEX)\n-\t\t\thw->phy.autoneg_advertised = ADVERTISE_10_FULL;\n-\t\telse\n-\t\t\tgoto error_invalid_config;\n-\t\tbreak;\n-\tcase ETH_SPEED_NUM_100M:\n-\t\tif (dev->data->dev_conf.link_duplex == ETH_LINK_AUTONEG_DUPLEX)\n-\t\t\thw->phy.autoneg_advertised = E1000_ALL_100_SPEED;\n-\t\telse if (dev->data->dev_conf.link_duplex == ETH_LINK_HALF_DUPLEX)\n-\t\t\thw->phy.autoneg_advertised = ADVERTISE_100_HALF;\n-\t\telse if (dev->data->dev_conf.link_duplex == ETH_LINK_FULL_DUPLEX)\n-\t\t\thw->phy.autoneg_advertised = ADVERTISE_100_FULL;\n-\t\telse\n+\tspeeds = &dev->data->dev_conf.link_speeds;\n+\tif (*speeds == ETH_LINK_SPEED_AUTONEG) {\n+\t\thw->phy.autoneg_advertised = E1000_ALL_SPEED_DUPLEX;\n+\t} else {\n+\t\tnum_speeds = 0;\n+\t\tautoneg = (*speeds & ETH_LINK_SPEED_AUTONEG);\n+\n+\t\t/* Reset */\n+\t\thw->phy.autoneg_advertised = 0;\n+\n+\t\tif (*speeds & ~(ETH_LINK_SPEED_10M_HD | ETH_LINK_SPEED_10M |\n+\t\t\t\tETH_LINK_SPEED_100M_HD | ETH_LINK_SPEED_100M |\n+\t\t\t\tETH_LINK_SPEED_1G)) {\n+\t\t\tnum_speeds = -1;\n \t\t\tgoto error_invalid_config;\n-\t\tbreak;\n-\tcase ETH_SPEED_NUM_1G:\n-\t\tif ((dev->data->dev_conf.link_duplex == ETH_LINK_AUTONEG_DUPLEX) ||\n-\t\t\t\t(dev->data->dev_conf.link_duplex == ETH_LINK_FULL_DUPLEX))\n-\t\t\thw->phy.autoneg_advertised = ADVERTISE_1000_FULL;\n-\t\telse\n+\t\t}\n+\t\tif (*speeds & ETH_LINK_SPEED_10M_HD) {\n+\t\t\thw->phy.autoneg_advertised |= ADVERTISE_10_HALF;\n+\t\t\tnum_speeds++;\n+\t\t}\n+\t\tif (*speeds & ETH_LINK_SPEED_10M) {\n+\t\t\thw->phy.autoneg_advertised |= ADVERTISE_10_FULL;\n+\t\t\tnum_speeds++;\n+\t\t}\n+\t\tif (*speeds & ETH_LINK_SPEED_100M_HD) {\n+\t\t\thw->phy.autoneg_advertised |= ADVERTISE_100_HALF;\n+\t\t\tnum_speeds++;\n+\t\t}\n+\t\tif (*speeds & ETH_LINK_SPEED_100M) {\n+\t\t\thw->phy.autoneg_advertised |= ADVERTISE_100_FULL;\n+\t\t\tnum_speeds++;\n+\t\t}\n+\t\tif (*speeds & ETH_LINK_SPEED_1G) {\n+\t\t\thw->phy.autoneg_advertised |= ADVERTISE_1000_FULL;\n+\t\t\tnum_speeds++;\n+\t\t}\n+\t\tif (num_speeds == 0 || (!autoneg && (num_speeds > 2)))\n \t\t\tgoto error_invalid_config;\n-\t\tbreak;\n-\tcase ETH_SPEED_NUM_10G:\n-\tdefault:\n-\t\tgoto error_invalid_config;\n \t}\n+\n \te1000_setup_link(hw);\n \n \tif (rte_intr_allow_others(intr_handle)) {\n@@ -1306,9 +1307,8 @@ eth_igb_start(struct rte_eth_dev *dev)\n \treturn 0;\n \n error_invalid_config:\n-\tPMD_INIT_LOG(ERR, \"Invalid link_speed/link_duplex (%u/%u) for port %u\",\n-\t\t     dev->data->dev_conf.link_speed,\n-\t\t     dev->data->dev_conf.link_duplex, dev->data->port_id);\n+\tPMD_INIT_LOG(ERR, \"Invalid advertised speeds (%u) for port %u\",\n+\t\t     dev->data->dev_conf.link_speeds, dev->data->port_id);\n \tigb_dev_clear_queues(dev);\n \treturn -EINVAL;\n }\n@@ -2061,13 +2061,19 @@ eth_igb_link_update(struct rte_eth_dev *dev, int wait_to_complete)\n \n \t/* Now we check if a transition has happened */\n \tif (link_check) {\n-\t\thw->mac.ops.get_link_up_info(hw, &link.link_speed,\n-\t\t\t\t\t  &link.link_duplex);\n+\t\tuint16_t duplex, speed;\n+\t\thw->mac.ops.get_link_up_info(hw, &speed, &duplex);\n+\t\tlink.link_duplex = duplex ? ETH_LINK_FULL_DUPLEX :\n+\t\t\t\tETH_LINK_HALF_DUPLEX;\n+\t\tlink.link_speed = speed;\n \t\tlink.link_status = ETH_LINK_UP;\n+\t\tlink.link_autoneg = (dev->data->dev_conf.link_speeds &\n+\t\t\t\tETH_LINK_SPEED_AUTONEG);\n \t} else if (!link_check) {\n \t\tlink.link_speed = 0;\n \t\tlink.link_duplex = ETH_LINK_HALF_DUPLEX;\n \t\tlink.link_status = ETH_LINK_DOWN;\n+\t\tlink.link_autoneg = ETH_LINK_SPEED_FIXED;\n \t}\n \trte_igb_dev_atomic_write_link_status(dev, &link);\n \ndiff --git a/drivers/net/i40e/i40e_ethdev.c b/drivers/net/i40e/i40e_ethdev.c\nindex dce31db..87bc767 100644\n--- a/drivers/net/i40e/i40e_ethdev.c\n+++ b/drivers/net/i40e/i40e_ethdev.c\n@@ -1381,27 +1381,20 @@ i40e_vsi_disable_queues_intr(struct i40e_vsi *vsi)\n }\n \n static inline uint8_t\n-i40e_parse_link_speed(uint16_t eth_link_speed)\n+i40e_parse_link_speeds(uint16_t link_speeds)\n {\n \tuint8_t link_speed = I40E_LINK_SPEED_UNKNOWN;\n \n-\tswitch (eth_link_speed) {\n-\tcase ETH_SPEED_NUM_40G:\n-\t\tlink_speed = I40E_LINK_SPEED_40GB;\n-\t\tbreak;\n-\tcase ETH_SPEED_NUM_20G:\n-\t\tlink_speed = I40E_LINK_SPEED_20GB;\n-\t\tbreak;\n-\tcase ETH_SPEED_NUM_10G:\n-\t\tlink_speed = I40E_LINK_SPEED_10GB;\n-\t\tbreak;\n-\tcase ETH_SPEED_NUM_1G:\n-\t\tlink_speed = I40E_LINK_SPEED_1GB;\n-\t\tbreak;\n-\tcase ETH_SPEED_NUM_100M:\n-\t\tlink_speed = I40E_LINK_SPEED_100MB;\n-\t\tbreak;\n-\t}\n+\tif (link_speeds & ETH_LINK_SPEED_40G)\n+\t\tlink_speed |= I40E_LINK_SPEED_40GB;\n+\tif (link_speeds & ETH_LINK_SPEED_20G)\n+\t\tlink_speed |= I40E_LINK_SPEED_20GB;\n+\tif (link_speeds & ETH_LINK_SPEED_10G)\n+\t\tlink_speed |= I40E_LINK_SPEED_10GB;\n+\tif (link_speeds & ETH_LINK_SPEED_1G)\n+\t\tlink_speed |= I40E_LINK_SPEED_1GB;\n+\tif (link_speeds & ETH_LINK_SPEED_100M)\n+\t\tlink_speed |= I40E_LINK_SPEED_100MB;\n \n \treturn link_speed;\n }\n@@ -1427,9 +1420,9 @@ i40e_apply_link_speed(struct rte_eth_dev *dev)\n \tstruct i40e_hw *hw = I40E_DEV_PRIVATE_TO_HW(dev->data->dev_private);\n \tstruct rte_eth_conf *conf = &dev->data->dev_conf;\n \n-\tspeed = i40e_parse_link_speed(conf->link_speed);\n+\tspeed = i40e_parse_link_speeds(conf->link_speeds);\n \tabilities |= I40E_AQ_PHY_ENABLE_ATOMIC_LINK;\n-\tif (conf->link_speed == ETH_LINK_SPEED_AUTONEG)\n+\tif (conf->link_speeds & ETH_LINK_SPEED_AUTONEG)\n \t\tabilities |= I40E_AQ_PHY_AN_ENABLED;\n \telse\n \t\tabilities |= I40E_AQ_PHY_LINK_ENABLED;\n@@ -1449,10 +1442,8 @@ i40e_dev_start(struct rte_eth_dev *dev)\n \n \thw->adapter_stopped = 0;\n \n-\tif ((dev->data->dev_conf.link_duplex != ETH_LINK_AUTONEG_DUPLEX) &&\n-\t\t(dev->data->dev_conf.link_duplex != ETH_LINK_FULL_DUPLEX)) {\n-\t\tPMD_INIT_LOG(ERR, \"Invalid link_duplex (%hu) for port %hhu\",\n-\t\t\t     dev->data->dev_conf.link_duplex,\n+\tif (!(dev->data->dev_conf.link_speeds & ETH_LINK_SPEED_AUTONEG)) {\n+\t\tPMD_INIT_LOG(ERR, \"Invalid link_speeds for port %hhu; autonegotiation disabled\",\n \t\t\t     dev->data->port_id);\n \t\treturn -EINVAL;\n \t}\n@@ -1525,6 +1516,12 @@ i40e_dev_start(struct rte_eth_dev *dev)\n \t}\n \n \t/* Apply link configure */\n+\tif (dev->data->dev_conf.link_speeds & ~(ETH_LINK_SPEED_100M |\n+\t\t\t\tETH_LINK_SPEED_1G | ETH_LINK_SPEED_10G |\n+\t\t\t\tETH_LINK_SPEED_20G | ETH_LINK_SPEED_40G)) {\n+\t\tPMD_DRV_LOG(ERR, \"Invalid link setting\");\n+\t\tgoto err_up;\n+\t}\n \tret = i40e_apply_link_speed(dev);\n \tif (I40E_SUCCESS != ret) {\n \t\tPMD_DRV_LOG(ERR, \"Fail to apply link setting\");\n@@ -1809,6 +1806,9 @@ i40e_dev_link_update(struct rte_eth_dev *dev,\n \t\tbreak;\n \t}\n \n+\tlink.link_autoneg = (dev->data->dev_conf.link_speeds &\n+\t\t\tETH_LINK_SPEED_AUTONEG);\n+\n out:\n \trte_i40e_dev_atomic_write_link_status(dev, &link);\n \tif (link.link_status == old.link_status)\ndiff --git a/drivers/net/i40e/i40e_ethdev_vf.c b/drivers/net/i40e/i40e_ethdev_vf.c\nindex 295dcd2..8cf22ee 100644\n--- a/drivers/net/i40e/i40e_ethdev_vf.c\n+++ b/drivers/net/i40e/i40e_ethdev_vf.c\n@@ -2121,12 +2121,13 @@ i40evf_dev_link_update(struct rte_eth_dev *dev,\n \t * DPDK pf host provide interfacet to acquire link status\n \t * while Linux driver does not\n \t */\n-\tif (vf->version_major == I40E_DPDK_VERSION_MAJOR)\n+\tif (vf->version_major == I40E_DPDK_VERSION_MAJOR) {\n \t\ti40evf_get_link_status(dev, &new_link);\n-\telse {\n+\t} else {\n \t\t/* Always assume it's up, for Linux driver PF host */\n-\t\tnew_link.link_duplex = ETH_LINK_AUTONEG_DUPLEX;\n \t\tnew_link.link_speed  = ETH_SPEED_NUM_10G;\n+\t\tnew_link.link_duplex = ETH_LINK_FULL_DUPLEX;\n+\t\tnew_link.link_autoneg = ETH_LINK_SPEED_AUTONEG;\n \t\tnew_link.link_status = ETH_LINK_UP;\n \t}\n \ti40evf_dev_atomic_write_link_status(dev, &new_link);\ndiff --git a/drivers/net/ixgbe/ixgbe_ethdev.c b/drivers/net/ixgbe/ixgbe_ethdev.c\nindex a98e8eb..ff23d7d 100644\n--- a/drivers/net/ixgbe/ixgbe_ethdev.c\n+++ b/drivers/net/ixgbe/ixgbe_ethdev.c\n@@ -2094,14 +2094,13 @@ ixgbe_dev_start(struct rte_eth_dev *dev)\n \tint mask = 0;\n \tint status;\n \tuint16_t vf, idx;\n+\tuint32_t *link_speeds;\n \n \tPMD_INIT_FUNC_TRACE();\n \n \t/* IXGBE devices don't support half duplex */\n-\tif ((dev->data->dev_conf.link_duplex != ETH_LINK_AUTONEG_DUPLEX) &&\n-\t\t\t(dev->data->dev_conf.link_duplex != ETH_LINK_FULL_DUPLEX)) {\n-\t\tPMD_INIT_LOG(ERR, \"Invalid link_duplex (%hu) for port %hhu\",\n-\t\t\t     dev->data->dev_conf.link_duplex,\n+\tif (!(dev->data->dev_conf.link_speeds & ETH_LINK_SPEED_AUTONEG)) {\n+\t\tPMD_INIT_LOG(ERR, \"Invalid link_speeds for port %hhu; autonegotiation disabled\",\n \t\t\t     dev->data->port_id);\n \t\treturn -EINVAL;\n \t}\n@@ -2193,32 +2192,21 @@ ixgbe_dev_start(struct rte_eth_dev *dev)\n \tif (err)\n \t\tgoto error;\n \n-\tswitch(dev->data->dev_conf.link_speed) {\n-\tcase ETH_LINK_SPEED_AUTONEG:\n-\t\tspeed = (hw->mac.type != ixgbe_mac_82598EB) ?\n-\t\t\t\tIXGBE_LINK_SPEED_82599_AUTONEG :\n-\t\t\t\tIXGBE_LINK_SPEED_82598_AUTONEG;\n-\t\tbreak;\n-\tcase ETH_SPEED_NUM_100M:\n-\t\t/*\n-\t\t * Invalid for 82598 but error will be detected by\n-\t\t * ixgbe_setup_link()\n-\t\t */\n-\t\tspeed = IXGBE_LINK_SPEED_100_FULL;\n-\t\tbreak;\n-\tcase ETH_SPEED_NUM_1G:\n-\t\tspeed = IXGBE_LINK_SPEED_1GB_FULL;\n-\t\tbreak;\n-\tcase ETH_SPEED_NUM_10G:\n-\t\tspeed = IXGBE_LINK_SPEED_10GB_FULL;\n-\t\tbreak;\n-\tdefault:\n-\t\tPMD_INIT_LOG(ERR, \"Invalid link_speed (%hu) for port %hhu\",\n-\t\t\t     dev->data->dev_conf.link_speed,\n-\t\t\t     dev->data->port_id);\n+\tlink_speeds = &dev->data->dev_conf.link_speeds;\n+\tif (*link_speeds & ~(ETH_LINK_SPEED_100M | ETH_LINK_SPEED_1G |\n+\t\t\tETH_LINK_SPEED_10G)) {\n+\t\tPMD_INIT_LOG(ERR, \"Invalid link setting\");\n \t\tgoto error;\n \t}\n \n+\tspeed = 0x0;\n+\tif (*link_speeds & ETH_LINK_SPEED_10G)\n+\t\tspeed |= IXGBE_LINK_SPEED_10GB_FULL;\n+\tif (*link_speeds & ETH_LINK_SPEED_1G)\n+\t\tspeed |= IXGBE_LINK_SPEED_1GB_FULL;\n+\tif (*link_speeds & ETH_LINK_SPEED_100M)\n+\t\tspeed |= IXGBE_LINK_SPEED_100_FULL;\n+\n \terr = ixgbe_setup_link(hw, speed, link_up);\n \tif (err)\n \t\tgoto error;\n@@ -3083,7 +3071,7 @@ ixgbe_dev_link_update(struct rte_eth_dev *dev, int wait_to_complete)\n \n \tif (diag != 0) {\n \t\tlink.link_speed = ETH_SPEED_NUM_100M;\n-\t\tlink.link_duplex = ETH_LINK_HALF_DUPLEX;\n+\t\tlink.link_duplex = ETH_LINK_FULL_DUPLEX;\n \t\trte_ixgbe_dev_atomic_write_link_status(dev, &link);\n \t\tif (link.link_status == old.link_status)\n \t\t\treturn -1;\n@@ -3102,7 +3090,7 @@ ixgbe_dev_link_update(struct rte_eth_dev *dev, int wait_to_complete)\n \tswitch (link_speed) {\n \tdefault:\n \tcase IXGBE_LINK_SPEED_UNKNOWN:\n-\t\tlink.link_duplex = ETH_LINK_HALF_DUPLEX;\n+\t\tlink.link_duplex = ETH_LINK_FULL_DUPLEX;\n \t\tlink.link_speed = ETH_SPEED_NUM_100M;\n \t\tbreak;\n \ndiff --git a/drivers/net/mlx4/mlx4.c b/drivers/net/mlx4/mlx4.c\nindex 59ac423..43ac763 100644\n--- a/drivers/net/mlx4/mlx4.c\n+++ b/drivers/net/mlx4/mlx4.c\n@@ -4721,6 +4721,8 @@ mlx4_link_update_unlocked(struct rte_eth_dev *dev, int wait_to_complete)\n \t\tdev_link.link_speed = link_speed;\n \tdev_link.link_duplex = ((edata.duplex == DUPLEX_HALF) ?\n \t\t\t\tETH_LINK_HALF_DUPLEX : ETH_LINK_FULL_DUPLEX);\n+\tdev_link.link_autoneg = (dev->data->dev_conf.link_speeds &\n+\t\t\tETH_LINK_SPEED_AUTONEG);\n \tif (memcmp(&dev_link, &dev->data->dev_link, sizeof(dev_link))) {\n \t\t/* Link status changed. */\n \t\tdev->data->dev_link = dev_link;\ndiff --git a/drivers/net/mpipe/mpipe_tilegx.c b/drivers/net/mpipe/mpipe_tilegx.c\nindex 1a77c7a..adcbc19 100644\n--- a/drivers/net/mpipe/mpipe_tilegx.c\n+++ b/drivers/net/mpipe/mpipe_tilegx.c\n@@ -394,6 +394,8 @@ mpipe_link_update(struct rte_eth_dev *dev, int wait_to_complete)\n \n \t\tspeed = state & GXIO_MPIPE_LINK_SPEED_MASK;\n \n+\t\tnew.link_autoneg = (dev->data->dev_conf.link_speeds &\n+\t\t\t\tETH_LINK_SPEED_AUTONEG);\n \t\tif (speed == GXIO_MPIPE_LINK_1G) {\n \t\t\tnew.link_speed = ETH_SPEED_NUM_1G;\n \t\t\tnew.link_duplex = ETH_LINK_FULL_DUPLEX;\ndiff --git a/drivers/net/null/rte_eth_null.c b/drivers/net/null/rte_eth_null.c\nindex 5640585..5e8e203 100644\n--- a/drivers/net/null/rte_eth_null.c\n+++ b/drivers/net/null/rte_eth_null.c\n@@ -92,6 +92,7 @@ static struct rte_eth_link pmd_link = {\n \t.link_speed = ETH_SPEED_NUM_10G,\n \t.link_duplex = ETH_LINK_FULL_DUPLEX,\n \t.link_status = ETH_LINK_DOWN,\n+\t.link_autoneg = ETH_LINK_SPEED_AUTONEG,\n };\n \n static uint16_t\ndiff --git a/drivers/net/pcap/rte_eth_pcap.c b/drivers/net/pcap/rte_eth_pcap.c\nindex c657951..c98e234 100644\n--- a/drivers/net/pcap/rte_eth_pcap.c\n+++ b/drivers/net/pcap/rte_eth_pcap.c\n@@ -126,6 +126,7 @@ static struct rte_eth_link pmd_link = {\n \t\t.link_speed = ETH_SPEED_NUM_10G,\n \t\t.link_duplex = ETH_LINK_FULL_DUPLEX,\n \t\t.link_status = ETH_LINK_DOWN,\n+\t\t.link_autoneg = ETH_LINK_SPEED_FIXED,\n };\n \n static int\ndiff --git a/drivers/net/ring/rte_eth_ring.c b/drivers/net/ring/rte_eth_ring.c\nindex 58685e9..b1783c3 100644\n--- a/drivers/net/ring/rte_eth_ring.c\n+++ b/drivers/net/ring/rte_eth_ring.c\n@@ -80,6 +80,7 @@ static struct rte_eth_link pmd_link = {\n \t\t.link_speed = ETH_SPEED_NUM_10G,\n \t\t.link_duplex = ETH_LINK_FULL_DUPLEX,\n \t\t.link_status = ETH_LINK_DOWN,\n+\t\t.link_autoneg = ETH_LINK_SPEED_AUTONEG\n };\n \n static uint16_t\ndiff --git a/drivers/net/szedata2/rte_eth_szedata2.c b/drivers/net/szedata2/rte_eth_szedata2.c\nindex dd1ae9e..ee97a4e 100644\n--- a/drivers/net/szedata2/rte_eth_szedata2.c\n+++ b/drivers/net/szedata2/rte_eth_szedata2.c\n@@ -1174,6 +1174,8 @@ eth_link_update(struct rte_eth_dev *dev,\n \tlink.link_status = (cgmii_ibuf_is_enabled(ibuf) &&\n \t\t\tcgmii_ibuf_is_link_up(ibuf)) ? ETH_LINK_UP : ETH_LINK_DOWN;\n \n+\tlink.link_autoneg = ETH_LINK_SPEED_FIXED;\n+\n \trte_atomic64_cmpset((uint64_t *)dev_link, *(uint64_t *)dev_link,\n \t\t\t*(uint64_t *)link_ptr);\n \ndiff --git a/drivers/net/vmxnet3/vmxnet3_ethdev.c b/drivers/net/vmxnet3/vmxnet3_ethdev.c\nindex 6afa14e..94d1b2c 100644\n--- a/drivers/net/vmxnet3/vmxnet3_ethdev.c\n+++ b/drivers/net/vmxnet3/vmxnet3_ethdev.c\n@@ -780,6 +780,7 @@ vmxnet3_dev_link_update(struct rte_eth_dev *dev, __attribute__((unused)) int wai\n \t\tlink.link_status = ETH_LINK_UP;\n \t\tlink.link_duplex = ETH_LINK_FULL_DUPLEX;\n \t\tlink.link_speed = ETH_SPEED_NUM_10G;\n+\t\tlink.link_autoneg = ETH_LINK_SPEED_FIXED;\n \t}\n \n \tvmxnet3_dev_atomic_write_link_status(dev, &link);\ndiff --git a/drivers/net/xenvirt/rte_eth_xenvirt.c b/drivers/net/xenvirt/rte_eth_xenvirt.c\nindex 77d3ba1..b9638d9 100644\n--- a/drivers/net/xenvirt/rte_eth_xenvirt.c\n+++ b/drivers/net/xenvirt/rte_eth_xenvirt.c\n@@ -73,6 +73,7 @@ static struct rte_eth_link pmd_link = {\n \t\t.link_speed = ETH_SPEED_NUM_10G,\n \t\t.link_duplex = ETH_LINK_FULL_DUPLEX,\n \t\t.link_status = ETH_LINK_DOWN,\n+\t\t.link_autoneg = ETH_LINK_SPEED_FIXED\n };\n \n static void\ndiff --git a/examples/ip_pipeline/config_parse.c b/examples/ip_pipeline/config_parse.c\nindex 152889d..2cd5707 100644\n--- a/examples/ip_pipeline/config_parse.c\n+++ b/examples/ip_pipeline/config_parse.c\n@@ -87,8 +87,7 @@ static const struct app_link_params link_params_default = {\n \t.pci_bdf = {0},\n \n \t.conf = {\n-\t\t.link_speed = 0,\n-\t\t.link_duplex = 0,\n+\t\t.link_speeds = 0,\n \t\t.rxmode = {\n \t\t\t.mq_mode = ETH_MQ_RX_NONE,\n \ndiff --git a/lib/librte_ether/rte_ethdev.h b/lib/librte_ether/rte_ethdev.h\nindex 49fdcb7..03d3278 100644\n--- a/lib/librte_ether/rte_ethdev.h\n+++ b/lib/librte_ether/rte_ethdev.h\n@@ -244,6 +244,8 @@ struct rte_eth_stats {\n /**\n  * Device supported speeds bitmap flags\n  */\n+#define ETH_LINK_SPEED_FIXED    (0 <<  0)  /**< Disable autoneg (fixed speed) */\n+#define ETH_LINK_SPEED_AUTONEG  (1 <<  0)  /**< Autonegotiate (all speeds) */\n #define ETH_LINK_SPEED_10M_HD   (1 <<  1)  /**<  10 Mbps half-duplex */\n #define ETH_LINK_SPEED_10M      (1 <<  2)  /**<  10 Mbps full-duplex */\n #define ETH_LINK_SPEED_100M_HD  (1 <<  3)  /**< 100 Mbps half-duplex */\n@@ -261,7 +263,7 @@ struct rte_eth_stats {\n /**\n  * Ethernet numeric link speeds in Mbps\n  */\n-#define ETH_LINK_SPEED_AUTONEG     0 /**< Auto-negotiate link speed. */\n+#define ETH_SPEED_NUM_NONE         0 /**< Not defined */\n #define ETH_SPEED_NUM_10M         10 /**<  10 Mbps */\n #define ETH_SPEED_NUM_100M       100 /**< 100 Mbps */\n #define ETH_SPEED_NUM_1G        1000 /**<   1 Gbps */\n@@ -278,15 +280,15 @@ struct rte_eth_stats {\n  * A structure used to retrieve link-level information of an Ethernet port.\n  */\n struct rte_eth_link {\n-\tuint16_t link_speed;      /**< ETH_SPEED_NUM_ */\n-\tuint16_t link_duplex;     /**< ETH_LINK_[HALF/FULL]_DUPLEX */\n-\tuint8_t  link_status : 1; /**< ETH_LINK_[DOWN/UP] */\n-}__attribute__((aligned(8)));     /**< aligned for atomic64 read/write */\n+\tuint16_t link_speed;        /**< ETH_SPEED_NUM_ */\n+\tuint16_t link_duplex  : 1;  /**< ETH_LINK_[HALF/FULL]_DUPLEX */\n+\tuint16_t link_autoneg : 1;  /**< ETH_LINK_SPEED_[AUTONEG/FIXED] */\n+\tuint16_t link_status  : 1;  /**< ETH_LINK_[DOWN/UP] */\n+} __attribute__((aligned(8)));      /**< aligned for atomic64 read/write */\n \n /* Utility constants */\n-#define ETH_LINK_AUTONEG_DUPLEX 0       /**< Auto-negotiate duplex. */\n-#define ETH_LINK_HALF_DUPLEX    1       /**< Half-duplex connection. */\n-#define ETH_LINK_FULL_DUPLEX    2       /**< Full-duplex connection. */\n+#define ETH_LINK_HALF_DUPLEX    0 /**< Half-duplex connection. */\n+#define ETH_LINK_FULL_DUPLEX    1 /**< Full-duplex connection. */\n #define ETH_LINK_DOWN           0 /**< Link is down. */\n #define ETH_LINK_UP             1 /**< Link is up. */\n \n@@ -802,10 +804,13 @@ struct rte_intr_conf {\n  * configuration settings may be needed.\n  */\n struct rte_eth_conf {\n-\tuint16_t link_speed;\n-\t/**< ETH_SPEED_NUM_ or 0 for autonegotiation */\n-\tuint16_t link_duplex;\n-\t/**< ETH_LINK_[HALF_DUPLEX|FULL_DUPLEX], or 0 for autonegotation */\n+\tuint32_t link_speeds; /**< bitmap of ETH_LINK_SPEED_XXX of speeds to be\n+\t\t\t\tused. ETH_LINK_SPEED_FIXED disables link\n+\t\t\t\tautonegotiation, and a unique speed shall be\n+\t\t\t\tset. Otherwise, the bitmap defines the set of\n+\t\t\t\tspeeds to be advertised. If the special value\n+\t\t\t\tETH_LINK_SPEED_AUTONEG (0) is used, all speeds\n+\t\t\t\tsupported are advertised. */\n \tstruct rte_eth_rxmode rxmode; /**< Port RX configuration. */\n \tstruct rte_eth_txmode txmode; /**< Port TX configuration. */\n \tuint32_t lpbk_mode; /**< Loopback operation mode. By default the value\n",
    "prefixes": [
        "dpdk-dev",
        "v12",
        "6/8"
    ]
}