get:
Show a patch.

patch:
Update a patch.

put:
Update a patch.

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

{
    "id": 7995,
    "url": "http://patches.dpdk.org/api/patches/7995/?format=api",
    "web_url": "http://patches.dpdk.org/project/dpdk/patch/1445810400-8978-4-git-send-email-marcdevel@gmail.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": "<1445810400-8978-4-git-send-email-marcdevel@gmail.com>",
    "list_archive_url": "https://inbox.dpdk.org/dev/1445810400-8978-4-git-send-email-marcdevel@gmail.com",
    "date": "2015-10-25T21:59:58",
    "name": "[dpdk-dev,v6,3/5] ethdev: redesign link speed config API",
    "commit_ref": null,
    "pull_url": null,
    "state": "changes-requested",
    "archived": true,
    "hash": "f2dde583ecc7afe488f43b37b444cc9375ec64b3",
    "submitter": {
        "id": 314,
        "url": "http://patches.dpdk.org/api/people/314/?format=api",
        "name": "Marc Sune",
        "email": "marcdevel@gmail.com"
    },
    "delegate": null,
    "mbox": "http://patches.dpdk.org/project/dpdk/patch/1445810400-8978-4-git-send-email-marcdevel@gmail.com/mbox/",
    "series": [],
    "comments": "http://patches.dpdk.org/api/patches/7995/comments/",
    "check": "pending",
    "checks": "http://patches.dpdk.org/api/patches/7995/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 C98745699;\n\tSun, 25 Oct 2015 23:00:37 +0100 (CET)",
            "from mail-wi0-f177.google.com (mail-wi0-f177.google.com\n\t[209.85.212.177]) by dpdk.org (Postfix) with ESMTP id A67A05A76\n\tfor <dev@dpdk.org>; Sun, 25 Oct 2015 23:00:33 +0100 (CET)",
            "by wikq8 with SMTP id q8so140264619wik.1\n\tfor <dev@dpdk.org>; Sun, 25 Oct 2015 15:00:33 -0700 (PDT)",
            "from localhost.localdomain\n\t(189.Red-83-47-134.dynamicIP.rima-tde.net. [83.47.134.189])\n\tby smtp.gmail.com with ESMTPSA id\n\tev1sm8733669wic.21.2015.10.25.15.00.32\n\t(version=TLSv1.2 cipher=ECDHE-RSA-AES128-SHA bits=128/128);\n\tSun, 25 Oct 2015 15:00:32 -0700 (PDT)"
        ],
        "DKIM-Signature": "v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113;\n\th=from:to:cc:subject:date:message-id:in-reply-to:references;\n\tbh=TWZlu+rOl8fnE7289NAfjrZmNXljXVRf+bfrB+Q/9is=;\n\tb=mzsHSyT6HICentfMfMz/XC9fVkY7j8bYUDDd3yCypllDNGeguGedGDjhqgsy7u+LFV\n\tBkMRy+1u+2xNykvqWbLFkBNGCYueneSGBsl9xY7HQUKzdyRthXgSMvtmgCAsIydSu61R\n\ty253ak3ogtrpC1B+Jrk+enLf52zdQBrdfdXLOiXhcIV/NyE4TRTSla6f9yPEDFULzR4r\n\tON7WLu6j4mAtI2//ykvAEBQqthjAXsU6k/vlYXPt3DVkJYfiwylcU0Yp+l9OZhkl0UVj\n\t+4K8aaziFg9H1uoUHjT+ApK8+aqkvWCFT38zSnWig1SQJYusU4P8ADwnRDlvwgXtZjXp\n\tB+mw==",
        "X-Received": "by 10.194.176.129 with SMTP id\n\tci1mr16574370wjc.156.1445810433506; \n\tSun, 25 Oct 2015 15:00:33 -0700 (PDT)",
        "From": "Marc Sune <marcdevel@gmail.com>",
        "To": "dev@dpdk.org",
        "Date": "Sun, 25 Oct 2015 22:59:58 +0100",
        "Message-Id": "<1445810400-8978-4-git-send-email-marcdevel@gmail.com>",
        "X-Mailer": "git-send-email 2.1.4",
        "In-Reply-To": "<1445810400-8978-1-git-send-email-marcdevel@gmail.com>",
        "References": "<1443993003-1059-1-git-send-email-marcdevel@gmail.com>\n\t<1445810400-8978-1-git-send-email-marcdevel@gmail.com>",
        "Subject": "[dpdk-dev] [PATCH v6 3/5] ethdev: redesign link speed config API",
        "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": "This patch redesigns the API to set the link speed/s configure\nfor 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\nOther changes:\n\n* Added utility MACROs ETH_SPEED_NUM_XXX with the numeric\n  values of all supported link speeds, in Mbps.\n* Converted link_speed to uint32_t to accomodate 100G speeds\n  (bug).\n* Added autoneg flag in struct rte_eth_link to indicate if\n  link speed was a result of auto-negociation or was fixed\n  by configuration.\n* Added utility function to convert numeric speeds to bitmap\n  fields.\n\nSigned-off-by: Marc Sune <marcdevel@gmail.com>\n---\n app/test-pmd/cmdline.c                     | 124 +++++++++++++++--------------\n app/test/virtual_pmd.c                     |   4 +-\n drivers/net/af_packet/rte_eth_af_packet.c  |   5 +-\n drivers/net/bonding/rte_eth_bond_8023ad.c  |  14 ++--\n drivers/net/cxgbe/base/t4_hw.c             |   8 +-\n drivers/net/e1000/base/e1000_80003es2lan.c |   6 +-\n drivers/net/e1000/base/e1000_82541.c       |   8 +-\n drivers/net/e1000/base/e1000_82543.c       |   4 +-\n drivers/net/e1000/base/e1000_82575.c       |  11 +--\n drivers/net/e1000/base/e1000_api.c         |   2 +-\n drivers/net/e1000/base/e1000_api.h         |   2 +-\n drivers/net/e1000/base/e1000_defines.h     |   4 +-\n drivers/net/e1000/base/e1000_hw.h          |   2 +-\n drivers/net/e1000/base/e1000_ich8lan.c     |   4 +-\n drivers/net/e1000/base/e1000_mac.c         |   9 ++-\n drivers/net/e1000/base/e1000_mac.h         |   6 +-\n drivers/net/e1000/base/e1000_vf.c          |   4 +-\n drivers/net/e1000/base/e1000_vf.h          |   2 +-\n drivers/net/e1000/em_ethdev.c              | 113 +++++++++++++-------------\n drivers/net/e1000/igb_ethdev.c             | 108 +++++++++++++------------\n drivers/net/fm10k/fm10k_ethdev.c           |   8 +-\n drivers/net/i40e/i40e_ethdev.c             |  73 ++++++++---------\n drivers/net/i40e/i40e_ethdev_vf.c          |  11 +--\n drivers/net/ixgbe/ixgbe_ethdev.c           |  72 ++++++++---------\n drivers/net/mlx4/mlx4.c                    |   2 +\n drivers/net/mpipe/mpipe_tilegx.c           |   6 +-\n drivers/net/null/rte_eth_null.c            |   5 +-\n drivers/net/pcap/rte_eth_pcap.c            |   9 ++-\n drivers/net/ring/rte_eth_ring.c            |   5 +-\n drivers/net/virtio/virtio_ethdev.c         |   2 +-\n drivers/net/virtio/virtio_ethdev.h         |   2 -\n drivers/net/vmxnet3/vmxnet3_ethdev.c       |   5 +-\n drivers/net/xenvirt/rte_eth_xenvirt.c      |   5 +-\n examples/ip_pipeline/config_parse.c        |   3 +-\n lib/librte_ether/rte_ethdev.c              |  49 ++++++++++++\n lib/librte_ether/rte_ethdev.h              | 113 ++++++++++++++++----------\n 36 files changed, 449 insertions(+), 361 deletions(-)",
    "diff": "diff --git a/app/test-pmd/cmdline.c b/app/test-pmd/cmdline.c\nindex 0f8f48f..c62f5be 100644\n--- a/app/test-pmd/cmdline.c\n+++ b/app/test-pmd/cmdline.c\n@@ -897,14 +897,65 @@ struct cmd_config_speed_all {\n \tcmdline_fixed_string_t value2;\n };\n \n+static int\n+parse_and_check_speed_duplex(char *value1, char *value2, uint32_t *link_speed)\n+{\n+\n+\tint duplex;\n+\n+\tif (!strcmp(value2, \"half\")) {\n+\t\tduplex = 0;\n+\t} else if (!strcmp(value2, \"full\")) {\n+\t\tduplex = 1;\n+\t} else if (!strcmp(value2, \"auto\")) {\n+\t\tduplex = 1;\n+\t} else {\n+\t\tprintf(\"Unknown parameter\\n\");\n+\t\treturn -1;\n+\t}\n+\n+\tif (!strcmp(value1, \"10\")) {\n+\t\t*link_speed = (duplex) ? ETH_LINK_SPEED_10M :\n+\t\t\t\t\t\t\tETH_LINK_SPEED_10M_HD;\n+\t} else if (!strcmp(value1, \"100\")) {\n+\t\t*link_speed = (duplex) ? ETH_LINK_SPEED_100M :\n+\t\t\t\t\t\t\tETH_LINK_SPEED_100M_HD;\n+\t} else if (!strcmp(value1, \"1000\")) {\n+\t\tif (!duplex)\n+\t\t\tgoto invalid_speed_param;\n+\t\t*link_speed = ETH_LINK_SPEED_1G;\n+\t} else if (!strcmp(value1, \"10000\")) {\n+\t\tif (!duplex)\n+\t\t\tgoto invalid_speed_param;\n+\t\t*link_speed = ETH_LINK_SPEED_10G;\n+\t} else if (!strcmp(value1, \"40000\")) {\n+\t\tif (!duplex)\n+\t\t\tgoto invalid_speed_param;\n+\t\t*link_speed = ETH_LINK_SPEED_40G;\n+\t} else if (!strcmp(value1, \"auto\")) {\n+\t\tif (!duplex)\n+\t\t\tgoto invalid_speed_param;\n+\t\t*link_speed = ETH_LINK_SPEED_AUTONEG;\n+\t} else {\n+\t\tprintf(\"Unknown parameter\\n\");\n+\t\treturn -1;\n+\t}\n+\n+\treturn 0;\n+\n+invalid_speed_param:\n+\n+\tprintf(\"Invalid speed parameter\\n\");\n+\treturn -1;\n+}\n+\n static void\n cmd_config_speed_all_parsed(void *parsed_result,\n \t\t\t__attribute__((unused)) struct cmdline *cl,\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@@ -912,40 +963,18 @@ cmd_config_speed_all_parsed(void *parsed_result,\n \t\treturn;\n \t}\n \n-\tif (!strcmp(res->value1, \"10\"))\n-\t\tlink_speed = ETH_LINK_SPEED_10;\n-\telse if (!strcmp(res->value1, \"100\"))\n-\t\tlink_speed = ETH_LINK_SPEED_100;\n-\telse if (!strcmp(res->value1, \"1000\"))\n-\t\tlink_speed = ETH_LINK_SPEED_1000;\n-\telse if (!strcmp(res->value1, \"10000\"))\n-\t\tlink_speed = ETH_LINK_SPEED_10G;\n-\telse if (!strcmp(res->value1, \"40000\"))\n-\t\tlink_speed = ETH_LINK_SPEED_40G;\n-\telse if (!strcmp(res->value1, \"auto\"))\n-\t\tlink_speed = ETH_LINK_SPEED_AUTONEG;\n-\telse {\n-\t\tprintf(\"Unknown parameter\\n\");\n+\tif (parse_and_check_speed_duplex(res->value1,\n+\t\t\t\t\t\tres->value2,\n+\t\t\t\t\t\t&link_speed) < 0)\n \t\treturn;\n-\t}\n-\n-\tif (!strcmp(res->value2, \"half\"))\n-\t\tlink_duplex = ETH_LINK_HALF_DUPLEX;\n-\telse if (!strcmp(res->value2, \"full\"))\n-\t\tlink_duplex = ETH_LINK_FULL_DUPLEX;\n-\telse if (!strcmp(res->value2, \"auto\"))\n-\t\tlink_duplex = ETH_LINK_AUTONEG_DUPLEX;\n-\telse {\n-\t\tprintf(\"Unknown parameter\\n\");\n-\t\treturn;\n-\t}\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+\n+\treturn;\n }\n \n cmdline_parse_token_string_t cmd_config_speed_all_port =\n@@ -1000,8 +1029,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@@ -1011,36 +1039,12 @@ cmd_config_speed_specific_parsed(void *parsed_result,\n \tif (port_id_is_invalid(res->id, ENABLED_WARN))\n \t\treturn;\n \n-\tif (!strcmp(res->value1, \"10\"))\n-\t\tlink_speed = ETH_LINK_SPEED_10;\n-\telse if (!strcmp(res->value1, \"100\"))\n-\t\tlink_speed = ETH_LINK_SPEED_100;\n-\telse if (!strcmp(res->value1, \"1000\"))\n-\t\tlink_speed = ETH_LINK_SPEED_1000;\n-\telse if (!strcmp(res->value1, \"10000\"))\n-\t\tlink_speed = ETH_LINK_SPEED_10000;\n-\telse if (!strcmp(res->value1, \"40000\"))\n-\t\tlink_speed = ETH_LINK_SPEED_40G;\n-\telse if (!strcmp(res->value1, \"auto\"))\n-\t\tlink_speed = ETH_LINK_SPEED_AUTONEG;\n-\telse {\n-\t\tprintf(\"Unknown parameter\\n\");\n+\tif (parse_and_check_speed_duplex(res->value1,\n+\t\t\t\t\t\tres->value2,\n+\t\t\t\t\t\t&link_speed) < 0)\n \t\treturn;\n-\t}\n-\n-\tif (!strcmp(res->value2, \"half\"))\n-\t\tlink_duplex = ETH_LINK_HALF_DUPLEX;\n-\telse if (!strcmp(res->value2, \"full\"))\n-\t\tlink_duplex = ETH_LINK_FULL_DUPLEX;\n-\telse if (!strcmp(res->value2, \"auto\"))\n-\t\tlink_duplex = ETH_LINK_AUTONEG_DUPLEX;\n-\telse {\n-\t\tprintf(\"Unknown parameter\\n\");\n-\t\treturn;\n-\t}\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/app/test/virtual_pmd.c b/app/test/virtual_pmd.c\nindex a538c8a..3c4040b 100644\n--- a/app/test/virtual_pmd.c\n+++ b/app/test/virtual_pmd.c\n@@ -603,8 +603,8 @@ virtual_ethdev_create(const char *name, struct ether_addr *mac_addr,\n \n \tTAILQ_INIT(&(eth_dev->link_intr_cbs));\n \n-\teth_dev->data->dev_link.link_status = 0;\n-\teth_dev->data->dev_link.link_speed = ETH_LINK_SPEED_10000;\n+\teth_dev->data->dev_link.link_status = ETH_LINK_DOWN;\n+\teth_dev->data->dev_link.link_speed = ETH_SPEED_NUM_10G;\n \teth_dev->data->dev_link.link_duplex = ETH_LINK_FULL_DUPLEX;\n \n \teth_dev->data->mac_addrs = rte_zmalloc(name, ETHER_ADDR_LEN, 0);\ndiff --git a/drivers/net/af_packet/rte_eth_af_packet.c b/drivers/net/af_packet/rte_eth_af_packet.c\nindex bdd9628..a5d689d 100644\n--- a/drivers/net/af_packet/rte_eth_af_packet.c\n+++ b/drivers/net/af_packet/rte_eth_af_packet.c\n@@ -115,9 +115,10 @@ static const char *valid_arguments[] = {\n static const char *drivername = \"AF_PACKET PMD\";\n \n static struct rte_eth_link pmd_link = {\n-\t.link_speed = 10000,\n+\t.link_speed = ETH_SPEED_NUM_10G,\n \t.link_duplex = ETH_LINK_FULL_DUPLEX,\n-\t.link_status = 0\n+\t.link_status = ETH_LINK_DOWN,\n+\t.link_autoneg = ETH_LINK_SPEED_NEG\n };\n \n static uint16_t\ndiff --git a/drivers/net/bonding/rte_eth_bond_8023ad.c b/drivers/net/bonding/rte_eth_bond_8023ad.c\nindex c0f0b99..f375f95 100644\n--- a/drivers/net/bonding/rte_eth_bond_8023ad.c\n+++ b/drivers/net/bonding/rte_eth_bond_8023ad.c\n@@ -708,25 +708,25 @@ 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_LINK_SPEED_10:\n+\tcase ETH_SPEED_NUM_10M:\n \t\tkey_speed = BOND_LINK_SPEED_KEY_10M;\n \t\tbreak;\n-\tcase ETH_LINK_SPEED_100:\n+\tcase ETH_SPEED_NUM_100M:\n \t\tkey_speed = BOND_LINK_SPEED_KEY_100M;\n \t\tbreak;\n-\tcase ETH_LINK_SPEED_1000:\n+\tcase ETH_SPEED_NUM_1G:\n \t\tkey_speed = BOND_LINK_SPEED_KEY_1000M;\n \t\tbreak;\n-\tcase ETH_LINK_SPEED_10G:\n+\tcase ETH_SPEED_NUM_10G:\n \t\tkey_speed = BOND_LINK_SPEED_KEY_10G;\n \t\tbreak;\n-\tcase ETH_LINK_SPEED_20G:\n+\tcase ETH_SPEED_NUM_20G:\n \t\tkey_speed = BOND_LINK_SPEED_KEY_20G;\n \t\tbreak;\n-\tcase ETH_LINK_SPEED_40G:\n+\tcase ETH_SPEED_NUM_40G:\n \t\tkey_speed = BOND_LINK_SPEED_KEY_40G;\n \t\tbreak;\n \tdefault:\ndiff --git a/drivers/net/cxgbe/base/t4_hw.c b/drivers/net/cxgbe/base/t4_hw.c\nindex 884d2cf..79af806 100644\n--- a/drivers/net/cxgbe/base/t4_hw.c\n+++ b/drivers/net/cxgbe/base/t4_hw.c\n@@ -2159,13 +2159,13 @@ int t4_handle_fw_rpl(struct adapter *adap, const __be64 *rpl)\n \t\tif (stat & F_FW_PORT_CMD_TXPAUSE)\n \t\t\tfc |= PAUSE_TX;\n \t\tif (stat & V_FW_PORT_CMD_LSPEED(FW_PORT_CAP_SPEED_100M))\n-\t\t\tspeed = ETH_LINK_SPEED_100;\n+\t\t\tspeed = ETH_SPEED_NUM_100M;\n \t\telse if (stat & V_FW_PORT_CMD_LSPEED(FW_PORT_CAP_SPEED_1G))\n-\t\t\tspeed = ETH_LINK_SPEED_1000;\n+\t\t\tspeed = ETH_SPEED_NUM_1G;\n \t\telse if (stat & V_FW_PORT_CMD_LSPEED(FW_PORT_CAP_SPEED_10G))\n-\t\t\tspeed = ETH_LINK_SPEED_10000;\n+\t\t\tspeed = ETH_SPEED_NUM_10G;\n \t\telse if (stat & V_FW_PORT_CMD_LSPEED(FW_PORT_CAP_SPEED_40G))\n-\t\t\tspeed = ETH_LINK_SPEED_40G;\n+\t\t\tspeed = ETH_SPEED_NUM_40G;\n \n \t\tfor_each_port(adap, i) {\n \t\t\tpi = adap2pinfo(adap, i);\ndiff --git a/drivers/net/e1000/base/e1000_80003es2lan.c b/drivers/net/e1000/base/e1000_80003es2lan.c\nindex 72692d9..8ca66c4 100644\n--- a/drivers/net/e1000/base/e1000_80003es2lan.c\n+++ b/drivers/net/e1000/base/e1000_80003es2lan.c\n@@ -52,7 +52,7 @@ STATIC s32  e1000_write_nvm_80003es2lan(struct e1000_hw *hw, u16 offset,\n STATIC s32  e1000_get_cfg_done_80003es2lan(struct e1000_hw *hw);\n STATIC s32  e1000_phy_force_speed_duplex_80003es2lan(struct e1000_hw *hw);\n STATIC s32  e1000_get_cable_length_80003es2lan(struct e1000_hw *hw);\n-STATIC s32  e1000_get_link_up_info_80003es2lan(struct e1000_hw *hw, u16 *speed,\n+STATIC s32  e1000_get_link_up_info_80003es2lan(struct e1000_hw *hw, u32 *speed,\n \t\t\t\t\t       u16 *duplex);\n STATIC s32  e1000_reset_hw_80003es2lan(struct e1000_hw *hw);\n STATIC s32  e1000_init_hw_80003es2lan(struct e1000_hw *hw);\n@@ -789,7 +789,7 @@ STATIC s32 e1000_get_cable_length_80003es2lan(struct e1000_hw *hw)\n  *\n  *  Retrieve the current speed and duplex configuration.\n  **/\n-STATIC s32 e1000_get_link_up_info_80003es2lan(struct e1000_hw *hw, u16 *speed,\n+STATIC s32 e1000_get_link_up_info_80003es2lan(struct e1000_hw *hw, u32 *speed,\n \t\t\t\t\t      u16 *duplex)\n {\n \ts32 ret_val;\n@@ -1236,7 +1236,7 @@ STATIC s32 e1000_setup_copper_link_80003es2lan(struct e1000_hw *hw)\n STATIC s32 e1000_cfg_on_link_up_80003es2lan(struct e1000_hw *hw)\n {\n \ts32 ret_val = E1000_SUCCESS;\n-\tu16 speed;\n+\tu32 speed;\n \tu16 duplex;\n \n \tDEBUGFUNC(\"e1000_configure_on_link_up\");\ndiff --git a/drivers/net/e1000/base/e1000_82541.c b/drivers/net/e1000/base/e1000_82541.c\nindex 952aea2..707b317 100644\n--- a/drivers/net/e1000/base/e1000_82541.c\n+++ b/drivers/net/e1000/base/e1000_82541.c\n@@ -47,7 +47,7 @@ STATIC s32  e1000_init_nvm_params_82541(struct e1000_hw *hw);\n STATIC s32  e1000_init_mac_params_82541(struct e1000_hw *hw);\n STATIC s32  e1000_reset_hw_82541(struct e1000_hw *hw);\n STATIC s32  e1000_init_hw_82541(struct e1000_hw *hw);\n-STATIC s32  e1000_get_link_up_info_82541(struct e1000_hw *hw, u16 *speed,\n+STATIC s32  e1000_get_link_up_info_82541(struct e1000_hw *hw, u32 *speed,\n \t\t\t\t\t u16 *duplex);\n STATIC s32  e1000_phy_hw_reset_82541(struct e1000_hw *hw);\n STATIC s32  e1000_setup_copper_link_82541(struct e1000_hw *hw);\n@@ -437,7 +437,7 @@ out:\n  *\n  * Retrieve the current speed and duplex configuration.\n  **/\n-STATIC s32 e1000_get_link_up_info_82541(struct e1000_hw *hw, u16 *speed,\n+STATIC s32 e1000_get_link_up_info_82541(struct e1000_hw *hw, u32 *speed,\n \t\t\t\t\tu16 *duplex)\n {\n \tstruct e1000_phy_info *phy = &hw->phy;\n@@ -667,8 +667,8 @@ STATIC s32 e1000_config_dsp_after_link_change_82541(struct e1000_hw *hw,\n \tstruct e1000_phy_info *phy = &hw->phy;\n \tstruct e1000_dev_spec_82541 *dev_spec = &hw->dev_spec._82541;\n \ts32 ret_val;\n-\tu32 idle_errs = 0;\n-\tu16 phy_data, phy_saved_data, speed, duplex, i;\n+\tu32 idle_errs = 0, speed;\n+\tu16 phy_data, phy_saved_data, duplex, i;\n \tu16 ffe_idle_err_timeout = FFE_IDLE_ERR_COUNT_TIMEOUT_20;\n \tu16 dsp_reg_array[IGP01E1000_PHY_CHANNEL_NUM] = {\n \t\t\t\t\t\tIGP01E1000_PHY_AGC_PARAM_A,\ndiff --git a/drivers/net/e1000/base/e1000_82543.c b/drivers/net/e1000/base/e1000_82543.c\nindex 36335ba..9ef3d80 100644\n--- a/drivers/net/e1000/base/e1000_82543.c\n+++ b/drivers/net/e1000/base/e1000_82543.c\n@@ -1192,9 +1192,9 @@ out:\n STATIC s32 e1000_check_for_copper_link_82543(struct e1000_hw *hw)\n {\n \tstruct e1000_mac_info *mac = &hw->mac;\n-\tu32 icr, rctl;\n+\tu32 icr, rctl, speed;\n \ts32 ret_val;\n-\tu16 speed, duplex;\n+\tu16 duplex;\n \tbool link;\n \n \tDEBUGFUNC(\"e1000_check_for_copper_link_82543\");\ndiff --git a/drivers/net/e1000/base/e1000_82575.c b/drivers/net/e1000/base/e1000_82575.c\nindex 25fa672..386f058 100644\n--- a/drivers/net/e1000/base/e1000_82575.c\n+++ b/drivers/net/e1000/base/e1000_82575.c\n@@ -53,7 +53,7 @@ STATIC void e1000_release_nvm_82575(struct e1000_hw *hw);\n STATIC s32  e1000_check_for_link_82575(struct e1000_hw *hw);\n STATIC s32  e1000_check_for_link_media_swap(struct e1000_hw *hw);\n STATIC s32  e1000_get_cfg_done_82575(struct e1000_hw *hw);\n-STATIC s32  e1000_get_link_up_info_82575(struct e1000_hw *hw, u16 *speed,\n+STATIC s32  e1000_get_link_up_info_82575(struct e1000_hw *hw, u32 *speed,\n \t\t\t\t\t u16 *duplex);\n STATIC s32  e1000_phy_hw_reset_sgmii_82575(struct e1000_hw *hw);\n STATIC s32  e1000_read_phy_reg_sgmii_82575(struct e1000_hw *hw, u32 offset,\n@@ -80,7 +80,7 @@ STATIC s32  e1000_write_phy_reg_sgmii_82575(struct e1000_hw *hw,\n STATIC void e1000_clear_hw_cntrs_82575(struct e1000_hw *hw);\n STATIC s32  e1000_acquire_swfw_sync_82575(struct e1000_hw *hw, u16 mask);\n STATIC s32  e1000_get_pcs_speed_and_duplex_82575(struct e1000_hw *hw,\n-\t\t\t\t\t\t u16 *speed, u16 *duplex);\n+\t\t\t\t\t\t u32 *speed, u16 *duplex);\n STATIC s32  e1000_get_phy_id_82575(struct e1000_hw *hw);\n STATIC void e1000_release_swfw_sync_82575(struct e1000_hw *hw, u16 mask);\n STATIC bool e1000_sgmii_active_82575(struct e1000_hw *hw);\n@@ -1165,7 +1165,7 @@ STATIC s32 e1000_get_cfg_done_82575(struct e1000_hw *hw)\n  *  interface, use PCS to retrieve the link speed and duplex information.\n  *  Otherwise, use the generic function to get the link speed and duplex info.\n  **/\n-STATIC s32 e1000_get_link_up_info_82575(struct e1000_hw *hw, u16 *speed,\n+STATIC s32 e1000_get_link_up_info_82575(struct e1000_hw *hw, u32 *speed,\n \t\t\t\t\tu16 *duplex)\n {\n \ts32 ret_val;\n@@ -1192,7 +1192,8 @@ STATIC s32 e1000_get_link_up_info_82575(struct e1000_hw *hw, u16 *speed,\n STATIC s32 e1000_check_for_link_82575(struct e1000_hw *hw)\n {\n \ts32 ret_val;\n-\tu16 speed, duplex;\n+\tu32 speed;\n+\tu16 duplex;\n \n \tDEBUGFUNC(\"e1000_check_for_link_82575\");\n \n@@ -1316,7 +1317,7 @@ STATIC void e1000_power_up_serdes_link_82575(struct e1000_hw *hw)\n  *  duplex, then store the values in the pointers provided.\n  **/\n STATIC s32 e1000_get_pcs_speed_and_duplex_82575(struct e1000_hw *hw,\n-\t\t\t\t\t\tu16 *speed, u16 *duplex)\n+\t\t\t\t\t\tu32 *speed, u16 *duplex)\n {\n \tstruct e1000_mac_info *mac = &hw->mac;\n \tu32 pcs;\ndiff --git a/drivers/net/e1000/base/e1000_api.c b/drivers/net/e1000/base/e1000_api.c\nindex a064565..08e103a 100644\n--- a/drivers/net/e1000/base/e1000_api.c\n+++ b/drivers/net/e1000/base/e1000_api.c\n@@ -669,7 +669,7 @@ s32 e1000_setup_link(struct e1000_hw *hw)\n  *  variables passed in. This is a function pointer entry point called\n  *  by drivers.\n  **/\n-s32 e1000_get_speed_and_duplex(struct e1000_hw *hw, u16 *speed, u16 *duplex)\n+s32 e1000_get_speed_and_duplex(struct e1000_hw *hw, u32 *speed, u16 *duplex)\n {\n \tif (hw->mac.ops.get_link_up_info)\n \t\treturn hw->mac.ops.get_link_up_info(hw, speed, duplex);\ndiff --git a/drivers/net/e1000/base/e1000_api.h b/drivers/net/e1000/base/e1000_api.h\nindex 02b16da..39579e0 100644\n--- a/drivers/net/e1000/base/e1000_api.h\n+++ b/drivers/net/e1000/base/e1000_api.h\n@@ -65,7 +65,7 @@ s32 e1000_check_for_link(struct e1000_hw *hw);\n s32 e1000_reset_hw(struct e1000_hw *hw);\n s32 e1000_init_hw(struct e1000_hw *hw);\n s32 e1000_setup_link(struct e1000_hw *hw);\n-s32 e1000_get_speed_and_duplex(struct e1000_hw *hw, u16 *speed, u16 *duplex);\n+s32 e1000_get_speed_and_duplex(struct e1000_hw *hw, u32 *speed, u16 *duplex);\n s32 e1000_disable_pcie_master(struct e1000_hw *hw);\n void e1000_config_collision_dist(struct e1000_hw *hw);\n void e1000_rar_set(struct e1000_hw *hw, u8 *addr, u32 index);\ndiff --git a/drivers/net/e1000/base/e1000_defines.h b/drivers/net/e1000/base/e1000_defines.h\nindex 278c507..20c4153 100644\n--- a/drivers/net/e1000/base/e1000_defines.h\n+++ b/drivers/net/e1000/base/e1000_defines.h\n@@ -347,8 +347,8 @@ POSSIBILITY OF SUCH DAMAGE.\n #define SPEED_100\t100\n #define SPEED_1000\t1000\n #define SPEED_2500\t2500\n-#define HALF_DUPLEX\t1\n-#define FULL_DUPLEX\t2\n+#define HALF_DUPLEX\t0\n+#define FULL_DUPLEX\t1\n \n #define PHY_FORCE_TIME\t20\n \ndiff --git a/drivers/net/e1000/base/e1000_hw.h b/drivers/net/e1000/base/e1000_hw.h\nindex 4dd92a3..b48a759 100644\n--- a/drivers/net/e1000/base/e1000_hw.h\n+++ b/drivers/net/e1000/base/e1000_hw.h\n@@ -682,7 +682,7 @@ struct e1000_mac_operations {\n \tvoid (*clear_vfta)(struct e1000_hw *);\n \ts32  (*get_bus_info)(struct e1000_hw *);\n \tvoid (*set_lan_id)(struct e1000_hw *);\n-\ts32  (*get_link_up_info)(struct e1000_hw *, u16 *, u16 *);\n+\ts32  (*get_link_up_info)(struct e1000_hw *, u32 *, u16 *);\n \ts32  (*led_on)(struct e1000_hw *);\n \ts32  (*led_off)(struct e1000_hw *);\n \tvoid (*update_mc_addr_list)(struct e1000_hw *, u8 *, u32);\ndiff --git a/drivers/net/e1000/base/e1000_ich8lan.c b/drivers/net/e1000/base/e1000_ich8lan.c\nindex 3b1627b..7fe9955 100644\n--- a/drivers/net/e1000/base/e1000_ich8lan.c\n+++ b/drivers/net/e1000/base/e1000_ich8lan.c\n@@ -104,7 +104,7 @@ STATIC s32  e1000_setup_link_ich8lan(struct e1000_hw *hw);\n STATIC s32  e1000_setup_copper_link_ich8lan(struct e1000_hw *hw);\n STATIC s32  e1000_setup_copper_link_pch_lpt(struct e1000_hw *hw);\n STATIC s32  e1000_get_link_up_info_ich8lan(struct e1000_hw *hw,\n-\t\t\t\t\t   u16 *speed, u16 *duplex);\n+\t\t\t\t\t   u32 *speed, u16 *duplex);\n STATIC s32  e1000_cleanup_led_ich8lan(struct e1000_hw *hw);\n STATIC s32  e1000_led_on_ich8lan(struct e1000_hw *hw);\n STATIC s32  e1000_led_off_ich8lan(struct e1000_hw *hw);\n@@ -4561,7 +4561,7 @@ STATIC s32 e1000_setup_copper_link_pch_lpt(struct e1000_hw *hw)\n  *  information and then calls the Kumeran lock loss workaround for links at\n  *  gigabit speeds.\n  **/\n-STATIC s32 e1000_get_link_up_info_ich8lan(struct e1000_hw *hw, u16 *speed,\n+STATIC s32 e1000_get_link_up_info_ich8lan(struct e1000_hw *hw, u32 *speed,\n \t\t\t\t\t  u16 *duplex)\n {\n \ts32 ret_val;\ndiff --git a/drivers/net/e1000/base/e1000_mac.c b/drivers/net/e1000/base/e1000_mac.c\nindex c8ec049..6703a17 100644\n--- a/drivers/net/e1000/base/e1000_mac.c\n+++ b/drivers/net/e1000/base/e1000_mac.c\n@@ -106,7 +106,7 @@ void e1000_null_mac_generic(struct e1000_hw E1000_UNUSEDARG *hw)\n  *  @hw: pointer to the HW structure\n  **/\n s32 e1000_null_link_info(struct e1000_hw E1000_UNUSEDARG *hw,\n-\t\t\t u16 E1000_UNUSEDARG *s, u16 E1000_UNUSEDARG *d)\n+\t\t\t u32 E1000_UNUSEDARG *s, u16 E1000_UNUSEDARG *d)\n {\n \tDEBUGFUNC(\"e1000_null_link_info\");\n \tUNREFERENCED_3PARAMETER(hw, s, d);\n@@ -1346,7 +1346,8 @@ s32 e1000_config_fc_after_link_up_generic(struct e1000_hw *hw)\n \ts32 ret_val = E1000_SUCCESS;\n \tu32 pcs_status_reg, pcs_adv_reg, pcs_lp_ability_reg, pcs_ctrl_reg;\n \tu16 mii_status_reg, mii_nway_adv_reg, mii_nway_lp_ability_reg;\n-\tu16 speed, duplex;\n+\tu32 speed;\n+\tu16 duplex;\n \n \tDEBUGFUNC(\"e1000_config_fc_after_link_up_generic\");\n \n@@ -1648,7 +1649,7 @@ s32 e1000_config_fc_after_link_up_generic(struct e1000_hw *hw)\n  *  Read the status register for the current speed/duplex and store the current\n  *  speed and duplex for copper connections.\n  **/\n-s32 e1000_get_speed_and_duplex_copper_generic(struct e1000_hw *hw, u16 *speed,\n+s32 e1000_get_speed_and_duplex_copper_generic(struct e1000_hw *hw, u32 *speed,\n \t\t\t\t\t      u16 *duplex)\n {\n \tu32 status;\n@@ -1688,7 +1689,7 @@ s32 e1000_get_speed_and_duplex_copper_generic(struct e1000_hw *hw, u16 *speed,\n  *  for fiber/serdes links.\n  **/\n s32 e1000_get_speed_and_duplex_fiber_serdes_generic(struct e1000_hw E1000_UNUSEDARG *hw,\n-\t\t\t\t\t\t    u16 *speed, u16 *duplex)\n+\t\t\t\t\t\t    u32 *speed, u16 *duplex)\n {\n \tDEBUGFUNC(\"e1000_get_speed_and_duplex_fiber_serdes_generic\");\n \tUNREFERENCED_1PARAMETER(hw);\ndiff --git a/drivers/net/e1000/base/e1000_mac.h b/drivers/net/e1000/base/e1000_mac.h\nindex 5a7ce4a..987df76 100644\n--- a/drivers/net/e1000/base/e1000_mac.h\n+++ b/drivers/net/e1000/base/e1000_mac.h\n@@ -40,7 +40,7 @@ void e1000_init_mac_ops_generic(struct e1000_hw *hw);\n #endif /* E1000_REMOVED */\n void e1000_null_mac_generic(struct e1000_hw *hw);\n s32  e1000_null_ops_generic(struct e1000_hw *hw);\n-s32  e1000_null_link_info(struct e1000_hw *hw, u16 *s, u16 *d);\n+s32  e1000_null_link_info(struct e1000_hw *hw, u32 *s, u16 *d);\n bool e1000_null_mng_mode(struct e1000_hw *hw);\n void e1000_null_update_mc(struct e1000_hw *hw, u8 *h, u32 a);\n void e1000_null_write_vfta(struct e1000_hw *hw, u32 a, u32 b);\n@@ -61,10 +61,10 @@ s32  e1000_get_bus_info_pcie_generic(struct e1000_hw *hw);\n void e1000_set_lan_id_single_port(struct e1000_hw *hw);\n void e1000_set_lan_id_multi_port_pci(struct e1000_hw *hw);\n s32  e1000_get_hw_semaphore_generic(struct e1000_hw *hw);\n-s32  e1000_get_speed_and_duplex_copper_generic(struct e1000_hw *hw, u16 *speed,\n+s32  e1000_get_speed_and_duplex_copper_generic(struct e1000_hw *hw, u32 *speed,\n \t\t\t\t\t       u16 *duplex);\n s32  e1000_get_speed_and_duplex_fiber_serdes_generic(struct e1000_hw *hw,\n-\t\t\t\t\t\t     u16 *speed, u16 *duplex);\n+\t\t\t\t\t\t     u32 *speed, u16 *duplex);\n s32  e1000_id_led_init_generic(struct e1000_hw *hw);\n s32  e1000_led_on_generic(struct e1000_hw *hw);\n s32  e1000_led_off_generic(struct e1000_hw *hw);\ndiff --git a/drivers/net/e1000/base/e1000_vf.c b/drivers/net/e1000/base/e1000_vf.c\nindex 778561e..2221f1c 100644\n--- a/drivers/net/e1000/base/e1000_vf.c\n+++ b/drivers/net/e1000/base/e1000_vf.c\n@@ -43,7 +43,7 @@ STATIC s32 e1000_setup_link_vf(struct e1000_hw *hw);\n STATIC s32 e1000_get_bus_info_pcie_vf(struct e1000_hw *hw);\n STATIC s32 e1000_init_mac_params_vf(struct e1000_hw *hw);\n STATIC s32 e1000_check_for_link_vf(struct e1000_hw *hw);\n-STATIC s32 e1000_get_link_up_info_vf(struct e1000_hw *hw, u16 *speed,\n+STATIC s32 e1000_get_link_up_info_vf(struct e1000_hw *hw, u32 *speed,\n \t\t\t\t     u16 *duplex);\n STATIC s32 e1000_init_hw_vf(struct e1000_hw *hw);\n STATIC s32 e1000_reset_hw_vf(struct e1000_hw *hw);\n@@ -220,7 +220,7 @@ STATIC s32 e1000_get_bus_info_pcie_vf(struct e1000_hw *hw)\n  *  Since we cannot read the PHY and get accurate link info, we must rely upon\n  *  the status register's data which is often stale and inaccurate.\n  **/\n-STATIC s32 e1000_get_link_up_info_vf(struct e1000_hw *hw, u16 *speed,\n+STATIC s32 e1000_get_link_up_info_vf(struct e1000_hw *hw, u32 *speed,\n \t\t\t\t     u16 *duplex)\n {\n \ts32 status;\ndiff --git a/drivers/net/e1000/base/e1000_vf.h b/drivers/net/e1000/base/e1000_vf.h\nindex 6d5bd99..9d801ad 100644\n--- a/drivers/net/e1000/base/e1000_vf.h\n+++ b/drivers/net/e1000/base/e1000_vf.h\n@@ -201,7 +201,7 @@ struct e1000_mac_operations {\n \ts32  (*check_for_link)(struct e1000_hw *);\n \tvoid (*clear_vfta)(struct e1000_hw *);\n \ts32  (*get_bus_info)(struct e1000_hw *);\n-\ts32  (*get_link_up_info)(struct e1000_hw *, u16 *, u16 *);\n+\ts32  (*get_link_up_info)(struct e1000_hw *, u32 *, u16 *);\n \tvoid (*update_mc_addr_list)(struct e1000_hw *, u8 *, u32);\n \ts32  (*reset_hw)(struct e1000_hw *);\n \ts32  (*init_hw)(struct e1000_hw *);\ndiff --git a/drivers/net/e1000/em_ethdev.c b/drivers/net/e1000/em_ethdev.c\nindex 72f792c..35ef558 100644\n--- a/drivers/net/e1000/em_ethdev.c\n+++ b/drivers/net/e1000/em_ethdev.c\n@@ -493,6 +493,9 @@ eth_em_start(struct rte_eth_dev *dev)\n \tstruct e1000_hw *hw =\n \t\tE1000_DEV_PRIVATE_TO_HW(dev->data->dev_private);\n \tint ret, mask;\n+\tuint32_t *speeds;\n+\tint num_speeds;\n+\tbool autoneg;\n \n \tPMD_INIT_FUNC_TRACE();\n \n@@ -547,56 +550,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_LINK_SPEED_10:\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_LINK_SPEED_100:\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_NO_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_LINK_SPEED_1000:\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_LINK_SPEED_10000:\n-\tdefault:\n-\t\tgoto error_invalid_config;\n \t}\n+\n \te1000_setup_link(hw);\n \n \t/* check if lsc interrupt feature is enabled */\n@@ -616,9 +609,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@@ -934,11 +926,11 @@ eth_em_infos_get(struct rte_eth_dev *dev, struct rte_eth_dev_info *dev_info)\n \tdev_info->max_rx_queues = 1;\n \tdev_info->max_tx_queues = 1;\n \n-\tdev_info->speed_capa = ETH_SPEED_CAP_10M_HD |\n-\t\t\t\t\tETH_SPEED_CAP_10M_FD |\n-\t\t\t\t\tETH_SPEED_CAP_100M_HD |\n-\t\t\t\t\tETH_SPEED_CAP_100M_FD |\n-\t\t\t\t\tETH_SPEED_CAP_1G;\n+\tdev_info->speed_capa = ETH_LINK_SPEED_10M_HD |\n+\t\t\t\t\tETH_LINK_SPEED_10M |\n+\t\t\t\t\tETH_LINK_SPEED_100M_HD |\n+\t\t\t\t\tETH_LINK_SPEED_100M |\n+\t\t\t\t\tETH_LINK_SPEED_1G;\n }\n \n /* return 0 means link status changed, -1 means not changed */\n@@ -987,13 +979,16 @@ 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 == 0)) {\n+\t\tuint16_t duplex;\n \t\thw->mac.ops.get_link_up_info(hw, &link.link_speed,\n-\t\t\t&link.link_duplex);\n-\t\tlink.link_status = 1;\n+\t\t\t&duplex);\n+\t\tlink.link_duplex = (duplex) ? ETH_LINK_FULL_DUPLEX :\n+\t\t\t\t\t\tETH_LINK_HALF_DUPLEX;\n+\t\tlink.link_status = ETH_LINK_UP;\n \t} else if (!link_check && (link.link_status == 1)) {\n \t\tlink.link_speed = 0;\n-\t\tlink.link_duplex = 0;\n-\t\tlink.link_status = 0;\n+\t\tlink.link_duplex = ETH_LINK_HALF_DUPLEX;\n+\t\tlink.link_status = ETH_LINK_DOWN;\n \t}\n \trte_em_dev_atomic_write_link_status(dev, &link);\n \ndiff --git a/drivers/net/e1000/igb_ethdev.c b/drivers/net/e1000/igb_ethdev.c\nindex 927f5d9..2bbac02 100644\n--- a/drivers/net/e1000/igb_ethdev.c\n+++ b/drivers/net/e1000/igb_ethdev.c\n@@ -889,6 +889,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@@ -984,48 +987,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_LINK_SPEED_10:\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_LINK_SPEED_100:\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_NO_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_LINK_SPEED_1000:\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_LINK_SPEED_10000:\n-\tdefault:\n-\t\tgoto error_invalid_config;\n \t}\n+\n \te1000_setup_link(hw);\n \n \t/* check if lsc interrupt feature is enabled */\n@@ -1055,9 +1056,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@@ -1571,11 +1571,11 @@ eth_igb_infos_get(struct rte_eth_dev *dev, struct rte_eth_dev_info *dev_info)\n \t\t.txq_flags = 0,\n \t};\n \n-\tdev_info->speed_capa = ETH_SPEED_CAP_10M_HD |\n-\t\t\t\t\tETH_SPEED_CAP_10M_FD |\n-\t\t\t\t\tETH_SPEED_CAP_100M_HD |\n-\t\t\t\t\tETH_SPEED_CAP_100M_FD |\n-\t\t\t\t\tETH_SPEED_CAP_1G;\n+\tdev_info->speed_capa = ETH_LINK_SPEED_10M_HD |\n+\t\t\t\t\tETH_LINK_SPEED_10M |\n+\t\t\t\t\tETH_LINK_SPEED_100M_HD |\n+\t\t\t\t\tETH_LINK_SPEED_100M |\n+\t\t\t\t\tETH_LINK_SPEED_1G;\n }\n \n static void\n@@ -1681,13 +1681,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\tuint16_t duplex;\n \t\thw->mac.ops.get_link_up_info(hw, &link.link_speed,\n-\t\t\t\t\t  &link.link_duplex);\n-\t\tlink.link_status = 1;\n+\t\t\t\t\t  &duplex);\n+\t\tlink.link_duplex = (duplex) ? ETH_LINK_FULL_DUPLEX :\n+\t\t\t\t\t\t\tETH_LINK_HALF_DUPLEX ;\n+\t\tlink.link_status = ETH_LINK_UP;\n+\t\tlink.link_autoneg = ~(dev->data->dev_conf.link_speeds &\n+\t\t\t\t\t\tETH_LINK_SPEED_NO_AUTONEG);\n \t} else if (!link_check) {\n \t\tlink.link_speed = 0;\n-\t\tlink.link_duplex = 0;\n-\t\tlink.link_status = 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/fm10k/fm10k_ethdev.c b/drivers/net/fm10k/fm10k_ethdev.c\nindex ca6357c..6e05355 100644\n--- a/drivers/net/fm10k/fm10k_ethdev.c\n+++ b/drivers/net/fm10k/fm10k_ethdev.c\n@@ -862,7 +862,7 @@ fm10k_link_update(struct rte_eth_dev *dev,\n \t * is no 50Gbps Ethernet. */\n \tdev->data->dev_link.link_speed  = 0;\n \tdev->data->dev_link.link_duplex = ETH_LINK_FULL_DUPLEX;\n-\tdev->data->dev_link.link_status = 1;\n+\tdev->data->dev_link.link_status = ETH_LINK_UP;\n \n \treturn 0;\n }\n@@ -964,9 +964,9 @@ fm10k_dev_infos_get(struct rte_eth_dev *dev,\n \t\t\t\tETH_TXQ_FLAGS_NOOFFLOADS,\n \t};\n \n-\tdev_info->speed_capa = ETH_SPEED_CAP_1G | ETH_SPEED_CAP_2_5G |\n-\t\t\t\t\tETH_SPEED_CAP_10G | ETH_SPEED_CAP_25G |\n-\t\t\t\t\tETH_SPEED_CAP_40G | ETH_SPEED_CAP_100G;\n+\tdev_info->speed_capa = ETH_LINK_SPEED_1G | ETH_LINK_SPEED_2_5G |\n+\t\t\t\tETH_LINK_SPEED_10G | ETH_LINK_SPEED_25G |\n+\t\t\t\tETH_LINK_SPEED_40G | ETH_LINK_SPEED_100G;\n }\n \n static int\ndiff --git a/drivers/net/i40e/i40e_ethdev.c b/drivers/net/i40e/i40e_ethdev.c\nindex 8a5dfbf..b18e81f 100644\n--- a/drivers/net/i40e/i40e_ethdev.c\n+++ b/drivers/net/i40e/i40e_ethdev.c\n@@ -835,27 +835,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_LINK_SPEED_40G:\n-\t\tlink_speed = I40E_LINK_SPEED_40GB;\n-\t\tbreak;\n-\tcase ETH_LINK_SPEED_20G:\n-\t\tlink_speed = I40E_LINK_SPEED_20GB;\n-\t\tbreak;\n-\tcase ETH_LINK_SPEED_10G:\n-\t\tlink_speed = I40E_LINK_SPEED_10GB;\n-\t\tbreak;\n-\tcase ETH_LINK_SPEED_1000:\n-\t\tlink_speed = I40E_LINK_SPEED_1GB;\n-\t\tbreak;\n-\tcase ETH_LINK_SPEED_100:\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@@ -924,9 +917,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@@ -944,10 +937,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_NO_AUTONEG) {\n+\t\tPMD_INIT_LOG(ERR, \"Invalid link_speeds for port %hhu; autonegociation disabled\",\n \t\t\t     dev->data->port_id);\n \t\treturn -EINVAL;\n \t}\n@@ -995,6 +986,13 @@ 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+\n \tret = i40e_apply_link_speed(dev);\n \tif (I40E_SUCCESS != ret) {\n \t\tPMD_DRV_LOG(ERR, \"Fail to apply link setting\");\n@@ -1209,7 +1207,7 @@ i40e_dev_link_update(struct rte_eth_dev *dev,\n \t\t/* Get link status information from hardware */\n \t\tstatus = i40e_aq_get_link_info(hw, false, &link_status, NULL);\n \t\tif (status != I40E_SUCCESS) {\n-\t\t\tlink.link_speed = ETH_LINK_SPEED_100;\n+\t\t\tlink.link_speed = ETH_SPEED_NUM_100M;\n \t\t\tlink.link_duplex = ETH_LINK_FULL_DUPLEX;\n \t\t\tPMD_DRV_LOG(ERR, \"Failed to get link info\");\n \t\t\tgoto out;\n@@ -1231,25 +1229,28 @@ i40e_dev_link_update(struct rte_eth_dev *dev,\n \t/* Parse the link status */\n \tswitch (link_status.link_speed) {\n \tcase I40E_LINK_SPEED_100MB:\n-\t\tlink.link_speed = ETH_LINK_SPEED_100;\n+\t\tlink.link_speed = ETH_SPEED_NUM_100M;\n \t\tbreak;\n \tcase I40E_LINK_SPEED_1GB:\n-\t\tlink.link_speed = ETH_LINK_SPEED_1000;\n+\t\tlink.link_speed = ETH_SPEED_NUM_1G;\n \t\tbreak;\n \tcase I40E_LINK_SPEED_10GB:\n-\t\tlink.link_speed = ETH_LINK_SPEED_10G;\n+\t\tlink.link_speed = ETH_SPEED_NUM_10G;\n \t\tbreak;\n \tcase I40E_LINK_SPEED_20GB:\n-\t\tlink.link_speed = ETH_LINK_SPEED_20G;\n+\t\tlink.link_speed = ETH_SPEED_NUM_20G;\n \t\tbreak;\n \tcase I40E_LINK_SPEED_40GB:\n-\t\tlink.link_speed = ETH_LINK_SPEED_40G;\n+\t\tlink.link_speed = ETH_SPEED_NUM_40G;\n \t\tbreak;\n \tdefault:\n-\t\tlink.link_speed = ETH_LINK_SPEED_100;\n+\t\tlink.link_speed = ETH_SPEED_NUM_100M;\n \t\tbreak;\n \t}\n \n+\tlink.link_autoneg = ~(dev->data->dev_conf.link_speeds &\n+\t\t\t\t\t\tETH_LINK_SPEED_NO_AUTONEG);\n+\n out:\n \trte_i40e_dev_atomic_write_link_status(dev, &link);\n \tif (link.link_status == old.link_status)\n@@ -1687,10 +1688,10 @@ i40e_dev_info_get(struct rte_eth_dev *dev, struct rte_eth_dev_info *dev_info)\n \n \tif (i40e_is_40G_device(hw->device_id))\n \t\t/* For XL710 */\n-\t\tdev_info->speed_capa = ETH_SPEED_CAP_1G | ETH_SPEED_CAP_10G;\n+\t\tdev_info->speed_capa = ETH_LINK_SPEED_1G | ETH_LINK_SPEED_10G;\n \telse\n \t\t/* For X710 */\n-\t\tdev_info->speed_capa = ETH_SPEED_CAP_10G | ETH_SPEED_CAP_40G;\n+\t\tdev_info->speed_capa = ETH_LINK_SPEED_10G | ETH_LINK_SPEED_40G;\n \n }\n \n@@ -6195,15 +6196,15 @@ i40e_timesync_enable(struct rte_eth_dev *dev)\n \tuint32_t tsync_inc_h;\n \n \tswitch (link->link_speed) {\n-\tcase ETH_LINK_SPEED_40G:\n+\tcase ETH_SPEED_NUM_40G:\n \t\ttsync_inc_l = I40E_PTP_40GB_INCVAL & 0xFFFFFFFF;\n \t\ttsync_inc_h = I40E_PTP_40GB_INCVAL >> 32;\n \t\tbreak;\n-\tcase ETH_LINK_SPEED_10G:\n+\tcase ETH_SPEED_NUM_10G:\n \t\ttsync_inc_l = I40E_PTP_10GB_INCVAL & 0xFFFFFFFF;\n \t\ttsync_inc_h = I40E_PTP_10GB_INCVAL >> 32;\n \t\tbreak;\n-\tcase ETH_LINK_SPEED_1000:\n+\tcase ETH_SPEED_NUM_1G:\n \t\ttsync_inc_l = I40E_PTP_1GB_INCVAL & 0xFFFFFFFF;\n \t\ttsync_inc_h = I40E_PTP_1GB_INCVAL >> 32;\n \t\tbreak;\ndiff --git a/drivers/net/i40e/i40e_ethdev_vf.c b/drivers/net/i40e/i40e_ethdev_vf.c\nindex b694400..8d3acae 100644\n--- a/drivers/net/i40e/i40e_ethdev_vf.c\n+++ b/drivers/net/i40e/i40e_ethdev_vf.c\n@@ -1635,13 +1635,14 @@ 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_LINK_SPEED_10000;\n-\t\tnew_link.link_status = 1;\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_NEG;\n+\t\tnew_link.link_status = ETH_LINK_UP;\n \t}\n \ti40evf_dev_atomic_write_link_status(dev, &new_link);\n \ndiff --git a/drivers/net/ixgbe/ixgbe_ethdev.c b/drivers/net/ixgbe/ixgbe_ethdev.c\nindex 3be84aa..f4dd1d2 100644\n--- a/drivers/net/ixgbe/ixgbe_ethdev.c\n+++ b/drivers/net/ixgbe/ixgbe_ethdev.c\n@@ -1676,14 +1676,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_NO_AUTONEG) {\n+\t\tPMD_INIT_LOG(ERR, \"Invalid link_speeds for port %hhu; autonegociation disabled\",\n \t\t\t     dev->data->port_id);\n \t\treturn -EINVAL;\n \t}\n@@ -1769,32 +1768,22 @@ 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_LINK_SPEED_100:\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_LINK_SPEED_1000:\n-\t\tspeed = IXGBE_LINK_SPEED_1GB_FULL;\n-\t\tbreak;\n-\tcase ETH_LINK_SPEED_10000:\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\t\t\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+\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@@ -2400,15 +2389,16 @@ ixgbe_dev_info_get(struct rte_eth_dev *dev, struct rte_eth_dev_info *dev_info)\n \tdev_info->reta_size = ETH_RSS_RETA_SIZE_128;\n \tdev_info->flow_type_rss_offloads = IXGBE_RSS_OFFLOAD_ALL;\n \n-\tdev_info->speed_capa = ETH_SPEED_CAP_1G | ETH_SPEED_CAP_10G;\n+\tdev_info->speed_capa = ETH_LINK_SPEED_1G | ETH_LINK_SPEED_10G;\n \n \tif (hw->mac.type == ixgbe_mac_X540 ||\n \t    hw->mac.type == ixgbe_mac_X540_vf ||\n \t    hw->mac.type == ixgbe_mac_X550 ||\n-\t    hw->mac.type == ixgbe_mac_X550_vf)\n+\t    hw->mac.type == ixgbe_mac_X550_vf) {\n \n-\t\tdev_info->speed_capa |= ETH_SPEED_CAP_100M_FD /*|\n-\t\t\t\t\tETH_SPEED_CAP_100M_HD*/;\n+\t\tdev_info->speed_capa |= ETH_LINK_SPEED_100M /*|\n+\t\t\t\t\tETH_LINK_SPEED_100M_HD*/;\n+\t}\n }\n \n static void\n@@ -2471,9 +2461,9 @@ ixgbe_dev_link_update(struct rte_eth_dev *dev, int wait_to_complete)\n \tint link_up;\n \tint diag;\n \n-\tlink.link_status = 0;\n+\tlink.link_status = ETH_LINK_DOWN;\n \tlink.link_speed = 0;\n-\tlink.link_duplex = 0;\n+\tlink.link_duplex = ETH_LINK_HALF_DUPLEX;\n \tmemset(&old, 0, sizeof(old));\n \trte_ixgbe_dev_atomic_read_link_status(dev, &old);\n \n@@ -2486,8 +2476,8 @@ ixgbe_dev_link_update(struct rte_eth_dev *dev, int wait_to_complete)\n \t\tdiag = ixgbe_check_link(hw, &link_speed, &link_up, 1);\n \n \tif (diag != 0) {\n-\t\tlink.link_speed = ETH_LINK_SPEED_100;\n-\t\tlink.link_duplex = ETH_LINK_HALF_DUPLEX;\n+\t\tlink.link_speed = ETH_SPEED_NUM_100M;\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@@ -2500,26 +2490,26 @@ ixgbe_dev_link_update(struct rte_eth_dev *dev, int wait_to_complete)\n \t\t\treturn -1;\n \t\treturn 0;\n \t}\n-\tlink.link_status = 1;\n+\tlink.link_status = ETH_LINK_UP;\n \tlink.link_duplex = ETH_LINK_FULL_DUPLEX;\n \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_speed = ETH_LINK_SPEED_100;\n+\t\tlink.link_duplex = ETH_LINK_FULL_DUPLEX;\n+\t\tlink.link_speed = ETH_SPEED_NUM_100M;\n \t\tbreak;\n \n \tcase IXGBE_LINK_SPEED_100_FULL:\n-\t\tlink.link_speed = ETH_LINK_SPEED_100;\n+\t\tlink.link_speed = ETH_SPEED_NUM_100M;\n \t\tbreak;\n \n \tcase IXGBE_LINK_SPEED_1GB_FULL:\n-\t\tlink.link_speed = ETH_LINK_SPEED_1000;\n+\t\tlink.link_speed = ETH_SPEED_NUM_1G;\n \t\tbreak;\n \n \tcase IXGBE_LINK_SPEED_10GB_FULL:\n-\t\tlink.link_speed = ETH_LINK_SPEED_10000;\n+\t\tlink.link_speed = ETH_SPEED_NUM_10G;\n \t\tbreak;\n \t}\n \trte_ixgbe_dev_atomic_write_link_status(dev, &link);\ndiff --git a/drivers/net/mlx4/mlx4.c b/drivers/net/mlx4/mlx4.c\nindex b45e21a..96fe4b6 100644\n--- a/drivers/net/mlx4/mlx4.c\n+++ b/drivers/net/mlx4/mlx4.c\n@@ -4207,6 +4207,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\t\t\t\tETH_LINK_SPEED_NO_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 743feef..5875371 100644\n--- a/drivers/net/mpipe/mpipe_tilegx.c\n+++ b/drivers/net/mpipe/mpipe_tilegx.c\n@@ -388,14 +388,16 @@ 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\t\t\tETH_LINK_SPEED_NO_AUTONEG);\n \t\tif (speed == GXIO_MPIPE_LINK_1G) {\n \t\t\tnew.link_speed = ETH_LINK_SPEED_1000;\n \t\t\tnew.link_duplex = ETH_LINK_FULL_DUPLEX;\n-\t\t\tnew.link_status = 1;\n+\t\t\tnew.link_status = ETH_LINK_UP;\n \t\t} else if (speed == GXIO_MPIPE_LINK_10G) {\n \t\t\tnew.link_speed = ETH_LINK_SPEED_10000;\n \t\t\tnew.link_duplex = ETH_LINK_FULL_DUPLEX;\n-\t\t\tnew.link_status = 1;\n+\t\t\tnew.link_status = ETH_LINK_UP;\n \t\t}\n \n \t\trc = mpipe_link_compare(&old, &new);\ndiff --git a/drivers/net/null/rte_eth_null.c b/drivers/net/null/rte_eth_null.c\nindex e244595..7704fa6 100644\n--- a/drivers/net/null/rte_eth_null.c\n+++ b/drivers/net/null/rte_eth_null.c\n@@ -79,9 +79,10 @@ struct pmd_internals {\n static struct ether_addr eth_addr = { .addr_bytes = {0} };\n static const char *drivername = \"Null PMD\";\n static struct rte_eth_link pmd_link = {\n-\t.link_speed = 10000,\n+\t.link_speed = ETH_SPEED_NUM_10G,\n \t.link_duplex = ETH_LINK_FULL_DUPLEX,\n-\t.link_status = 0\n+\t.link_status = ETH_LINK_DOWN,\n+\t.link_autoneg = ETH_LINK_SPEED_NEG,\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 f2e4634..ea7a28f 100644\n--- a/drivers/net/pcap/rte_eth_pcap.c\n+++ b/drivers/net/pcap/rte_eth_pcap.c\n@@ -125,9 +125,10 @@ static int open_single_iface(const char *iface, pcap_t **pcap);\n static struct ether_addr eth_addr = { .addr_bytes = { 0, 0, 0, 0x1, 0x2, 0x3 } };\n static const char *drivername = \"Pcap PMD\";\n static struct rte_eth_link pmd_link = {\n-\t\t.link_speed = 10000,\n+\t\t.link_speed = ETH_SPEED_NUM_10G,\n \t\t.link_duplex = ETH_LINK_FULL_DUPLEX,\n-\t\t.link_status = 0\n+\t\t.link_status = ETH_LINK_DOWN,\n+\t\t.link_autoneg = ETH_LINK_SPEED_FIXED,\n };\n \n static int\n@@ -430,7 +431,7 @@ eth_dev_start(struct rte_eth_dev *dev)\n \n status_up:\n \n-\tdev->data->dev_link.link_status = 1;\n+\tdev->data->dev_link.link_status = ETH_LINK_UP;\n \treturn 0;\n }\n \n@@ -481,7 +482,7 @@ eth_dev_stop(struct rte_eth_dev *dev)\n \t}\n \n status_down:\n-\tdev->data->dev_link.link_status = 0;\n+\tdev->data->dev_link.link_status = ETH_LINK_DOWN;\n }\n \n static int\ndiff --git a/drivers/net/ring/rte_eth_ring.c b/drivers/net/ring/rte_eth_ring.c\nindex 0ba36d5..626c381 100644\n--- a/drivers/net/ring/rte_eth_ring.c\n+++ b/drivers/net/ring/rte_eth_ring.c\n@@ -71,9 +71,10 @@ struct pmd_internals {\n \n static const char *drivername = \"Rings PMD\";\n static struct rte_eth_link pmd_link = {\n-\t\t.link_speed = 10000,\n+\t\t.link_speed = ETH_SPEED_NUM_10G,\n \t\t.link_duplex = ETH_LINK_FULL_DUPLEX,\n-\t\t.link_status = 0\n+\t\t.link_status = ETH_LINK_DOWN,\n+\t\t.link_autoneg = ETH_LINK_SPEED_NEG\n };\n \n static uint16_t\ndiff --git a/drivers/net/virtio/virtio_ethdev.c b/drivers/net/virtio/virtio_ethdev.c\nindex 465d3cd..ecbf9f2 100644\n--- a/drivers/net/virtio/virtio_ethdev.c\n+++ b/drivers/net/virtio/virtio_ethdev.c\n@@ -1517,7 +1517,7 @@ virtio_dev_link_update(struct rte_eth_dev *dev, __rte_unused int wait_to_complet\n \tmemset(&link, 0, sizeof(link));\n \tvirtio_dev_atomic_read_link_status(dev, &link);\n \told = link;\n-\tlink.link_duplex = FULL_DUPLEX;\n+\tlink.link_duplex = ETH_LINK_FULL_DUPLEX;\n \tlink.link_speed  = SPEED_10G;\n \n \tif (vtpci_with_feature(hw, VIRTIO_NET_F_STATUS)) {\ndiff --git a/drivers/net/virtio/virtio_ethdev.h b/drivers/net/virtio/virtio_ethdev.h\nindex 9026d42..424d650 100644\n--- a/drivers/net/virtio/virtio_ethdev.h\n+++ b/drivers/net/virtio/virtio_ethdev.h\n@@ -42,8 +42,6 @@\n #define SPEED_100\t100\n #define SPEED_1000\t1000\n #define SPEED_10G\t10000\n-#define HALF_DUPLEX\t1\n-#define FULL_DUPLEX\t2\n \n #ifndef PAGE_SIZE\n #define PAGE_SIZE 4096\ndiff --git a/drivers/net/vmxnet3/vmxnet3_ethdev.c b/drivers/net/vmxnet3/vmxnet3_ethdev.c\nindex a70be5c..6860360 100644\n--- a/drivers/net/vmxnet3/vmxnet3_ethdev.c\n+++ b/drivers/net/vmxnet3/vmxnet3_ethdev.c\n@@ -697,9 +697,10 @@ vmxnet3_dev_link_update(struct rte_eth_dev *dev, __attribute__((unused)) int wai\n \tret = VMXNET3_READ_BAR1_REG(hw, VMXNET3_REG_CMD);\n \n \tif (ret & 0x1) {\n-\t\tlink.link_status = 1;\n+\t\tlink.link_status = ETH_LINK_UP;\n \t\tlink.link_duplex = ETH_LINK_FULL_DUPLEX;\n-\t\tlink.link_speed = ETH_LINK_SPEED_10000;\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 73e8bce..fb492ee 100644\n--- a/drivers/net/xenvirt/rte_eth_xenvirt.c\n+++ b/drivers/net/xenvirt/rte_eth_xenvirt.c\n@@ -70,9 +70,10 @@ static int virtio_idx = 0;\n static const char *drivername = \"xen dummy virtio PMD\";\n \n static struct rte_eth_link pmd_link = {\n-\t\t.link_speed = 10000,\n+\t\t.link_speed = ETH_SPEED_NUM_10G,\n \t\t.link_duplex = ETH_LINK_FULL_DUPLEX,\n-\t\t.link_status = 0\n+\t\t.link_status = ETH_LINK_DOWN,\n+\t\t.link_autoneg = ETH_LINK_SPEED_FIXED\n };\n \n static inline struct rte_mbuf *\ndiff --git a/examples/ip_pipeline/config_parse.c b/examples/ip_pipeline/config_parse.c\nindex c9b78f9..92e6a18 100644\n--- a/examples/ip_pipeline/config_parse.c\n+++ b/examples/ip_pipeline/config_parse.c\n@@ -83,8 +83,7 @@ static const struct app_link_params link_params_default = {\n \t.mac_addr = 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.c b/lib/librte_ether/rte_ethdev.c\nindex f593f6e..29b2960 100644\n--- a/lib/librte_ether/rte_ethdev.c\n+++ b/lib/librte_ether/rte_ethdev.c\n@@ -1072,6 +1072,55 @@ rte_eth_dev_check_mq_mode(uint8_t port_id, uint16_t nb_rx_q, uint16_t nb_tx_q,\n }\n \n int\n+rte_eth_speed_to_bm_flag(uint32_t speed, int duplex, uint32_t *flag)\n+{\n+\tswitch (speed) {\n+\tcase ETH_SPEED_NUM_10M:\n+\t\t*flag = (duplex) ? ETH_LINK_SPEED_10M :\n+\t\t\t\t\t\t\tETH_LINK_SPEED_10M_HD;\n+\t\tbreak;\n+\tcase ETH_SPEED_NUM_100M:\n+\t\t*flag = (duplex) ? ETH_LINK_SPEED_100M :\n+\t\t\t\t\t\t\tETH_LINK_SPEED_100M_HD;\n+\t\tbreak;\n+\tcase ETH_SPEED_NUM_1G:\n+\t\t*flag = ETH_LINK_SPEED_1G;\n+\t\tbreak;\n+\tcase ETH_SPEED_NUM_2_5G:\n+\t\t*flag = ETH_LINK_SPEED_2_5G;\n+\t\tbreak;\n+\tcase ETH_SPEED_NUM_5G:\n+\t\t*flag = ETH_LINK_SPEED_5G;\n+\t\tbreak;\n+\tcase ETH_SPEED_NUM_10G:\n+\t\t*flag = ETH_LINK_SPEED_10G;\n+\t\tbreak;\n+\tcase ETH_SPEED_NUM_20G:\n+\t\t*flag = ETH_LINK_SPEED_20G;\n+\t\tbreak;\n+\tcase ETH_SPEED_NUM_25G:\n+\t\t*flag = ETH_LINK_SPEED_25G;\n+\t\tbreak;\n+\tcase ETH_SPEED_NUM_40G:\n+\t\t*flag = ETH_LINK_SPEED_40G;\n+\t\tbreak;\n+\tcase ETH_SPEED_NUM_50G:\n+\t\t*flag = ETH_LINK_SPEED_50G;\n+\t\tbreak;\n+\tcase ETH_SPEED_NUM_56G:\n+\t\t*flag = ETH_LINK_SPEED_56G;\n+\t\tbreak;\n+\tcase ETH_SPEED_NUM_100G:\n+\t\t*flag = ETH_LINK_SPEED_100G;\n+\t\tbreak;\n+\tdefault:\n+\t\treturn -EINVAL;\n+\t}\n+\n+\treturn 0;\n+}\n+\n+int\n rte_eth_dev_configure(uint8_t port_id, uint16_t nb_rx_q, uint16_t nb_tx_q,\n \t\t      const struct rte_eth_conf *dev_conf)\n {\ndiff --git a/lib/librte_ether/rte_ethdev.h b/lib/librte_ether/rte_ethdev.h\nindex 951a423..54ee6f9 100644\n--- a/lib/librte_ether/rte_ethdev.h\n+++ b/lib/librte_ether/rte_ethdev.h\n@@ -238,26 +238,59 @@ struct rte_eth_stats {\n };\n \n /**\n+ * Device supported speeds bitmap flags\n+ */\n+#define ETH_LINK_SPEED_AUTONEG\t\t(0 << 0)  /*< Autonegociate (all speeds)  */\n+#define ETH_LINK_SPEED_NO_AUTONEG\t(1 << 0)  /*< Disable autoneg (fixed speed)  */\n+#define ETH_LINK_SPEED_10M_HD\t\t(1 << 1)  /*< 10 Mbps half-duplex */\n+#define ETH_LINK_SPEED_10M\t\t(1 << 2)  /*< 10 Mbps full-duplex */\n+#define ETH_LINK_SPEED_100M_HD\t\t(1 << 3)  /*< 100 Mbps half-duplex */\n+#define ETH_LINK_SPEED_100M\t\t(1 << 4)  /*< 100 Mbps full-duplex */\n+#define ETH_LINK_SPEED_1G\t\t(1 << 5)  /*< 1 Gbps */\n+#define ETH_LINK_SPEED_2_5G\t\t(1 << 6)  /*< 2.5 Gbps */\n+#define ETH_LINK_SPEED_5G\t\t(1 << 7)  /*< 5 Gbps */\n+#define ETH_LINK_SPEED_10G\t\t(1 << 8)  /*< 10 Mbps */\n+#define ETH_LINK_SPEED_20G\t\t(1 << 9)  /*< 20 Gbps */\n+#define ETH_LINK_SPEED_25G\t\t(1 << 10)  /*< 25 Gbps */\n+#define ETH_LINK_SPEED_40G\t\t(1 << 11)  /*< 40 Gbps */\n+#define ETH_LINK_SPEED_50G\t\t(1 << 12)  /*< 50 Gbps */\n+#define ETH_LINK_SPEED_56G\t\t(1 << 13)  /*< 56 Gbps */\n+#define ETH_LINK_SPEED_100G\t\t(1 << 14)  /*< 100 Gbps */\n+\n+/**\n+ * Ethernet numeric link speeds in Mbps\n+ */\n+#define ETH_SPEED_NUM_NONE\t0      /*< Not defined */\n+#define ETH_SPEED_NUM_10M\t10     /*< 10 Mbps */\n+#define ETH_SPEED_NUM_100M\t100    /*< 100 Mbps */\n+#define ETH_SPEED_NUM_1G\t1000   /*< 1 Gbps */\n+#define ETH_SPEED_NUM_2_5G\t2500   /*< 2.5 Gbps */\n+#define ETH_SPEED_NUM_5G\t5000   /*< 5 Gbps */\n+#define ETH_SPEED_NUM_10G\t10000  /*< 10 Mbps */\n+#define ETH_SPEED_NUM_20G\t20000  /*< 20 Gbps */\n+#define ETH_SPEED_NUM_25G\t25000  /*< 25 Gbps */\n+#define ETH_SPEED_NUM_40G\t40000  /*< 40 Gbps */\n+#define ETH_SPEED_NUM_50G\t50000  /*< 50 Gbps */\n+#define ETH_SPEED_NUM_56G\t56000  /*< 56 Gbps */\n+#define ETH_SPEED_NUM_100G\t100000 /*< 100 Gbps */\n+\n+/**\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_LINK_SPEED_[10, 100, 1000, 10000] */\n-\tuint16_t link_duplex;     /**< ETH_LINK_[HALF_DUPLEX, FULL_DUPLEX] */\n-\tuint8_t  link_status : 1; /**< 1 -> link up, 0 -> link down */\n-}__attribute__((aligned(8)));     /**< aligned for atomic64 read/write */\n-\n-#define ETH_LINK_SPEED_AUTONEG  0       /**< Auto-negotiate link speed. */\n-#define ETH_LINK_SPEED_10       10      /**< 10 megabits/second. */\n-#define ETH_LINK_SPEED_100      100     /**< 100 megabits/second. */\n-#define ETH_LINK_SPEED_1000     1000    /**< 1 gigabits/second. */\n-#define ETH_LINK_SPEED_10000    10000   /**< 10 gigabits/second. */\n-#define ETH_LINK_SPEED_10G      10000   /**< alias of 10 gigabits/second. */\n-#define ETH_LINK_SPEED_20G      20000   /**< 20 gigabits/second. */\n-#define ETH_LINK_SPEED_40G      40000   /**< 40 gigabits/second. */\n+\tuint32_t link_speed;        /**< Link speed (ETH_SPEED_NUM_) */\n+\tuint16_t link_duplex  : 1;  /**< 1 -> full duplex, 0 -> half duplex */\n+\tuint16_t link_autoneg : 1;  /**< 1 -> link speed has been autoneg */\n+\tuint16_t link_status  : 1;  /**< 1 -> link up, 0 -> link down */\n+} __attribute__((aligned(8)));      /**< aligned for atomic64 read/write */\n \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+/* Utility constants */\n+#define ETH_LINK_HALF_DUPLEX    0\t/**< Half-duplex connection. */\n+#define ETH_LINK_FULL_DUPLEX    1\t/**< Full-duplex connection. */\n+#define ETH_LINK_SPEED_FIXED    0\t/**< Link speed was not autonegociated. */\n+#define ETH_LINK_SPEED_NEG      1\t/**< Link speed was autonegociated. */\n+#define ETH_LINK_DOWN\t\t0\t/**< Link is down. */\n+#define ETH_LINK_UP\t\t1\t/**< Link is up. */\n \n /**\n  * A structure used to configure the ring threshold registers of an RX/TX\n@@ -747,10 +780,14 @@ struct rte_intr_conf {\n  * configuration settings may be needed.\n  */\n struct rte_eth_conf {\n-\tuint16_t link_speed;\n-\t/**< ETH_LINK_SPEED_10[0|00|000], or 0 for autonegotation */\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_NO_AUTONEG disables link\n+\t\t\t\tautonegociation, 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+\t\t\t\t*/\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@@ -812,26 +849,6 @@ struct rte_eth_conf {\n #define DEV_TX_OFFLOAD_QINQ_INSERT 0x00000100\n \n /**\n- * Device supported speeds\n- */\n-#define ETH_SPEED_CAP_NOT_PHY\t(0)  /*< No phy media > */\n-#define ETH_SPEED_CAP_10M_HD\t(1 << 0)  /*< 10 Mbps half-duplex> */\n-#define ETH_SPEED_CAP_10M_FD\t(1 << 1)  /*< 10 Mbps full-duplex> */\n-#define ETH_SPEED_CAP_100M_HD\t(1 << 2)  /*< 100 Mbps half-duplex> */\n-#define ETH_SPEED_CAP_100M_FD\t(1 << 3)  /*< 100 Mbps full-duplex> */\n-#define ETH_SPEED_CAP_1G\t(1 << 4)  /*< 1 Gbps > */\n-#define ETH_SPEED_CAP_2_5G\t(1 << 5)  /*< 2.5 Gbps > */\n-#define ETH_SPEED_CAP_5G\t(1 << 6)  /*< 5 Gbps > */\n-#define ETH_SPEED_CAP_10G\t(1 << 7)  /*< 10 Mbps > */\n-#define ETH_SPEED_CAP_20G\t(1 << 8)  /*< 20 Gbps > */\n-#define ETH_SPEED_CAP_25G\t(1 << 9)  /*< 25 Gbps > */\n-#define ETH_SPEED_CAP_40G\t(1 << 10)  /*< 40 Gbps > */\n-#define ETH_SPEED_CAP_50G\t(1 << 11)  /*< 50 Gbps > */\n-#define ETH_SPEED_CAP_56G\t(1 << 12)  /*< 56 Gbps > */\n-#define ETH_SPEED_CAP_100G\t(1 << 13)  /*< 100 Gbps > */\n-\n-\n-/**\n  * Ethernet device information\n  */\n struct rte_eth_dev_info {\n@@ -1667,6 +1684,22 @@ struct eth_driver {\n extern void rte_eth_driver_register(struct eth_driver *eth_drv);\n \n /**\n+ * Convert a numerical speed in Mbps to a bitmap flag that can be used in\n+ * the bitmap link_speeds of the struct rte_eth_conf\n+ *\n+ * @param\n+ *   Numerical speed value in Mbps\n+ * @param\n+ *   Boolean is duplex (only for 10/100 speeds)\n+ * @param\n+ *   On success, the converted speed into a bitmap flag\n+ * @return\n+ *   0 on success, -EINVAL if the speed cannot be mapped\n+ */\n+extern int rte_eth_speed_to_bm_flag(uint32_t speed, int duplex,\n+\t\t\t\t\t\t\tuint32_t *flag);\n+\n+/**\n  * Configure an Ethernet device.\n  * This function must be invoked first before any other function in the\n  * Ethernet API. This function can also be re-invoked when a device is in the\n",
    "prefixes": [
        "dpdk-dev",
        "v6",
        "3/5"
    ]
}