get:
Show a patch.

patch:
Update a patch.

put:
Update a patch.

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

{
    "id": 138855,
    "url": "http://patchwork.dpdk.org/api/patches/138855/?format=api",
    "web_url": "http://patchwork.dpdk.org/project/dpdk/patch/20240326235909.25276-1-mpazdan@arista.com/",
    "project": {
        "id": 1,
        "url": "http://patchwork.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": "<20240326235909.25276-1-mpazdan@arista.com>",
    "list_archive_url": "https://inbox.dpdk.org/dev/20240326235909.25276-1-mpazdan@arista.com",
    "date": "2024-03-26T23:59:07",
    "name": "igc/ixgbe: add get/set link settings interface",
    "commit_ref": null,
    "pull_url": null,
    "state": "new",
    "archived": false,
    "hash": "36b9658276bfd06bd9a0a27731fa8cd0f87a1817",
    "submitter": {
        "id": 3302,
        "url": "http://patchwork.dpdk.org/api/people/3302/?format=api",
        "name": "Marek Pazdan",
        "email": "mpazdan@arista.com"
    },
    "delegate": {
        "id": 319,
        "url": "http://patchwork.dpdk.org/api/users/319/?format=api",
        "username": "fyigit",
        "first_name": "Ferruh",
        "last_name": "Yigit",
        "email": "ferruh.yigit@amd.com"
    },
    "mbox": "http://patchwork.dpdk.org/project/dpdk/patch/20240326235909.25276-1-mpazdan@arista.com/mbox/",
    "series": [
        {
            "id": 31628,
            "url": "http://patchwork.dpdk.org/api/series/31628/?format=api",
            "web_url": "http://patchwork.dpdk.org/project/dpdk/list/?series=31628",
            "date": "2024-03-26T23:59:07",
            "name": "igc/ixgbe: add get/set link settings interface",
            "version": 1,
            "mbox": "http://patchwork.dpdk.org/series/31628/mbox/"
        }
    ],
    "comments": "http://patchwork.dpdk.org/api/patches/138855/comments/",
    "check": "fail",
    "checks": "http://patchwork.dpdk.org/api/patches/138855/checks/",
    "tags": {},
    "related": [],
    "headers": {
        "Return-Path": "<dev-bounces@dpdk.org>",
        "X-Original-To": "patchwork@inbox.dpdk.org",
        "Delivered-To": "patchwork@inbox.dpdk.org",
        "Received": [
            "from mails.dpdk.org (mails.dpdk.org [217.70.189.124])\n\tby inbox.dpdk.org (Postfix) with ESMTP id B276D43D66;\n\tWed, 27 Mar 2024 11:07:51 +0100 (CET)",
            "from mails.dpdk.org (localhost [127.0.0.1])\n\tby mails.dpdk.org (Postfix) with ESMTP id 9ED30402B2;\n\tWed, 27 Mar 2024 11:07:51 +0100 (CET)",
            "from mail-oa1-f97.google.com (mail-oa1-f97.google.com\n [209.85.160.97]) by mails.dpdk.org (Postfix) with ESMTP id E163B402A3\n for <dev@dpdk.org>; Wed, 27 Mar 2024 00:59:12 +0100 (CET)",
            "by mail-oa1-f97.google.com with SMTP id\n 586e51a60fabf-22a73f2d6adso373100fac.3\n for <dev@dpdk.org>; Tue, 26 Mar 2024 16:59:12 -0700 (PDT)",
            "from smtp.aristanetworks.com ([74.123.28.25])\n by smtp-relay.gmail.com with ESMTPS id\n i6-20020a632206000000b005e49d335f81sm411921pgi.22.2024.03.26.16.59.11\n (version=TLS1_2 cipher=ECDHE-ECDSA-AES128-GCM-SHA256 bits=128/128);\n Tue, 26 Mar 2024 16:59:11 -0700 (PDT)",
            "from mpazdan-autoneg-dpdk-0.sjc.aristanetworks.com\n (dhcp-243-132-215.sjc.aristanetworks.com [10.243.132.215])\n by smtp.aristanetworks.com (Postfix) with ESMTP id B4F61400F87;\n Tue, 26 Mar 2024 16:59:09 -0700 (PDT)"
        ],
        "X-Google-DKIM-Signature": "v=1; a=rsa-sha256; c=relaxed/relaxed;\n d=1e100.net; s=20230601; t=1711497552; x=1712102352;\n h=content-transfer-encoding:message-id:date:subject:cc:to:from\n :dkim-signature:x-gm-message-state:from:to:cc:subject:date\n :message-id:reply-to;\n bh=Tc0QgGBDxnWPz3L30gKTaZm0i9huIH7BbskK5e7HvE4=;\n b=YKRnjqzq/8XRi1ltrFPKKc8q4iPP7PycG395CLGfCQtN2AG73vjK6bexWff9TZ9L0J\n JT4J1XMKVp0j3GTo6IVBwglGe1hWR0xjVbp48EtDqot4gVI943pkz5liCtVe4PiuMYYZ\n aMBNmLB8zNBrY5VHZ0KFpwjKqlJiPCWnJ3aHeK72lYhQtzy2cCugREfU5H3WuVyGGnI1\n PzU87AZolnHN+P8FZzoKWGOozsf9cuIrpGXtX/94woqqwXUFRy0MWzw8ABysSUOKu/ie\n 8gDJaiLJ7adqY420HMbQUNXAC7oQSnGiNC13IW0jz/w7Lh0mfiyYUPujMPzy9eyLAJo3\n RpMQ==",
        "X-Gm-Message-State": "AOJu0Ywb9Fy1mA/avCR7/kGKDcVaiPPV3E/3uZtCGoQxEt2OX5fThm1t\n WwM+IcvJ+A5TzsKHYBeeGPaNk1NhQhYb9aE5ORCyWT9W6Uc3E1i4u75CAueKVV/i01ShCmy77dQ\n cQyXYFXt1gWKy21TGPHJa7TXHVO2c5A==",
        "X-Google-Smtp-Source": "\n AGHT+IGgZNjRalxq+FXt0rCnJQAgoYqBkjrNrtFZuyGnROS2yJiiB9EjOqusm1NsRvEJTS4Ekn4jteK2+h9h",
        "X-Received": "by 2002:a05:6870:fb89:b0:221:9157:b587 with SMTP id\n kv9-20020a056870fb8900b002219157b587mr14107003oab.35.1711497551748;\n Tue, 26 Mar 2024 16:59:11 -0700 (PDT)",
        "X-Relaying-Domain": "arista.com",
        "DKIM-Signature": "v=1; a=rsa-sha256; c=relaxed/relaxed; d=arista.com;\n s=Arista-A; t=1711497549;\n bh=Tc0QgGBDxnWPz3L30gKTaZm0i9huIH7BbskK5e7HvE4=;\n h=From:To:Cc:Subject:Date:From;\n b=HORRdy91yNVD6ILg+rG+uKu4brkRBZpMu/c+rBaQe/IME69mr/nkj53YVtNILpFd8\n JWiwBqkg6pM6SxkLQuQ5Hj4Tpqz+BM9M2mJr5OfumTpwQu1URuNeBgx5hf+eI5jrZt\n 8PC0Qx5NGRvPF8P8BfsbZmgKvpQx8Pc9MTuVS60pwqoJBxcxgBs/KC8tKpYgtn2XQC\n VtrGQZ4IsAWvR1m4Wctz3MNWPbZFExZJlBpIa6JVCtb3ksf70dRpFcddzoYHNMmwrG\n nG0Y/u706dZgtPWqdmSM0f5B6rtOt8kb5kW/2RXUPLuXRVze4y8H6vC+zFIiMKCy1E\n sDWCg547sXkdg==",
        "X-SMTP-Authentication": [
            "Allow-List-permitted",
            "Allow-List-permitted"
        ],
        "From": "Marek Pazdan <mpazdan@arista.com>",
        "To": "Thomas Monjalon <thomas@monjalon.net>,\n Aman Singh <aman.deep.singh@intel.com>,\n Yuying Zhang <yuying.zhang@intel.com>, Ferruh Yigit <ferruh.yigit@amd.com>,\n Andrew Rybchenko <andrew.rybchenko@oktetlabs.ru>",
        "Cc": "dev@dpdk.org,\n\tMarek Pazdan <mpazdan@arista.com>",
        "Subject": "[PATCH] igc/ixgbe: add get/set link settings interface",
        "Date": "Tue, 26 Mar 2024 16:59:07 -0700",
        "Message-ID": "<20240326235909.25276-1-mpazdan@arista.com>",
        "Content-Type": "text/plain; charset=UTF-8",
        "Content-Transfer-Encoding": "8bit",
        "X-Mailman-Approved-At": "Wed, 27 Mar 2024 11:07:35 +0100",
        "X-BeenThere": "dev@dpdk.org",
        "X-Mailman-Version": "2.1.29",
        "Precedence": "list",
        "List-Id": "DPDK patches and discussions <dev.dpdk.org>",
        "List-Unsubscribe": "<https://mails.dpdk.org/options/dev>,\n <mailto:dev-request@dpdk.org?subject=unsubscribe>",
        "List-Archive": "<http://mails.dpdk.org/archives/dev/>",
        "List-Post": "<mailto:dev@dpdk.org>",
        "List-Help": "<mailto:dev-request@dpdk.org?subject=help>",
        "List-Subscribe": "<https://mails.dpdk.org/listinfo/dev>,\n <mailto:dev-request@dpdk.org?subject=subscribe>",
        "Errors-To": "dev-bounces@dpdk.org"
    },
    "content": "There are link settings parameters available from PMD drivers level\nwhich are currently not exposed to the user via consistent interface.\nWhen interface is available for system level those information can\nbe acquired with 'ethtool DEVNAME' (ioctl: ETHTOOL_SLINKSETTINGS/\nETHTOOL_GLINKSETTINGS). There are use cases where\nphysical interface is passthrough to dpdk driver and is not available\nfrom system level. Information provided by ioctl carries information\nuseful for link auto negotiation settings among others.\nAdditionally dpdk-testpmd application has been extended to provided\ntesting tool for newly implemtented interface functions.\n\nSigned-off-by: Marek Pazdan <mpazdan@arista.com>\n---\n .mailmap                           |   1 +\n app/test-pmd/cmdline.c             |   9 +\n app/test-pmd/cmdline_settings.c    | 516 +++++++++++++++++++++++++++++\n app/test-pmd/cmdline_settings.h    |  14 +\n app/test-pmd/meson.build           |   1 +\n app/test-pmd/testpmd.h             |   1 +\n app/test-pmd/util.c                |  10 +\n drivers/net/igc/igc_ethdev.c       | 229 ++++++++++++-\n drivers/net/ixgbe/base/ixgbe_phy.h |   7 +\n drivers/net/ixgbe/ixgbe_ethdev.c   | 395 ++++++++++++++++++++++\n lib/ethdev/ethdev_driver.h         |  33 ++\n lib/ethdev/rte_ethdev.c            |  26 ++\n lib/ethdev/rte_ethdev.h            | 215 +++++++++++-\n lib/ethdev/version.map             |   3 +\n 14 files changed, 1450 insertions(+), 10 deletions(-)\n create mode 100644 app/test-pmd/cmdline_settings.c\n create mode 100644 app/test-pmd/cmdline_settings.h",
    "diff": "diff --git a/.mailmap b/.mailmap\nindex 3843868716..145ce726ba 100644\n--- a/.mailmap\n+++ b/.mailmap\n@@ -885,6 +885,7 @@ Marcin Wojtas <mw@semihalf.com>\n Marcin Zapolski <marcinx.a.zapolski@intel.com>\n Marco Varlese <mvarlese@suse.de>\n Marc Sune <marcdevel@gmail.com> <marc.sune@bisdn.de>\n+Marek Pazdan <mpazdan@arista.com>\n Maria Lingemark <maria.lingemark@ericsson.com>\n Mario Carrillo <mario.alfredo.c.arevalo@intel.com>\n Mário Kuka <kuka@cesnet.cz>\ndiff --git a/app/test-pmd/cmdline.c b/app/test-pmd/cmdline.c\nindex b7759e38a8..7fdd134467 100644\n--- a/app/test-pmd/cmdline.c\n+++ b/app/test-pmd/cmdline.c\n@@ -65,6 +65,7 @@\n #include \"cmdline_cman.h\"\n #include \"cmdline_mtr.h\"\n #include \"cmdline_tm.h\"\n+#include \"cmdline_settings.h\"\n #include \"bpf_cmd.h\"\n \n static struct cmdline *testpmd_cl;\n@@ -255,6 +256,9 @@ static void cmd_help_long_parsed(void *parsed_result,\n \t\t\t\"show port (port_id) flow_ctrl\"\n \t\t\t\"\tShow flow control info of a port.\\n\\n\"\n \n+\t\t\t\"show port (port_id) link settings\"\n+\t\t\t\"\tShow link settings of a port.\\n\\n\"\n+\n \t\t\t\"dump_physmem\\n\"\n \t\t\t\"    Dumps all physical memory segment layouts\\n\\n\"\n \n@@ -661,6 +665,9 @@ static void cmd_help_long_parsed(void *parsed_result,\n \t\t\t\"(max_thresh) (prob_inv)]\\n\"\n \t\t\t\"    Set congestion management configuration\\n\\n\"\n \n+\t\t\t\"set port (port_id) link settings advertising (bitmap_str)\"\n+\t\t\t\"\tSet link advertising settings of a port.\\n\\n\"\n+\n \t\t\t, list_pkt_forwarding_modes()\n \t\t);\n \t}\n@@ -13219,6 +13226,8 @@ static cmdline_parse_ctx_t builtin_ctx[] = {\n \t(cmdline_parse_inst_t *)&cmd_link_flow_control_set_macfwd,\n \t(cmdline_parse_inst_t *)&cmd_link_flow_control_set_autoneg,\n \t(cmdline_parse_inst_t *)&cmd_link_flow_control_show,\n+\t(cmdline_parse_inst_t *)&cmd_link_settings_show,\n+\t(cmdline_parse_inst_t *)&cmd_link_settings_set_advertising,\n \t(cmdline_parse_inst_t *)&cmd_priority_flow_control_set,\n \t(cmdline_parse_inst_t *)&cmd_queue_priority_flow_control_set,\n \t(cmdline_parse_inst_t *)&cmd_config_dcb,\ndiff --git a/app/test-pmd/cmdline_settings.c b/app/test-pmd/cmdline_settings.c\nnew file mode 100644\nindex 0000000000..4db6bd4e9a\n--- /dev/null\n+++ b/app/test-pmd/cmdline_settings.c\n@@ -0,0 +1,516 @@\n+/* SPDX-License-Identifier: BSD-3-Clause\n+ * Copyright (c) 2024 Arista Networks, Inc.  All rights reserved.\n+ * Arista Networks, Inc. Confidential and Proprietary\n+ */\n+\n+#include <stdio.h>\n+#include <rte_ethdev.h>\n+\n+#include <cmdline_parse_string.h>\n+#include <cmdline_parse_num.h>\n+\n+#include \"testpmd.h\"\n+\n+/* *** GET CURRENT ETHERNET LINK SETTINGS *** */\n+struct cmd_link_settings_show {\n+\tcmdline_fixed_string_t show;\n+\tcmdline_fixed_string_t port;\n+\tportid_t port_id;\n+\tcmdline_fixed_string_t link;\n+\tcmdline_fixed_string_t settings;\n+};\n+\n+cmdline_parse_token_string_t cmd_ls_show_show =\n+\tTOKEN_STRING_INITIALIZER(struct cmd_link_settings_show,\n+\t\t\t\tshow, \"show\");\n+cmdline_parse_token_string_t cmd_ls_show_port =\n+\tTOKEN_STRING_INITIALIZER(struct cmd_link_settings_show,\n+\t\t\t\tport, \"port\");\n+cmdline_parse_token_num_t cmd_ls_show_portid =\n+\tTOKEN_NUM_INITIALIZER(struct cmd_link_settings_show,\n+\t\t\t\tport_id, RTE_UINT16);\n+cmdline_parse_token_string_t cmd_ls_show_link =\n+\tTOKEN_STRING_INITIALIZER(struct cmd_link_settings_show,\n+\t\t\t\tlink, \"link\");\n+cmdline_parse_token_string_t cmd_ls_show_settings =\n+\tTOKEN_STRING_INITIALIZER(struct cmd_link_settings_show,\n+\t\t\t\tsettings, \"settings\");\n+\n+/* Print link capability flags (supported, advertised or lp_advertised).\n+ * Assumes that the corresponding SUPPORTED and ADVERTISED flags are equal.\n+ */\n+static void dump_link_caps(const char *prefix, const char *an_prefix,\n+\t\tconst uint32_t *mask, int link_mode_only)\n+{\n+\tstatic const struct {\n+\t\tint same_line; /* print on same line as previous */\n+\t\tunsigned int bit_index;\n+\t\tconst char *name;\n+\t} mode_defs[] = {\n+\t\t{ 0, RTE_LINK_MODE_10baseT_Half_BIT,\n+\t\t  \"10baseT/Half\" },\n+\t\t{ 1, RTE_LINK_MODE_10baseT_Full_BIT,\n+\t\t  \"10baseT/Full\" },\n+\t\t{ 0, RTE_LINK_MODE_100baseT_Half_BIT,\n+\t\t  \"100baseT/Half\" },\n+\t\t{ 1, RTE_LINK_MODE_100baseT_Full_BIT,\n+\t\t  \"100baseT/Full\" },\n+\t\t{ 0, RTE_LINK_MODE_100baseT1_Full_BIT,\n+\t\t  \"100baseT1/Full\" },\n+\t\t{ 0, RTE_LINK_MODE_1000baseT_Half_BIT,\n+\t\t  \"1000baseT/Half\" },\n+\t\t{ 1, RTE_LINK_MODE_1000baseT_Full_BIT,\n+\t\t  \"1000baseT/Full\" },\n+\t\t{ 0, RTE_LINK_MODE_1000baseT1_Full_BIT,\n+\t\t  \"1000baseT1/Full\" },\n+\t\t{ 0, RTE_LINK_MODE_1000baseKX_Full_BIT,\n+\t\t  \"1000baseKX/Full\" },\n+\t\t{ 0, RTE_LINK_MODE_2500baseX_Full_BIT,\n+\t\t  \"2500baseX/Full\" },\n+\t\t{ 0, RTE_LINK_MODE_10000baseT_Full_BIT,\n+\t\t  \"10000baseT/Full\" },\n+\t\t{ 0, RTE_LINK_MODE_10000baseKX4_Full_BIT,\n+\t\t  \"10000baseKX4/Full\" },\n+\t\t{ 0, RTE_LINK_MODE_10000baseKR_Full_BIT,\n+\t\t  \"10000baseKR/Full\" },\n+\t\t{ 0, RTE_LINK_MODE_10000baseR_FEC_BIT,\n+\t\t  \"10000baseR_FEC\" },\n+\t\t{ 0, RTE_LINK_MODE_20000baseMLD2_Full_BIT,\n+\t\t  \"20000baseMLD2/Full\" },\n+\t\t{ 0, RTE_LINK_MODE_20000baseKR2_Full_BIT,\n+\t\t  \"20000baseKR2/Full\" },\n+\t\t{ 0, RTE_LINK_MODE_40000baseKR4_Full_BIT,\n+\t\t  \"40000baseKR4/Full\" },\n+\t\t{ 0, RTE_LINK_MODE_40000baseCR4_Full_BIT,\n+\t\t  \"40000baseCR4/Full\" },\n+\t\t{ 0, RTE_LINK_MODE_40000baseSR4_Full_BIT,\n+\t\t  \"40000baseSR4/Full\" },\n+\t\t{ 0, RTE_LINK_MODE_40000baseLR4_Full_BIT,\n+\t\t  \"40000baseLR4/Full\" },\n+\t\t{ 0, RTE_LINK_MODE_56000baseKR4_Full_BIT,\n+\t\t  \"56000baseKR4/Full\" },\n+\t\t{ 0, RTE_LINK_MODE_56000baseCR4_Full_BIT,\n+\t\t  \"56000baseCR4/Full\" },\n+\t\t{ 0, RTE_LINK_MODE_56000baseSR4_Full_BIT,\n+\t\t  \"56000baseSR4/Full\" },\n+\t\t{ 0, RTE_LINK_MODE_56000baseLR4_Full_BIT,\n+\t\t  \"56000baseLR4/Full\" },\n+\t\t{ 0, RTE_LINK_MODE_25000baseCR_Full_BIT,\n+\t\t  \"25000baseCR/Full\" },\n+\t\t{ 0, RTE_LINK_MODE_25000baseKR_Full_BIT,\n+\t\t  \"25000baseKR/Full\" },\n+\t\t{ 0, RTE_LINK_MODE_25000baseSR_Full_BIT,\n+\t\t  \"25000baseSR/Full\" },\n+\t\t{ 0, RTE_LINK_MODE_50000baseCR2_Full_BIT,\n+\t\t  \"50000baseCR2/Full\" },\n+\t\t{ 0, RTE_LINK_MODE_50000baseKR2_Full_BIT,\n+\t\t  \"50000baseKR2/Full\" },\n+\t\t{ 0, RTE_LINK_MODE_100000baseKR4_Full_BIT,\n+\t\t  \"100000baseKR4/Full\" },\n+\t\t{ 0, RTE_LINK_MODE_100000baseSR4_Full_BIT,\n+\t\t  \"100000baseSR4/Full\" },\n+\t\t{ 0, RTE_LINK_MODE_100000baseCR4_Full_BIT,\n+\t\t  \"100000baseCR4/Full\" },\n+\t\t{ 0, RTE_LINK_MODE_100000baseLR4_ER4_Full_BIT,\n+\t\t  \"100000baseLR4_ER4/Full\" },\n+\t\t{ 0, RTE_LINK_MODE_50000baseSR2_Full_BIT,\n+\t\t  \"50000baseSR2/Full\" },\n+\t\t{ 0, RTE_LINK_MODE_1000baseX_Full_BIT,\n+\t\t  \"1000baseX/Full\" },\n+\t\t{ 0, RTE_LINK_MODE_10000baseCR_Full_BIT,\n+\t\t  \"10000baseCR/Full\" },\n+\t\t{ 0, RTE_LINK_MODE_10000baseSR_Full_BIT,\n+\t\t  \"10000baseSR/Full\" },\n+\t\t{ 0, RTE_LINK_MODE_10000baseLR_Full_BIT,\n+\t\t  \"10000baseLR/Full\" },\n+\t\t{ 0, RTE_LINK_MODE_10000baseLRM_Full_BIT,\n+\t\t  \"10000baseLRM/Full\" },\n+\t\t{ 0, RTE_LINK_MODE_10000baseER_Full_BIT,\n+\t\t  \"10000baseER/Full\" },\n+\t\t{ 0, RTE_LINK_MODE_2500baseT_Full_BIT,\n+\t\t  \"2500baseT/Full\" },\n+\t\t{ 0, RTE_LINK_MODE_5000baseT_Full_BIT,\n+\t\t  \"5000baseT/Full\" },\n+\t\t{ 0, RTE_LINK_MODE_50000baseKR_Full_BIT,\n+\t\t  \"50000baseKR/Full\" },\n+\t\t{ 0, RTE_LINK_MODE_50000baseSR_Full_BIT,\n+\t\t  \"50000baseSR/Full\" },\n+\t\t{ 0, RTE_LINK_MODE_50000baseCR_Full_BIT,\n+\t\t  \"50000baseCR/Full\" },\n+\t\t{ 0, RTE_LINK_MODE_50000baseLR_ER_FR_Full_BIT,\n+\t\t  \"50000baseLR_ER_FR/Full\" },\n+\t\t{ 0, RTE_LINK_MODE_50000baseDR_Full_BIT,\n+\t\t  \"50000baseDR/Full\" },\n+\t\t{ 0, RTE_LINK_MODE_100000baseKR2_Full_BIT,\n+\t\t  \"100000baseKR2/Full\" },\n+\t\t{ 0, RTE_LINK_MODE_100000baseSR2_Full_BIT,\n+\t\t  \"100000baseSR2/Full\" },\n+\t\t{ 0, RTE_LINK_MODE_100000baseCR2_Full_BIT,\n+\t\t  \"100000baseCR2/Full\" },\n+\t\t{ 0, RTE_LINK_MODE_100000baseLR2_ER2_FR2_Full_BIT,\n+\t\t  \"100000baseLR2_ER2_FR2/Full\" },\n+\t\t{ 0, RTE_LINK_MODE_100000baseDR2_Full_BIT,\n+\t\t  \"100000baseDR2/Full\" },\n+\t\t{ 0, RTE_LINK_MODE_200000baseKR4_Full_BIT,\n+\t\t  \"200000baseKR4/Full\" },\n+\t\t{ 0, RTE_LINK_MODE_200000baseSR4_Full_BIT,\n+\t\t  \"200000baseSR4/Full\" },\n+\t\t{ 0, RTE_LINK_MODE_200000baseLR4_ER4_FR4_Full_BIT,\n+\t\t  \"200000baseLR4_ER4_FR4/Full\" },\n+\t\t{ 0, RTE_LINK_MODE_200000baseDR4_Full_BIT,\n+\t\t  \"200000baseDR4/Full\" },\n+\t\t{ 0, RTE_LINK_MODE_200000baseCR4_Full_BIT,\n+\t\t  \"200000baseCR4/Full\" },\n+\t};\n+\tint indent;\n+\tint did1;\n+\tint new_line_pend;\n+\tint fecreported = 0;\n+\n+\t/* Indent just like the separate functions used to */\n+\tindent = strlen(prefix) + 14;\n+\tif (indent < 24)\n+\t\tindent = 24;\n+\n+\tfprintf(stdout, \"       %s link modes:%*s\", prefix,\n+\t\tindent - (int)strlen(prefix) - 12, \"\");\n+\tdid1 = 0;\n+\tnew_line_pend = 0;\n+\tfor (uint32_t i = 0; i < RTE_DIM(mode_defs); i++) {\n+\t\tif (did1 && !mode_defs[i].same_line)\n+\t\t\tnew_line_pend = 1;\n+\t\tif (get_bit(mask, mode_defs[i].bit_index)) {\n+\t\t\tif (new_line_pend) {\n+\t\t\t\tfprintf(stdout, \"\\n\");\n+\t\t\t\tfprintf(stdout, \"       %*s\", indent, \"\");\n+\t\t\t\tnew_line_pend = 0;\n+\t\t\t}\n+\t\t\tdid1++;\n+\t\t\tfprintf(stdout, \"%s \", mode_defs[i].name);\n+\t\t}\n+\t}\n+\tif (did1 == 0)\n+\t\tfprintf(stdout, \"Not reported\");\n+\tfprintf(stdout, \"\\n\");\n+\n+\tif (!link_mode_only) {\n+\t\tfprintf(stdout, \"       %s pause frame use: \", prefix);\n+\t\tif (get_bit(mask, RTE_LINK_MODE_Pause_BIT)) {\n+\t\t\tfprintf(stdout, \"Symmetric\");\n+\t\t\tif (get_bit(mask, RTE_LINK_MODE_Asym_Pause_BIT))\n+\t\t\t\tfprintf(stdout, \" Receive-only\");\n+\t\t\tfprintf(stdout, \"\\n\");\n+\t\t} else {\n+\t\t\tif (get_bit(mask, RTE_LINK_MODE_Asym_Pause_BIT))\n+\t\t\t\tfprintf(stdout, \"Transmit-only\\n\");\n+\t\t\telse\n+\t\t\t\tfprintf(stdout, \"No\\n\");\n+\t\t}\n+\n+\t\tfprintf(stdout, \"       %s auto-negotiation: \", an_prefix);\n+\t\tif (get_bit(mask, RTE_LINK_MODE_Autoneg_BIT))\n+\t\t\tfprintf(stdout, \"Yes\\n\");\n+\t\telse\n+\t\t\tfprintf(stdout, \"No\\n\");\n+\n+\t\tfprintf(stdout, \"       %s FEC modes:\", prefix);\n+\t\tif (get_bit(mask, RTE_LINK_MODE_FEC_NONE_BIT)) {\n+\t\t\tfprintf(stdout, \" None\");\n+\t\t\tfecreported = 1;\n+\t\t}\n+\t\tif (get_bit(mask, RTE_LINK_MODE_FEC_BASER_BIT)) {\n+\t\t\tfprintf(stdout, \" BaseR\");\n+\t\t\tfecreported = 1;\n+\t\t}\n+\t\tif (get_bit(mask, RTE_LINK_MODE_FEC_RS_BIT)) {\n+\t\t\tfprintf(stdout, \" RS\");\n+\t\t\tfecreported = 1;\n+\t\t}\n+\t\tif (!fecreported)\n+\t\t\tfprintf(stdout, \" Not reported\");\n+\t\tfprintf(stdout, \"\\n\");\n+\t}\n+}\n+\n+static void\n+dump_supported(const struct rte_link_settings *link_settings)\n+{\n+\tfprintf(stdout, \"       Supported ports: [ \");\n+\tif (get_bit(link_settings->link_modes.supported,\n+\t\t    RTE_LINK_MODE_TP_BIT))\n+\t\tfprintf(stdout, \"TP \");\n+\tif (get_bit(link_settings->link_modes.supported,\n+\t\t    RTE_LINK_MODE_AUI_BIT))\n+\t\tfprintf(stdout, \"AUI \");\n+\tif (get_bit(link_settings->link_modes.supported,\n+\t\t    RTE_LINK_MODE_BNC_BIT))\n+\t\tfprintf(stdout, \"BNC \");\n+\tif (get_bit(link_settings->link_modes.supported,\n+\t\t    RTE_LINK_MODE_MII_BIT))\n+\t\tfprintf(stdout, \"MII \");\n+\tif (get_bit(link_settings->link_modes.supported,\n+\t\t    RTE_LINK_MODE_FIBRE_BIT))\n+\t\tfprintf(stdout, \"FIBRE \");\n+\tif (get_bit(link_settings->link_modes.supported,\n+\t\t    RTE_LINK_MODE_Backplane_BIT))\n+\t\tfprintf(stdout, \"Backplane \");\n+\tfprintf(stdout, \"]\\n\");\n+\n+\tdump_link_caps(\"Supported\", \"Supports\",\n+\t\t       link_settings->link_modes.supported, 0);\n+}\n+\n+\n+\n+static void\n+cmd_link_settings_show_parsed(void *parsed_result,\n+\t\t\t      __rte_unused struct cmdline *cl,\n+\t\t\t      __rte_unused void *data)\n+{\n+\tstruct cmd_link_settings_show *res = parsed_result;\n+\tstatic const char *info_border = \"*********************\";\n+\tstruct rte_link_settings link_settings;\n+\tint ret;\n+\n+\tmemset(&link_settings, 0x00, sizeof(link_settings));\n+\tret = rte_eth_dev_get_link_settings(res->port_id, &link_settings);\n+\tif (ret != 0) {\n+\t\tfprintf(stderr,\n+\t\t\t\"Failed to get current link settings: err = %d\\n\",\n+\t\t\tret);\n+\t\treturn;\n+\t}\n+\n+\tprintf(\"\\n%s Link settings for port %-2d %s\\n\",\n+\t\tinfo_border, res->port_id, info_border);\n+\n+\tdump_supported(&link_settings);\n+\tdump_link_caps(\"Advertised\", \"Advertised\",\n+\t\t\tlink_settings.link_modes.advertising, 0);\n+\n+\tbool show_lp_advertising = false;\n+\tfor (uint32_t idx = 0; idx < RTE_DIM(link_settings.link_modes.lp_advertising); idx++) {\n+\t\tif (link_settings.link_modes.lp_advertising[idx] != 0) {\n+\t\t\tshow_lp_advertising = true;\n+\t\t\tbreak;\n+\t\t}\n+\t}\n+\n+\tif (show_lp_advertising) {\n+\t\tdump_link_caps(\"Link partner advertised\",\n+\t\t\t\t\"Link partner advertised\",\n+\t\t\t\tlink_settings.link_modes.lp_advertising, 0);\n+\t}\n+\n+\tfprintf(stdout, \"       Speed: \");\n+\tif (link_settings.base.link.link_speed == 0\n+\t    || link_settings.base.link.link_speed == (uint16_t)(-1)\n+\t    || link_settings.base.link.link_speed == (uint32_t)(-1))\n+\t\tfprintf(stdout, \"Unknown!\\n\");\n+\telse\n+\t\tfprintf(stdout, \"%uMb/s\\n\", link_settings.base.link.link_speed);\n+\n+\tfprintf(stdout, \"       Duplex: \");\n+\tswitch (link_settings.base.link.link_duplex) {\n+\tcase RTE_ETH_LINK_HALF_DUPLEX:\n+\t\tfprintf(stdout, \"Half\\n\");\n+\t\tbreak;\n+\tcase RTE_ETH_LINK_FULL_DUPLEX:\n+\t\tfprintf(stdout, \"Full\\n\");\n+\t\tbreak;\n+\tdefault:\n+\t\tfprintf(stdout, \"Unknown! (%i)\\n\", link_settings.base.link.link_duplex);\n+\t\tbreak;\n+\t};\n+\n+\tfprintf(stdout, \"       Port: \");\n+\tswitch (link_settings.base.port) {\n+\tcase RTE_PORT_TP:\n+\t\tfprintf(stdout, \"Twisted Pair\\n\");\n+\t\tbreak;\n+\tcase RTE_PORT_AUI:\n+\t\tfprintf(stdout, \"AUI\\n\");\n+\t\tbreak;\n+\tcase RTE_PORT_BNC:\n+\t\tfprintf(stdout, \"BNC\\n\");\n+\t\tbreak;\n+\tcase RTE_PORT_MII:\n+\t\tfprintf(stdout, \"MII\\n\");\n+\t\tbreak;\n+\tcase RTE_PORT_FIBRE:\n+\t\tfprintf(stdout, \"FIBRE\\n\");\n+\t\tbreak;\n+\tcase RTE_PORT_DA:\n+\t\tfprintf(stdout, \"Direct Attach Copper\\n\");\n+\t\tbreak;\n+\tcase RTE_PORT_NONE:\n+\t\tfprintf(stdout, \"None\\n\");\n+\t\tbreak;\n+\tcase RTE_PORT_OTHER:\n+\t\tfprintf(stdout, \"Other\\n\");\n+\t\tbreak;\n+\tdefault:\n+\t\tfprintf(stdout, \"Unknown! (%i)\\n\", link_settings.base.port);\n+\t\tbreak;\n+\t};\n+\n+\tfprintf(stdout, \"       PHYAD: %d\\n\", link_settings.base.phy_address);\n+\n+\tfprintf(stdout, \"       Auto-negotiation: %s\\n\",\n+\t\t(link_settings.base.link.link_autoneg == RTE_AUTONEG_DISABLE) ?\n+\t\t\"off\" : \"on\");\n+\n+\tif (link_settings.base.port == RTE_PORT_TP) {\n+\t\tfprintf(stdout, \"       MDI-X: \");\n+\t\tif (link_settings.base.eth_tp_mdix_ctrl == RTE_TP_MDI) {\n+\t\t\tfprintf(stdout, \"off (forced)\\n\");\n+\t\t} else if (link_settings.base.eth_tp_mdix_ctrl\n+\t\t\t   == RTE_TP_MDI_X) {\n+\t\t\tfprintf(stdout, \"on (forced)\\n\");\n+\t\t} else {\n+\t\t\tswitch (link_settings.base.eth_tp_mdix) {\n+\t\t\tcase RTE_TP_MDI:\n+\t\t\t\tfprintf(stdout, \"off\");\n+\t\t\t\tbreak;\n+\t\t\tcase RTE_TP_MDI_X:\n+\t\t\t\tfprintf(stdout, \"on\");\n+\t\t\t\tbreak;\n+\t\t\tdefault:\n+\t\t\t\tfprintf(stdout, \"Unknown\");\n+\t\t\t\tbreak;\n+\t\t\t}\n+\t\t\tif (link_settings.base.eth_tp_mdix_ctrl\n+\t\t\t    == RTE_TP_MDI_AUTO)\n+\t\t\t\tfprintf(stdout, \" (auto)\");\n+\t\t\tfprintf(stdout, \"\\n\");\n+\t\t}\n+\t}\n+}\n+\n+cmdline_parse_inst_t cmd_link_settings_show = {\n+\t.f = cmd_link_settings_show_parsed,\n+\t.data = NULL,\n+\t.help_str = \"show port <port_id> link settings\",\n+\t.tokens = {\n+\t\t(void *)&cmd_ls_show_show,\n+\t\t(void *)&cmd_ls_show_port,\n+\t\t(void *)&cmd_ls_show_portid,\n+\t\t(void *)&cmd_ls_show_link,\n+\t\t(void *)&cmd_ls_show_settings,\n+\t\tNULL,\n+\t},\n+};\n+\n+static int parse_hex_u32_bitmap(const char *s,\n+\t\t\t\tunsigned int nbits, uint32_t *result)\n+{\n+\tconst unsigned int nwords = RTE_DIV_ROUND_UP(nbits, 32);\n+\tsize_t slen = strlen(s);\n+\tsize_t i;\n+\n+\t/* ignore optional '0x' prefix */\n+\tif ((slen > 2) && (strncasecmp(s, \"0x\", 2) == 0)) {\n+\t\tslen -= 2;\n+\t\ts += 2;\n+\t}\n+\n+\tif (slen > 8 * nwords)  /* up to 2 digits per byte */\n+\t\treturn -1;\n+\n+\tmemset(result, 0, 4 * nwords);\n+\tfor (i = 0; i < slen; ++i) {\n+\t\tconst unsigned int shift = (slen - 1 - i) * 4;\n+\t\tuint32_t *dest = &result[shift / 32];\n+\t\tuint32_t nibble;\n+\n+\t\tif ('a' <= s[i] && s[i] <= 'f')\n+\t\t\tnibble = 0xa + (s[i] - 'a');\n+\t\telse if ('A' <= s[i] && s[i] <= 'F')\n+\t\t\tnibble = 0xa + (s[i] - 'A');\n+\t\telse if ('0' <= s[i] && s[i] <= '9')\n+\t\t\tnibble = (s[i] - '0');\n+\t\telse\n+\t\t\treturn -1;\n+\n+\t\t*dest |= (nibble << (shift % 32));\n+\t}\n+\n+\treturn 0;\n+}\n+\n+/* *** SET ETHERNET LINK SETTINGS *** */\n+struct cmd_link_settings_set {\n+\tcmdline_fixed_string_t set;\n+\tcmdline_fixed_string_t port;\n+\tportid_t port_id;\n+\tcmdline_fixed_string_t link;\n+\tcmdline_fixed_string_t settings;\n+\tcmdline_fixed_string_t advertising;\n+\tcmdline_multi_string_t bitmap_str;\n+};\n+\n+cmdline_parse_token_string_t cmd_ls_set_set =\n+\tTOKEN_STRING_INITIALIZER(struct cmd_link_settings_set,\n+\t\t\t\tset, \"set\");\n+cmdline_parse_token_string_t cmd_ls_set_port =\n+\tTOKEN_STRING_INITIALIZER(struct cmd_link_settings_set,\n+\t\t\t\tport, \"port\");\n+cmdline_parse_token_num_t cmd_ls_set_portid =\n+\tTOKEN_NUM_INITIALIZER(struct cmd_link_settings_set,\n+\t\t\t\tport_id, RTE_UINT16);\n+cmdline_parse_token_string_t cmd_ls_set_link =\n+\tTOKEN_STRING_INITIALIZER(struct cmd_link_settings_set,\n+\t\t\t\tlink, \"link\");\n+cmdline_parse_token_string_t cmd_ls_set_settings =\n+\tTOKEN_STRING_INITIALIZER(struct cmd_link_settings_set,\n+\t\t\t\tsettings, \"settings\");\n+cmdline_parse_token_string_t cmd_ls_set_advertising =\n+\tTOKEN_STRING_INITIALIZER(struct cmd_link_settings_set,\n+\t\t\t\tadvertising, \"advertising\");\n+cmdline_parse_token_string_t cmd_ls_set_bitmap_str =\n+\tTOKEN_STRING_INITIALIZER(struct cmd_link_settings_set,\n+\t\t\t\tbitmap_str, TOKEN_STRING_MULTI);\n+\n+static void\n+cmd_link_settings_set_advertising_parsed(void *parsed_result,\n+\t\t\t      __rte_unused struct cmdline *cl,\n+\t\t\t      __rte_unused void *data)\n+{\n+\tstruct cmd_link_settings_set *res = parsed_result;\n+\tstruct rte_link_settings link_settings;\n+\tint ret;\n+\n+\tif (parse_hex_u32_bitmap(res->bitmap_str,\n+\t\t\t\t__RTE_LINK_MODE_MASK_NBITS,\n+\t\t\t\tlink_settings.link_modes.advertising)) {\n+\t\tfprintf(stderr, \"cannot parse bitmap_str\\n\");\n+\t\treturn;\n+\n+\t}\n+\n+\tlink_settings.base.link.link_autoneg = RTE_AUTONEG_ENABLE;\n+\n+\tret = rte_eth_dev_set_link_settings(res->port_id, &link_settings);\n+\tif (ret != 0) {\n+\t\tfprintf(stderr,\n+\t\t\t\"Failed to set link settings: err = %d\\n\",\n+\t\t\tret);\n+\t}\n+}\n+\n+cmdline_parse_inst_t cmd_link_settings_set_advertising = {\n+\t.f = cmd_link_settings_set_advertising_parsed,\n+\t.data = NULL,\n+\t.help_str = \"set port <port_id> link settings advertising <bitmap_str>\"\n+\t\t\" Bitmap_str - bitmap respresentation of advertising speeds\",\n+\t.tokens = {\n+\t\t(void *)&cmd_ls_set_set,\n+\t\t(void *)&cmd_ls_set_port,\n+\t\t(void *)&cmd_ls_set_portid,\n+\t\t(void *)&cmd_ls_set_link,\n+\t\t(void *)&cmd_ls_set_settings,\n+\t\t(void *)&cmd_ls_set_advertising,\n+\t\t(void *)&cmd_ls_set_bitmap_str,\n+\t\tNULL,\n+\t},\n+};\ndiff --git a/app/test-pmd/cmdline_settings.h b/app/test-pmd/cmdline_settings.h\nnew file mode 100644\nindex 0000000000..1bcd75f7ef\n--- /dev/null\n+++ b/app/test-pmd/cmdline_settings.h\n@@ -0,0 +1,14 @@\n+/* SPDX-License-Identifier: BSD-3-Clause\n+ * Copyright (c) 2024 Arista Networks, Inc.  All rights reserved.\n+ * Arista Networks, Inc. Confidential and Proprietary\n+ */\n+\n+#ifndef _CMDLINE_SETTINGS_H\n+#define _CMDLINE_SETTINGS_H\n+\n+/* Link settings CLI */\n+extern cmdline_parse_inst_t cmd_link_settings_show;\n+extern cmdline_parse_inst_t cmd_link_settings_set_advertising;\n+\n+#endif /* _CMDLINE_SETTINGS_H */\n+\ndiff --git a/app/test-pmd/meson.build b/app/test-pmd/meson.build\nindex 719f875be0..7aadc2ec42 100644\n--- a/app/test-pmd/meson.build\n+++ b/app/test-pmd/meson.build\n@@ -11,6 +11,7 @@ sources = files(\n         'cmdline_flow.c',\n         'cmdline_mtr.c',\n         'cmdline_tm.c',\n+        'cmdline_settings.c',\n         'cmd_flex_item.c',\n         'config.c',\n         'csumonly.c',\ndiff --git a/app/test-pmd/testpmd.h b/app/test-pmd/testpmd.h\nindex 0afae7d771..1873b45d23 100644\n--- a/app/test-pmd/testpmd.h\n+++ b/app/test-pmd/testpmd.h\n@@ -1187,6 +1187,7 @@ void eth_set_allmulticast_mode(uint16_t port, int enable);\n int eth_link_get_nowait_print_err(uint16_t port_id, struct rte_eth_link *link);\n int eth_macaddr_get_print_err(uint16_t port_id,\n \t\t\tstruct rte_ether_addr *mac_addr);\n+int get_bit(const uint32_t *ptr, uint32_t pos);\n \n /* Functions to display the set of MAC addresses added to a port*/\n void show_macs(portid_t port_id);\ndiff --git a/app/test-pmd/util.c b/app/test-pmd/util.c\nindex bf9b639d95..4d26776cc7 100644\n--- a/app/test-pmd/util.c\n+++ b/app/test-pmd/util.c\n@@ -17,6 +17,8 @@\n \n #define MAX_STRING_LEN 8192\n \n+#define UINT_32_BIT_WIDTH (CHAR_BIT * sizeof(uint32_t))\n+\n #define MKDUMPSTR(buf, buf_size, cur_len, ...) \\\n do { \\\n \tif (cur_len >= buf_size) \\\n@@ -525,3 +527,11 @@ eth_macaddr_get_print_err(uint16_t port_id, struct rte_ether_addr *mac_addr)\n \n \treturn ret;\n }\n+\n+int\n+get_bit(const uint32_t *ptr, uint32_t pos)\n+{\n+\tuint32_t byte_idx = pos / UINT_32_BIT_WIDTH;\n+\tuint32_t bit_idx = pos % UINT_32_BIT_WIDTH;\n+\treturn (ptr[byte_idx] >> bit_idx) & 0x1;\n+}\ndiff --git a/drivers/net/igc/igc_ethdev.c b/drivers/net/igc/igc_ethdev.c\nindex 87d7f7caa0..af11a6a3dd 100644\n--- a/drivers/net/igc/igc_ethdev.c\n+++ b/drivers/net/igc/igc_ethdev.c\n@@ -91,6 +91,8 @@\n uint64_t igc_tx_timestamp_dynflag;\n int igc_tx_timestamp_dynfield_offset = -1;\n \n+#define IGC_32_BIT_WIDTH (CHAR_BIT * sizeof(uint32_t))\n+\n static const struct rte_eth_desc_lim rx_desc_lim = {\n \t.nb_max = IGC_MAX_RXD,\n \t.nb_min = IGC_MIN_RXD,\n@@ -273,6 +275,10 @@ static int eth_igc_timesync_read_time(struct rte_eth_dev *dev,\n static int eth_igc_timesync_write_time(struct rte_eth_dev *dev,\n \t\t\t\t   const struct timespec *timestamp);\n static int eth_igc_read_clock(struct rte_eth_dev *dev, uint64_t *clock);\n+static int eth_igc_get_link_settings(struct rte_eth_dev *dev,\n+\t\t\t\tstruct rte_link_settings *link_settings);\n+static int eth_igc_set_link_settings(struct rte_eth_dev *dev,\n+\t\t\t\tconst struct rte_link_settings *link_settings);\n \n static const struct eth_dev_ops eth_igc_ops = {\n \t.dev_configure\t\t= eth_igc_configure,\n@@ -334,6 +340,8 @@ static const struct eth_dev_ops eth_igc_ops = {\n \t.timesync_read_time\t= eth_igc_timesync_read_time,\n \t.timesync_write_time\t= eth_igc_timesync_write_time,\n \t.read_clock             = eth_igc_read_clock,\n+\t.get_link_settings      = eth_igc_get_link_settings,\n+\t.set_link_settings      = eth_igc_set_link_settings,\n };\n \n /*\n@@ -532,8 +540,8 @@ eth_igc_link_update(struct rte_eth_dev *dev, int wait_to_complete)\n \t\t\t}\n \t\t}\n \t} else {\n-\t\tlink.link_speed = 0;\n-\t\tlink.link_duplex = RTE_ETH_LINK_HALF_DUPLEX;\n+\t\tlink.link_speed = RTE_ETH_SPEED_NUM_UNKNOWN;\n+\t\tlink.link_duplex = RTE_ETH_LINK_UNKNOWN_DUPLEX;\n \t\tlink.link_status = RTE_ETH_LINK_DOWN;\n \t\tlink.link_autoneg = RTE_ETH_LINK_FIXED;\n \t}\n@@ -2876,6 +2884,223 @@ eth_igc_read_clock(__rte_unused struct rte_eth_dev *dev, uint64_t *clock)\n \treturn 0;\n }\n \n+static inline void\n+igc_set_bit(uint32_t *ptr, uint32_t pos)\n+{\n+\tuint32_t byte_idx = pos / IGC_32_BIT_WIDTH;\n+\tuint32_t bit_idx = pos % IGC_32_BIT_WIDTH;\n+\tuint32_t tmp;\n+\n+\ttmp = ptr[byte_idx];\n+\ttmp &= ~(RTE_BIT32(bit_idx));\n+\ttmp |= RTE_BIT32(bit_idx);\n+\tptr[byte_idx] = tmp;\n+}\n+\n+static inline uint8_t\n+igc_get_bit(const uint32_t *ptr, uint32_t pos)\n+{\n+\tuint32_t byte_idx = pos / IGC_32_BIT_WIDTH;\n+\tuint32_t bit_idx = pos % IGC_32_BIT_WIDTH;\n+\n+\treturn (ptr[byte_idx] >> bit_idx) & 0x1;\n+}\n+\n+static int eth_igc_get_link_settings(struct rte_eth_dev *dev,\n+\t\t\t\t     struct rte_link_settings *link_settings)\n+{\n+\ts32 ret_val = IGC_SUCCESS;\n+\ts32 link_check = 0;\n+\tstruct igc_hw *hw = IGC_DEV_PRIVATE_HW(dev);\n+\tuint32_t *supported = link_settings->link_modes.supported;\n+\tuint32_t *advertising = link_settings->link_modes.advertising;\n+\tuint32_t *lp_advertising = link_settings->link_modes.lp_advertising;\n+\n+\tmemset(supported, 0x00, __RTE_LINK_MODE_MASK_NU32 * sizeof(uint32_t));\n+\tmemset(advertising, 0x00, __RTE_LINK_MODE_MASK_NU32 * sizeof(uint32_t));\n+\tmemset(lp_advertising, 0x00, __RTE_LINK_MODE_MASK_NU32 * sizeof(uint32_t));\n+\n+\tigc_set_bit(supported, RTE_LINK_MODE_10baseT_Half_BIT);\n+\tigc_set_bit(supported, RTE_LINK_MODE_10baseT_Full_BIT);\n+\tigc_set_bit(supported, RTE_LINK_MODE_100baseT_Half_BIT);\n+\tigc_set_bit(supported, RTE_LINK_MODE_100baseT_Full_BIT);\n+\tigc_set_bit(supported, RTE_LINK_MODE_1000baseT_Full_BIT);\n+\tigc_set_bit(supported, RTE_LINK_MODE_2500baseT_Full_BIT);\n+\n+\t/* twisted pair */\n+\tlink_settings->base.port = RTE_PORT_TP;\n+\t/* MDIO address of PHY (transceiver) */\n+\tlink_settings->base.phy_address = hw->phy.addr;\n+\tigc_set_bit(supported, RTE_LINK_MODE_TP_BIT);\n+\tigc_set_bit(advertising, RTE_LINK_MODE_TP_BIT);\n+\n+\tif (hw->phy.autoneg_advertised & ADVERTISE_10_HALF)\n+\t\tigc_set_bit(advertising, RTE_LINK_MODE_10baseT_Half_BIT);\n+\tif (hw->phy.autoneg_advertised & ADVERTISE_10_FULL)\n+\t\tigc_set_bit(advertising, RTE_LINK_MODE_10baseT_Full_BIT);\n+\tif (hw->phy.autoneg_advertised & ADVERTISE_100_HALF)\n+\t\tigc_set_bit(advertising, RTE_LINK_MODE_100baseT_Half_BIT);\n+\tif (hw->phy.autoneg_advertised & ADVERTISE_100_FULL)\n+\t\tigc_set_bit(advertising, RTE_LINK_MODE_100baseT_Full_BIT);\n+\tif (hw->phy.autoneg_advertised & ADVERTISE_1000_FULL)\n+\t\tigc_set_bit(advertising, RTE_LINK_MODE_1000baseT_Full_BIT);\n+\tif (hw->phy.autoneg_advertised & ADVERTISE_2500_FULL)\n+\t\tigc_set_bit(advertising, RTE_LINK_MODE_2500baseT_Full_BIT);\n+\n+\t/* set autoneg settings */\n+\tif (hw->mac.autoneg == 1) {\n+\t\tigc_set_bit(supported, RTE_LINK_MODE_Autoneg_BIT);\n+\t\tigc_set_bit(advertising, RTE_LINK_MODE_Autoneg_BIT);\n+\t\tlink_settings->base.link.link_autoneg = RTE_AUTONEG_ENABLE;\n+\t} else {\n+\t\tlink_settings->base.link.link_autoneg = RTE_AUTONEG_DISABLE;\n+\t}\n+\n+\t/* Set pause flow control settings */\n+\tigc_set_bit(supported, RTE_LINK_MODE_Pause_BIT);\n+\n+\tswitch (hw->fc.requested_mode) {\n+\tcase igc_fc_full:\n+\t\tigc_set_bit(advertising, RTE_LINK_MODE_Pause_BIT);\n+\t\tbreak;\n+\tcase igc_fc_rx_pause:\n+\t\tigc_set_bit(advertising, RTE_LINK_MODE_Pause_BIT);\n+\t\tigc_set_bit(advertising, RTE_LINK_MODE_Asym_Pause_BIT);\n+\t\tbreak;\n+\tcase igc_fc_tx_pause:\n+\t\tigc_set_bit(advertising, RTE_LINK_MODE_Asym_Pause_BIT);\n+\t\tbreak;\n+\tdefault:\n+\t\tbreak;\n+\t}\n+\n+\thw->mac.get_link_status = 1;\n+\t/* Read the real link status */\n+\tswitch (hw->phy.media_type) {\n+\tcase igc_media_type_copper:\n+\t\t/* Do the work to read phy */\n+\t\tigc_check_for_link(hw);\n+\t\tlink_check = !hw->mac.get_link_status;\n+\t\tbreak;\n+\tcase igc_media_type_fiber:\n+\t\tigc_check_for_link(hw);\n+\t\tlink_check = (IGC_READ_REG(hw, IGC_STATUS) &\n+\t\t\t      IGC_STATUS_LU);\n+\t\tbreak;\n+\tcase igc_media_type_internal_serdes:\n+\t\tigc_check_for_link(hw);\n+\t\tlink_check = hw->mac.serdes_has_link;\n+\t\tbreak;\n+\tdefault:\n+\t\tbreak;\n+\t}\n+\n+\t/* Now we check if a transition has happened */\n+\tif (link_check) {\n+\t\tuint16_t duplex, speed;\n+\t\thw->mac.ops.get_link_up_info(hw, &speed, &duplex);\n+\t\tlink_settings->base.link.link_duplex = (duplex == FULL_DUPLEX) ?\n+\t\t\t\tRTE_ETH_LINK_FULL_DUPLEX :\n+\t\t\t\tRTE_ETH_LINK_HALF_DUPLEX;\n+\t\tlink_settings->base.link.link_speed = speed;\n+\t\tlink_settings->base.link.link_status = RTE_ETH_LINK_UP;\n+\t\tlink_settings->base.link.link_autoneg = !(dev->data->dev_conf.link_speeds &\n+\t\t\t\tRTE_ETH_LINK_SPEED_FIXED);\n+\t\tif (speed == SPEED_2500) {\n+\t\t\tuint32_t tipg = IGC_READ_REG(hw, IGC_TIPG);\n+\t\t\tif ((tipg & IGC_TIPG_IPGT_MASK) != 0x0b) {\n+\t\t\t\ttipg &= ~IGC_TIPG_IPGT_MASK;\n+\t\t\t\ttipg |= 0x0b;\n+\t\t\t\tIGC_WRITE_REG(hw, IGC_TIPG, tipg);\n+\t\t\t}\n+\t\t}\n+\t} else {\n+\t\tlink_settings->base.link.link_speed = 0;\n+\t\tlink_settings->base.link.link_duplex = RTE_ETH_LINK_HALF_DUPLEX;\n+\t\tlink_settings->base.link.link_status = RTE_ETH_LINK_DOWN;\n+\t\tlink_settings->base.link.link_autoneg = RTE_ETH_LINK_FIXED;\n+\t}\n+\n+\t/* MDI-X => 2; MDI =>1; Invalid =>0 */\n+\tif (hw->phy.media_type == igc_media_type_copper)\n+\t\tlink_settings->base.eth_tp_mdix = hw->phy.is_mdix ? RTE_TP_MDI_X :\n+\t\t\t\t\t\t      RTE_TP_MDI;\n+\telse\n+\t\tlink_settings->base.eth_tp_mdix = RTE_TP_MDI_INVALID;\n+\n+\tif (hw->phy.mdix == 0) /* AUTO_ALL_MODES */\n+\t\tlink_settings->base.eth_tp_mdix_ctrl = RTE_TP_MDI_AUTO;\n+\telse\n+\t\tlink_settings->base.eth_tp_mdix_ctrl = hw->phy.mdix;\n+\n+\treturn ret_val;\n+}\n+\n+static int eth_igc_set_link_settings(struct rte_eth_dev *dev,\n+\t\t\t const struct rte_link_settings *link_settings)\n+{\n+\tstruct igc_hw *hw = IGC_DEV_PRIVATE_HW(dev);\n+\tstruct igc_adapter *adapter = IGC_DEV_PRIVATE(dev);\n+\tconst uint32_t *advertising = link_settings->link_modes.advertising;\n+\tint ret = IGC_SUCCESS;\n+\n+\tif (igc_check_reset_block(hw)) {\n+\t\tPMD_DRV_LOG(ERR, \"Cannot change link characteristics when reset is active\\n\");\n+\t\treturn -EINVAL;\n+\t}\n+\n+\t/* MDI setting is only allowed when autoneg enabled because\n+\t * some hardware doesn't allow MDI setting when speed or\n+\t * duplex is forced.\n+\t */\n+\tif (link_settings->base.eth_tp_mdix_ctrl) {\n+\t\tif (link_settings->base.eth_tp_mdix_ctrl != RTE_TP_MDI_AUTO &&\n+\t\t    link_settings->base.link.link_autoneg != RTE_AUTONEG_ENABLE) {\n+\t\t\tPMD_DRV_LOG(ERR, \"Forcing MDI/MDI-X state is not supported \"\n+\t\t\t\t\t \"when link speed and/or duplex are forced\\n\");\n+\t\t\treturn -EINVAL;\n+\t\t}\n+\t}\n+\n+\t/* All modes for igc but one fits into first byte of bitmask */\n+\tuint32_t igc_advertising = link_settings->link_modes.advertising[0];\n+\t/* Converting to u32 drops RTE_LINK_MODE_2500baseT_Full_BIT.\n+\t * We have to check this and convert it to ADVERTISE_2500_FULL\n+\t * (aka RTE_LINK_MODE_2500baseX_Full_BIT) explicitly.\n+\t */\n+\tif (igc_get_bit(advertising, RTE_LINK_MODE_2500baseT_Full_BIT))\n+\t\tigc_advertising |= ADVERTISE_2500_FULL;\n+\n+\tif (link_settings->base.link.link_autoneg == RTE_AUTONEG_ENABLE) {\n+\t\thw->mac.autoneg = 1;\n+\t\thw->phy.autoneg_advertised = igc_advertising;\n+\t\thw->fc.requested_mode = igc_fc_default;\n+\t} else {\n+\t\tPMD_DRV_LOG(INFO, \"Force mode currently not supported\\n\");\n+\t}\n+\n+\t/* MDI-X => 2; MDI => 1; Auto => 3 */\n+\tif (link_settings->base.eth_tp_mdix_ctrl) {\n+\t\t/* fix up the value for auto (3 => 0) as zero is mapped\n+\t\t * internally to auto\n+\t\t */\n+\t\tif (link_settings->base.eth_tp_mdix_ctrl == RTE_TP_MDI_AUTO)\n+\t\t\thw->phy.mdix = 0; /* AUTO_ALL_MODES */\n+\t\telse\n+\t\t\thw->phy.mdix = link_settings->base.eth_tp_mdix_ctrl;\n+\t}\n+\n+\t/* reset the link */\n+\tif (!adapter->stopped) {\n+\t\teth_igc_set_link_down(dev);\n+\t\teth_igc_set_link_up(dev);\n+\t} else {\n+\t\teth_igc_reset(dev);\n+\t}\n+\n+\treturn ret;\n+}\n+\n static int\n eth_igc_pci_probe(struct rte_pci_driver *pci_drv __rte_unused,\n \tstruct rte_pci_device *pci_dev)\ndiff --git a/drivers/net/ixgbe/base/ixgbe_phy.h b/drivers/net/ixgbe/base/ixgbe_phy.h\nindex ceefbb3e68..f4d22951be 100644\n--- a/drivers/net/ixgbe/base/ixgbe_phy.h\n+++ b/drivers/net/ixgbe/base/ixgbe_phy.h\n@@ -125,6 +125,13 @@\n /* SFP+ SFF-8472 Compliance */\n #define IXGBE_SFF_SFF_8472_UNSUP\t0x00\n \n+#define IXGBE_SPEED_10000\t10000\n+\n+/* Duplex, half or full. */\n+#define IXGBE_DUPLEX_HALF\t0x00\n+#define IXGBE_DUPLEX_FULL\t0x01\n+#define IXGBE_DUPLEX_UNKNOWN\t0xff\n+\n s32 ixgbe_init_phy_ops_generic(struct ixgbe_hw *hw);\n bool ixgbe_validate_phy_addr(struct ixgbe_hw *hw, u32 phy_addr);\n enum ixgbe_phy_type ixgbe_get_phy_type_from_id(u32 phy_id);\ndiff --git a/drivers/net/ixgbe/ixgbe_ethdev.c b/drivers/net/ixgbe/ixgbe_ethdev.c\nindex c61c52b296..2fd4a34b55 100644\n--- a/drivers/net/ixgbe/ixgbe_ethdev.c\n+++ b/drivers/net/ixgbe/ixgbe_ethdev.c\n@@ -94,6 +94,7 @@\n #define IXGBE_4_BIT_MASK   RTE_LEN2MASK(IXGBE_4_BIT_WIDTH, uint8_t)\n #define IXGBE_8_BIT_WIDTH  CHAR_BIT\n #define IXGBE_8_BIT_MASK   UINT8_MAX\n+#define IXGBE_32_BIT_WIDTH (CHAR_BIT * sizeof(uint32_t))\n \n #define IXGBEVF_PMD_NAME \"rte_ixgbevf_pmd\" /* PMD name */\n \n@@ -130,6 +131,8 @@\n \n #define IXGBE_DEVARG_FIBER_SDP3_NOT_TX_DISABLE\t\"fiber_sdp3_no_tx_disable\"\n \n+#define IXGBE_ISBACKPLANE(type)             ((type) == ixgbe_media_type_backplane)\n+\n static const char * const ixgbe_valid_arguments[] = {\n \tIXGBE_DEVARG_FIBER_SDP3_NOT_TX_DISABLE,\n \tNULL\n@@ -353,6 +356,10 @@ static int ixgbe_dev_udp_tunnel_port_add(struct rte_eth_dev *dev,\n \t\t\t\t\t struct rte_eth_udp_tunnel *udp_tunnel);\n static int ixgbe_dev_udp_tunnel_port_del(struct rte_eth_dev *dev,\n \t\t\t\t\t struct rte_eth_udp_tunnel *udp_tunnel);\n+static int ixgbe_get_link_settings(struct rte_eth_dev *dev,\n+\t\t\t\t   struct rte_link_settings *link_settings);\n+static int ixgbe_set_link_settings(struct rte_eth_dev *dev,\n+\t\t\t\t   const struct rte_link_settings *link_settings);\n static int ixgbe_filter_restore(struct rte_eth_dev *dev);\n static void ixgbe_l2_tunnel_conf(struct rte_eth_dev *dev);\n static int ixgbe_wait_for_link_up(struct ixgbe_hw *hw);\n@@ -564,6 +571,8 @@ static const struct eth_dev_ops ixgbe_eth_dev_ops = {\n \t.tm_ops_get           = ixgbe_tm_ops_get,\n \t.tx_done_cleanup      = ixgbe_dev_tx_done_cleanup,\n \t.get_monitor_addr     = ixgbe_get_monitor_addr,\n+\t.get_link_settings    = ixgbe_get_link_settings,\n+\t.set_link_settings    = ixgbe_set_link_settings,\n };\n \n /*\n@@ -7791,6 +7800,392 @@ ixgbe_dev_udp_tunnel_port_del(struct rte_eth_dev *dev,\n \treturn ret;\n }\n \n+static inline void\n+ixgbe_set_bit(uint32_t *ptr, uint32_t pos)\n+{\n+\tuint32_t byte_idx = pos / IXGBE_32_BIT_WIDTH;\n+\tuint32_t bit_idx = pos % IXGBE_32_BIT_WIDTH;\n+\tuint32_t tmp;\n+\n+\ttmp = ptr[byte_idx];\n+\ttmp &= ~(1 << bit_idx);\n+\ttmp |= 1 << bit_idx;\n+\tptr[byte_idx] = tmp;\n+}\n+\n+static inline uint8_t\n+ixgbe_get_bit(const uint32_t *ptr, uint32_t pos)\n+{\n+\tuint32_t byte_idx = pos / IXGBE_32_BIT_WIDTH;\n+\tuint32_t bit_idx = pos % IXGBE_32_BIT_WIDTH;\n+\n+\treturn (ptr[byte_idx] >> bit_idx) & 0x1;\n+}\n+\n+\n+static inline bool\n+ixgbe_is_subset(const uint32_t *bitmap1, const uint32_t *bitmap2,\n+\t\tuint32_t nbits)\n+{\n+\tuint32_t full_bytes_cnt = nbits / IXGBE_32_BIT_WIDTH;\n+\tuint32_t last_byte_bit_idx = nbits % IXGBE_32_BIT_WIDTH;\n+\n+\tfor (uint32_t idx = 0; idx < full_bytes_cnt; idx++) {\n+\t\tif (bitmap1[idx] & ~bitmap2[idx])\n+\t\t\treturn false;\n+\t}\n+\n+\tuint32_t last_chunk_mask = ((1ULL << last_byte_bit_idx) - 1) |\n+\t\t\t\t    (1ULL << last_byte_bit_idx);\n+\tif ((bitmap1[full_bytes_cnt] & ~bitmap2[full_bytes_cnt]) & last_chunk_mask)\n+\t\treturn false;\n+\n+\treturn true;\n+}\n+\n+static void ixgbe_set_supported_10gtypes(struct ixgbe_hw *hw,\n+\t\t\t\t\t uint32_t *bitmap)\n+{\n+\tif (!IXGBE_ISBACKPLANE(hw->phy.media_type)) {\n+\t\tixgbe_set_bit(bitmap, RTE_LINK_MODE_10000baseT_Full_BIT);\n+\t\treturn;\n+\t}\n+\n+\tswitch (hw->device_id) {\n+\tcase IXGBE_DEV_ID_82598:\n+\tcase IXGBE_DEV_ID_82599_KX4:\n+\tcase IXGBE_DEV_ID_82599_KX4_MEZZ:\n+\tcase IXGBE_DEV_ID_X550EM_X_KX4:\n+\t\tixgbe_set_bit(bitmap, RTE_LINK_MODE_10000baseKX4_Full_BIT);\n+\t\tbreak;\n+\tcase IXGBE_DEV_ID_82598_BX:\n+\tcase IXGBE_DEV_ID_82599_KR:\n+\tcase IXGBE_DEV_ID_X550EM_X_KR:\n+\tcase IXGBE_DEV_ID_X550EM_X_XFI:\n+\t\tixgbe_set_bit(bitmap, RTE_LINK_MODE_10000baseKR_Full_BIT);\n+\t\tbreak;\n+\tdefault:\n+\t\tixgbe_set_bit(bitmap, RTE_LINK_MODE_10000baseKX4_Full_BIT);\n+\t\tixgbe_set_bit(bitmap, RTE_LINK_MODE_10000baseKR_Full_BIT);\n+\t\tbreak;\n+\t}\n+}\n+\n+static int ixgbe_get_link_settings(struct rte_eth_dev *dev,\n+\t\t\t\t   struct rte_link_settings *link_settings)\n+{\n+\tint ret_val = IXGBE_SUCCESS;\n+\tint wait = 1;\n+\tbool link_up;\n+\tbool autoneg;\n+\tuint32_t esdp_reg;\n+\tixgbe_link_speed link_speed = IXGBE_LINK_SPEED_UNKNOWN;\n+\tstruct ixgbe_hw *hw = IXGBE_DEV_PRIVATE_TO_HW(dev->data->dev_private);\n+\tstruct ixgbe_adapter *ad = dev->data->dev_private;\n+\tuint32_t *supported = link_settings->link_modes.supported;\n+\tuint32_t *advertising = link_settings->link_modes.advertising;\n+\tuint32_t *lp_advertising = link_settings->link_modes.lp_advertising;\n+\n+\tmemset(supported, 0x00, __RTE_LINK_MODE_MASK_NU32 * sizeof(uint32_t));\n+\tmemset(advertising, 0x00, __RTE_LINK_MODE_MASK_NU32 * sizeof(uint32_t));\n+\tmemset(lp_advertising, 0x00, __RTE_LINK_MODE_MASK_NU32 * sizeof(uint32_t));\n+\n+\t/* Get supported speeds */\n+\tret_val = ixgbe_get_link_capabilities(hw, &link_speed, &autoneg);\n+\tif (ret_val != IXGBE_SUCCESS)\n+\t\treturn ret_val;\n+\n+\tif (link_speed & IXGBE_LINK_SPEED_10GB_FULL) {\n+\t\tixgbe_set_supported_10gtypes(hw, supported);\n+\t\tixgbe_set_supported_10gtypes(hw, advertising);\n+\t}\n+\n+\tif (link_speed & IXGBE_LINK_SPEED_5GB_FULL)\n+\t\tixgbe_set_bit(supported, RTE_LINK_MODE_5000baseT_Full_BIT);\n+\n+\tif (link_speed & IXGBE_LINK_SPEED_2_5GB_FULL)\n+\t\tixgbe_set_bit(supported, RTE_LINK_MODE_2500baseT_Full_BIT);\n+\n+\tif (link_speed & IXGBE_LINK_SPEED_1GB_FULL) {\n+\t\tif (IXGBE_ISBACKPLANE(hw->phy.media_type)) {\n+\t\t\tixgbe_set_bit(supported, RTE_LINK_MODE_1000baseKX_Full_BIT);\n+\t\t\tixgbe_set_bit(advertising, RTE_LINK_MODE_1000baseKX_Full_BIT);\n+\t\t} else {\n+\t\t\tixgbe_set_bit(supported, RTE_LINK_MODE_1000baseT_Full_BIT);\n+\t\t\tixgbe_set_bit(advertising, RTE_LINK_MODE_1000baseT_Full_BIT);\n+\t\t}\n+\t}\n+\tif (link_speed & IXGBE_LINK_SPEED_100_FULL) {\n+\t\tixgbe_set_bit(supported, RTE_LINK_MODE_100baseT_Full_BIT);\n+\t\tixgbe_set_bit(advertising, RTE_LINK_MODE_100baseT_Full_BIT);\n+\t}\n+\tif (link_speed & IXGBE_LINK_SPEED_10_FULL) {\n+\t\tixgbe_set_bit(supported, RTE_LINK_MODE_10baseT_Full_BIT);\n+\t\tixgbe_set_bit(advertising, RTE_LINK_MODE_10baseT_Full_BIT);\n+\t}\n+\n+\t/* set the advertised speeds */\n+\tif (hw->phy.autoneg_advertised) {\n+\t\tif (hw->phy.autoneg_advertised & IXGBE_LINK_SPEED_10_FULL)\n+\t\t\tixgbe_set_bit(advertising, RTE_LINK_MODE_10baseT_Full_BIT);\n+\t\tif (hw->phy.autoneg_advertised & IXGBE_LINK_SPEED_100_FULL)\n+\t\t\tixgbe_set_bit(advertising, RTE_LINK_MODE_100baseT_Full_BIT);\n+\t\tif (hw->phy.autoneg_advertised & IXGBE_LINK_SPEED_10GB_FULL)\n+\t\t\tixgbe_set_supported_10gtypes(hw, advertising);\n+\t\tif (hw->phy.autoneg_advertised & IXGBE_LINK_SPEED_1GB_FULL) {\n+\t\t\tif (ixgbe_get_bit(supported, RTE_LINK_MODE_1000baseKX_Full_BIT))\n+\t\t\t\tixgbe_set_bit(advertising,\n+\t\t\t\t\t      RTE_LINK_MODE_1000baseKX_Full_BIT);\n+\t\t\telse\n+\t\t\t\tixgbe_set_bit(advertising,\n+\t\t\t\t\t      RTE_LINK_MODE_1000baseT_Full_BIT);\n+\t\t}\n+\t\tif (hw->phy.autoneg_advertised & IXGBE_LINK_SPEED_5GB_FULL)\n+\t\t\tixgbe_set_bit(advertising, RTE_LINK_MODE_5000baseT_Full_BIT);\n+\t\tif (hw->phy.autoneg_advertised & IXGBE_LINK_SPEED_2_5GB_FULL)\n+\t\t\tixgbe_set_bit(advertising, RTE_LINK_MODE_2500baseT_Full_BIT);\n+\t} else {\n+\t\tif (hw->phy.multispeed_fiber && !autoneg) {\n+\t\t\tif (link_speed & IXGBE_LINK_SPEED_10GB_FULL)\n+\t\t\t\tixgbe_set_bit(advertising,\n+\t\t\t\t\t      RTE_LINK_MODE_10000baseT_Full_BIT);\n+\t\t}\n+\t}\n+\n+\tif (autoneg) {\n+\t\tixgbe_set_bit(supported, RTE_LINK_MODE_Autoneg_BIT);\n+\t\tixgbe_set_bit(advertising, RTE_LINK_MODE_Autoneg_BIT);\n+\t\tlink_settings->base.link.link_autoneg = RTE_AUTONEG_ENABLE;\n+\t} else {\n+\t\tlink_settings->base.link.link_autoneg = RTE_AUTONEG_DISABLE;\n+\t}\n+\n+\tswitch (hw->phy.type) {\n+\tcase ixgbe_phy_tn:\n+\tcase ixgbe_phy_aq:\n+\tcase ixgbe_phy_x550em_ext_t:\n+\tcase ixgbe_phy_fw:\n+\tcase ixgbe_phy_cu_unknown:\n+\t\tixgbe_set_bit(supported, RTE_LINK_MODE_TP_BIT);\n+\t\tixgbe_set_bit(advertising, RTE_LINK_MODE_TP_BIT);\n+\t\tlink_settings->base.port = RTE_PORT_TP;\n+\t\tbreak;\n+\tcase ixgbe_phy_qt:\n+\t\tixgbe_set_bit(supported, RTE_LINK_MODE_FIBRE_BIT);\n+\t\tixgbe_set_bit(advertising, RTE_LINK_MODE_FIBRE_BIT);\n+\t\tlink_settings->base.port = RTE_PORT_FIBRE;\n+\t\tbreak;\n+\tcase ixgbe_phy_nl:\n+\tcase ixgbe_phy_sfp_passive_tyco:\n+\tcase ixgbe_phy_sfp_passive_unknown:\n+\tcase ixgbe_phy_sfp_ftl:\n+\tcase ixgbe_phy_sfp_avago:\n+\tcase ixgbe_phy_sfp_intel:\n+\tcase ixgbe_phy_sfp_unknown:\n+\tcase ixgbe_phy_qsfp_passive_unknown:\n+\tcase ixgbe_phy_qsfp_active_unknown:\n+\tcase ixgbe_phy_qsfp_intel:\n+\tcase ixgbe_phy_qsfp_unknown:\n+\t\t/* SFP+ devices, further checking needed */\n+\t\tswitch (hw->phy.sfp_type) {\n+\t\tcase ixgbe_sfp_type_da_cu:\n+\t\tcase ixgbe_sfp_type_da_cu_core0:\n+\t\tcase ixgbe_sfp_type_da_cu_core1:\n+\t\t\tixgbe_set_bit(supported, RTE_LINK_MODE_FIBRE_BIT);\n+\t\t\tixgbe_set_bit(advertising, RTE_LINK_MODE_FIBRE_BIT);\n+\t\t\tlink_settings->base.port = RTE_PORT_DA;\n+\t\t\tbreak;\n+\t\tcase ixgbe_sfp_type_sr:\n+\t\tcase ixgbe_sfp_type_lr:\n+\t\tcase ixgbe_sfp_type_srlr_core0:\n+\t\tcase ixgbe_sfp_type_srlr_core1:\n+\t\tcase ixgbe_sfp_type_1g_sx_core0:\n+\t\tcase ixgbe_sfp_type_1g_sx_core1:\n+\t\tcase ixgbe_sfp_type_1g_lx_core0:\n+\t\tcase ixgbe_sfp_type_1g_lx_core1:\n+\t\t\tixgbe_set_bit(supported, RTE_LINK_MODE_FIBRE_BIT);\n+\t\t\tixgbe_set_bit(advertising, RTE_LINK_MODE_FIBRE_BIT);\n+\t\t\tlink_settings->base.port = RTE_PORT_FIBRE;\n+\t\t\tbreak;\n+\t\tcase ixgbe_sfp_type_not_present:\n+\t\t\tixgbe_set_bit(supported, RTE_LINK_MODE_FIBRE_BIT);\n+\t\t\tixgbe_set_bit(advertising, RTE_LINK_MODE_FIBRE_BIT);\n+\t\t\tlink_settings->base.port = RTE_PORT_NONE;\n+\t\t\tbreak;\n+\t\tcase ixgbe_sfp_type_1g_cu_core0:\n+\t\tcase ixgbe_sfp_type_1g_cu_core1:\n+\t\t\tixgbe_set_bit(supported, RTE_LINK_MODE_TP_BIT);\n+\t\t\tixgbe_set_bit(advertising, RTE_LINK_MODE_TP_BIT);\n+\t\t\tlink_settings->base.port = RTE_PORT_TP;\n+\t\t\tbreak;\n+\t\tcase ixgbe_sfp_type_unknown:\n+\t\tdefault:\n+\t\t\tixgbe_set_bit(supported, RTE_LINK_MODE_FIBRE_BIT);\n+\t\t\tixgbe_set_bit(advertising, RTE_LINK_MODE_FIBRE_BIT);\n+\t\t\tlink_settings->base.port = RTE_PORT_OTHER;\n+\t\t\tbreak;\n+\t\t}\n+\t\tbreak;\n+\tcase ixgbe_phy_xaui:\n+\t\tixgbe_set_bit(supported, RTE_LINK_MODE_FIBRE_BIT);\n+\t\tixgbe_set_bit(advertising, RTE_LINK_MODE_FIBRE_BIT);\n+\t\tlink_settings->base.port = RTE_PORT_NONE;\n+\t\tbreak;\n+\tcase ixgbe_phy_unknown:\n+\tcase ixgbe_phy_generic:\n+\tcase ixgbe_phy_sfp_unsupported:\n+\tdefault:\n+\t\tixgbe_set_bit(supported, RTE_LINK_MODE_FIBRE_BIT);\n+\t\tixgbe_set_bit(advertising, RTE_LINK_MODE_FIBRE_BIT);\n+\t\tlink_settings->base.port = RTE_PORT_OTHER;\n+\t\tbreak;\n+\t}\n+\n+\t/* Indicate pause support */\n+\tixgbe_set_bit(supported, RTE_LINK_MODE_Pause_BIT);\n+\tswitch (hw->fc.requested_mode) {\n+\tcase ixgbe_fc_full:\n+\t\tixgbe_set_bit(advertising, RTE_LINK_MODE_Pause_BIT);\n+\t\tbreak;\n+\tcase ixgbe_fc_rx_pause:\n+\t\tixgbe_set_bit(advertising, RTE_LINK_MODE_Pause_BIT);\n+\t\tixgbe_set_bit(advertising, RTE_LINK_MODE_Asym_Pause_BIT);\n+\t\tbreak;\n+\tcase ixgbe_fc_tx_pause:\n+\t\tixgbe_set_bit(advertising, RTE_LINK_MODE_Asym_Pause_BIT);\n+\t\tbreak;\n+\tdefault:\n+\t\tixgbe_set_bit(advertising, RTE_LINK_MODE_Pause_BIT);\n+\t\tixgbe_set_bit(advertising, RTE_LINK_MODE_Asym_Pause_BIT);\n+\t}\n+\n+\tlink_settings->base.link.link_status = RTE_ETH_LINK_DOWN;\n+\tlink_settings->base.link.link_speed = RTE_ETH_SPEED_NUM_NONE;\n+\tlink_settings->base.link.link_duplex = RTE_ETH_LINK_HALF_DUPLEX;\n+\n+\thw->mac.get_link_status = true;\n+\t/* check if it needs to wait to complete, if lsc interrupt is enabled */\n+\tif (dev->data->dev_conf.intr_conf.lsc != 0)\n+\t\twait = 0;\n+\n+\tret_val = ixgbe_check_link(hw, &link_speed, &link_up, wait);\n+\tif (ret_val != IXGBE_SUCCESS)\n+\t\treturn ret_val;\n+\n+\tif (ixgbe_get_media_type(hw) == ixgbe_media_type_fiber &&\n+\t\t!ad->sdp3_no_tx_disable) {\n+\t\tesdp_reg = IXGBE_READ_REG(hw, IXGBE_ESDP);\n+\t\tif ((esdp_reg & IXGBE_ESDP_SDP3))\n+\t\t\tlink_up = 0;\n+\t}\n+\n+\tif (link_up) {\n+\t\tlink_settings->base.link.link_status = RTE_ETH_LINK_UP;\n+\t\tlink_settings->base.link.link_status = RTE_ETH_LINK_FULL_DUPLEX;\n+\t\tswitch (link_speed) {\n+\t\tdefault:\n+\t\tcase IXGBE_LINK_SPEED_UNKNOWN:\n+\t\t\tlink_settings->base.link.link_speed = RTE_ETH_SPEED_NUM_UNKNOWN;\n+\t\t\tbreak;\n+\n+\t\tcase IXGBE_LINK_SPEED_10_FULL:\n+\t\t\tlink_settings->base.link.link_speed = RTE_ETH_SPEED_NUM_10M;\n+\t\t\tbreak;\n+\n+\t\tcase IXGBE_LINK_SPEED_100_FULL:\n+\t\t\tlink_settings->base.link.link_speed = RTE_ETH_SPEED_NUM_100M;\n+\t\t\tbreak;\n+\n+\t\tcase IXGBE_LINK_SPEED_1GB_FULL:\n+\t\t\tlink_settings->base.link.link_speed = RTE_ETH_SPEED_NUM_1G;\n+\t\t\tbreak;\n+\n+\t\tcase IXGBE_LINK_SPEED_2_5GB_FULL:\n+\t\t\tlink_settings->base.link.link_speed = RTE_ETH_SPEED_NUM_2_5G;\n+\t\t\tbreak;\n+\n+\t\tcase IXGBE_LINK_SPEED_5GB_FULL:\n+\t\t\tlink_settings->base.link.link_speed = RTE_ETH_SPEED_NUM_5G;\n+\t\t\tbreak;\n+\n+\t\tcase IXGBE_LINK_SPEED_10GB_FULL:\n+\t\t\tlink_settings->base.link.link_speed = RTE_ETH_SPEED_NUM_10G;\n+\t\t\tbreak;\n+\t\t}\n+\t}\n+\n+\treturn ret_val;\n+}\n+\n+static int ixgbe_set_link_settings(struct rte_eth_dev *dev,\n+\t\t\t\t   const struct rte_link_settings *link_settings)\n+{\n+\tstruct ixgbe_hw *hw = IXGBE_DEV_PRIVATE_TO_HW(dev->data->dev_private);\n+\tconst uint32_t *supported = link_settings->link_modes.supported;\n+\tconst uint32_t *advertising = link_settings->link_modes.advertising;\n+\n+\tu32 advertised, old;\n+\tint ret = 0;\n+\n+\tif (hw->phy.media_type == ixgbe_media_type_copper ||\n+\t    (IXGBE_ISBACKPLANE(hw->phy.media_type)) ||\n+\t    hw->phy.multispeed_fiber) {\n+\t\t/*\n+\t\t * Check if advertising is subset of supported\n+\t\t */\n+\t\tif (!ixgbe_is_subset(advertising, supported,\n+\t\t\t\t     __RTE_LINK_MODE_MASK_NBITS))\n+\t\t\treturn -EINVAL;\n+\n+\t\t/* only allow one speed at a time if no autoneg */\n+\t\tif (!link_settings->base.link.link_autoneg && hw->phy.multispeed_fiber) {\n+\t\t\tif (ixgbe_get_bit(advertising,\n+\t\t\t\t\t  RTE_LINK_MODE_10000baseT_Full_BIT) &&\n+\t\t\t    ixgbe_get_bit(advertising,\n+\t\t\t\t\t  RTE_LINK_MODE_1000baseT_Full_BIT))\n+\t\t\t\treturn -EINVAL;\n+\t\t}\n+\n+\t\told = hw->phy.autoneg_advertised;\n+\t\tadvertised = 0;\n+\t\tif ((ixgbe_get_bit(advertising, RTE_LINK_MODE_10000baseT_Full_BIT)) ||\n+\t\t    (ixgbe_get_bit(advertising, RTE_LINK_MODE_10000baseKR_Full_BIT)) ||\n+\t\t    (ixgbe_get_bit(advertising, RTE_LINK_MODE_10000baseKX4_Full_BIT)))\n+\t\t\tadvertised |= IXGBE_LINK_SPEED_10GB_FULL;\n+\t\tif (ixgbe_get_bit(advertising, RTE_LINK_MODE_5000baseT_Full_BIT))\n+\t\t\tadvertised |= IXGBE_LINK_SPEED_5GB_FULL;\n+\t\tif (ixgbe_get_bit(advertising, RTE_LINK_MODE_2500baseT_Full_BIT))\n+\t\t\tadvertised |= IXGBE_LINK_SPEED_2_5GB_FULL;\n+\t\tif ((ixgbe_get_bit(advertising, RTE_LINK_MODE_1000baseT_Full_BIT)) ||\n+\t\t    (ixgbe_get_bit(advertising, RTE_LINK_MODE_1000baseKX_Full_BIT)))\n+\t\t\tadvertised |= IXGBE_LINK_SPEED_1GB_FULL;\n+\t\tif (ixgbe_get_bit(advertising, RTE_LINK_MODE_100baseT_Full_BIT))\n+\t\t\tadvertised |= IXGBE_LINK_SPEED_100_FULL;\n+\t\tif (ixgbe_get_bit(advertising, RTE_LINK_MODE_10baseT_Full_BIT))\n+\t\t\tadvertised |= IXGBE_LINK_SPEED_10_FULL;\n+\t\tif (old == advertised)\n+\t\t\treturn ret;\n+\n+\t\thw->mac.autotry_restart = true;\n+\t\tret = hw->mac.ops.setup_link(hw, advertised, true);\n+\t\tif (ret) {\n+\t\t\tPMD_DRV_LOG(WARNING, \"setup link failed with code %d\\n\", ret);\n+\t\t\thw->mac.ops.setup_link(hw, old, true);\n+\t\t}\n+\t} else {\n+\t\t/* in this case we currently only support 10Gb/FULL */\n+\t\tu32 speed = link_settings->base.link.link_speed;\n+\n+\t\tif (link_settings->base.link.link_autoneg == RTE_AUTONEG_ENABLE ||\n+\t\t    (!ixgbe_get_bit(advertising, RTE_LINK_MODE_10000baseT_Full_BIT)) ||\n+\t\t    (speed + link_settings->base.link.link_duplex !=\n+\t\t\t\t\t\tIXGBE_SPEED_10000 + IXGBE_DUPLEX_FULL))\n+\t\t\treturn -EINVAL;\n+\t}\n+\n+\treturn ret;\n+}\n+\n static int\n ixgbevf_dev_promiscuous_enable(struct rte_eth_dev *dev)\n {\ndiff --git a/lib/ethdev/ethdev_driver.h b/lib/ethdev/ethdev_driver.h\nindex 0dbf2dd6a2..ee8f786b99 100644\n--- a/lib/ethdev/ethdev_driver.h\n+++ b/lib/ethdev/ethdev_driver.h\n@@ -1119,6 +1119,34 @@ typedef const uint32_t *(*eth_buffer_split_supported_hdr_ptypes_get_t)(struct rt\n  */\n typedef int (*eth_dev_priv_dump_t)(struct rte_eth_dev *dev, FILE *file);\n \n+/** @internal Retrieve physical link settings of a port.\n+ *\n+ * @param dev\n+ *   Port (ethdev) handle\n+ *\n+ * @param[out] settings\n+ *   Physical port link settings.\n+ *\n+ * @return\n+ *   Negative errno value on error, zero otherwise\n+ */\n+typedef int (*eth_get_link_settings_t)(struct rte_eth_dev *dev,\n+\t\t\t\t struct rte_link_settings *settings);\n+\n+/** @internal Configure physical link settings of a port.\n+ *\n+ * @param dev\n+ *   Port (ethdev) handle\n+ *\n+ * @param settings\n+ *   Physical port link settings.\n+ *\n+ * @return\n+ *   Negative errno value on error, zero otherwise\n+ */\n+typedef int (*eth_set_link_settings_t)(struct rte_eth_dev *dev,\n+\t\t\t\t const struct rte_link_settings *settings);\n+\n /**\n  * @internal Set Rx queue available descriptors threshold.\n  * @see rte_eth_rx_avail_thresh_set()\n@@ -1474,6 +1502,11 @@ struct eth_dev_ops {\n \teth_count_aggr_ports_t count_aggr_ports;\n \t/** Map a Tx queue with an aggregated port of the DPDK port */\n \teth_map_aggr_tx_affinity_t map_aggr_tx_affinity;\n+\n+\t/** Retrieve physical link settings */\n+\teth_get_link_settings_t get_link_settings;\n+\t/** Configure physical link settings */\n+\teth_set_link_settings_t set_link_settings;\n };\n \n /**\ndiff --git a/lib/ethdev/rte_ethdev.c b/lib/ethdev/rte_ethdev.c\nindex f1c658f49e..d2c52921ef 100644\n--- a/lib/ethdev/rte_ethdev.c\n+++ b/lib/ethdev/rte_ethdev.c\n@@ -6844,6 +6844,32 @@ rte_eth_dev_priv_dump(uint16_t port_id, FILE *file)\n \treturn eth_err(port_id, (*dev->dev_ops->eth_dev_priv_dump)(dev, file));\n }\n \n+int rte_eth_dev_get_link_settings(uint16_t port_id,\n+\t\t\t\t  struct rte_link_settings *settings)\n+{\n+\tstruct rte_eth_dev *dev;\n+\n+\tRTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);\n+\tdev = &rte_eth_devices[port_id];\n+\n+\tif (*dev->dev_ops->get_link_settings == NULL)\n+\t\treturn -ENOTSUP;\n+\treturn eth_err(port_id, (*dev->dev_ops->get_link_settings)(dev, settings));\n+}\n+\n+int rte_eth_dev_set_link_settings(uint16_t port_id,\n+\t\t\t\t  const struct rte_link_settings *settings)\n+{\n+\tstruct rte_eth_dev *dev;\n+\n+\tRTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);\n+\tdev = &rte_eth_devices[port_id];\n+\n+\tif (*dev->dev_ops->set_link_settings == NULL)\n+\t\treturn -ENOTSUP;\n+\treturn eth_err(port_id, (*dev->dev_ops->set_link_settings)(dev, settings));\n+}\n+\n int\n rte_eth_rx_descriptor_dump(uint16_t port_id, uint16_t queue_id,\n \t\t\t   uint16_t offset, uint16_t num, FILE *file)\ndiff --git a/lib/ethdev/rte_ethdev.h b/lib/ethdev/rte_ethdev.h\nindex 147257d6a2..66aad925d0 100644\n--- a/lib/ethdev/rte_ethdev.h\n+++ b/lib/ethdev/rte_ethdev.h\n@@ -335,7 +335,7 @@ struct rte_eth_stats {\n __extension__\n struct __rte_aligned(8) rte_eth_link { /**< aligned for atomic64 read/write */\n \tuint32_t link_speed;        /**< RTE_ETH_SPEED_NUM_ */\n-\tuint16_t link_duplex  : 1;  /**< RTE_ETH_LINK_[HALF/FULL]_DUPLEX */\n+\tuint16_t link_duplex  : 2;  /**< RTE_ETH_LINK_[HALF/FULL/UNKNOWN]_DUPLEX */\n \tuint16_t link_autoneg : 1;  /**< RTE_ETH_LINK_[AUTONEG/FIXED] */\n \tuint16_t link_status  : 1;  /**< RTE_ETH_LINK_[DOWN/UP] */\n };\n@@ -343,13 +343,27 @@ struct __rte_aligned(8) rte_eth_link { /**< aligned for atomic64 read/write */\n /**@{@name Link negotiation\n  * Constants used in link management.\n  */\n-#define RTE_ETH_LINK_HALF_DUPLEX 0 /**< Half-duplex connection (see link_duplex). */\n-#define RTE_ETH_LINK_FULL_DUPLEX 1 /**< Full-duplex connection (see link_duplex). */\n-#define RTE_ETH_LINK_DOWN        0 /**< Link is down (see link_status). */\n-#define RTE_ETH_LINK_UP          1 /**< Link is up (see link_status). */\n-#define RTE_ETH_LINK_FIXED       0 /**< No autonegotiation (see link_autoneg). */\n-#define RTE_ETH_LINK_AUTONEG     1 /**< Autonegotiated (see link_autoneg). */\n-#define RTE_ETH_LINK_MAX_STR_LEN 40 /**< Max length of default link string. */\n+#define RTE_ETH_LINK_HALF_DUPLEX\t0 /**< Half-duplex connection (see link_duplex). */\n+#define RTE_ETH_LINK_FULL_DUPLEX\t1 /**< Full-duplex connection (see link_duplex). */\n+#define RTE_ETH_LINK_UNKNOWN_DUPLEX\t2 /**</ Unknown-duplex (see link_duplex). */\n+#define RTE_ETH_LINK_DOWN\t\t0 /**< Link is down (see link_status). */\n+#define RTE_ETH_LINK_UP\t\t\t1 /**< Link is up (see link_status). */\n+#define RTE_ETH_LINK_FIXED\t\t0 /**< No autonegotiation (see link_autoneg). */\n+#define RTE_ETH_LINK_AUTONEG\t\t1 /**< Autonegotiated (see link_autoneg). */\n+#define RTE_ETH_LINK_MAX_STR_LEN\t40 /**< Max length of default link string. */\n+/**@}*/\n+\n+/**@{@name Link negotiation\n+ * Constants used in link management to specify connector port.\n+ */\n+#define RTE_PORT_TP             0x00\n+#define RTE_PORT_AUI            0x01\n+#define RTE_PORT_MII            0x02\n+#define RTE_PORT_FIBRE          0x03\n+#define RTE_PORT_BNC            0x04\n+#define RTE_PORT_DA             0x05\n+#define RTE_PORT_NONE           0xef\n+#define RTE_PORT_OTHER          0xff\n /**@}*/\n \n /**\n@@ -1433,6 +1447,147 @@ struct rte_eth_pfc_queue_conf {\n \t} tx_pause; /* Valid when (mode == FC_TX_PAUSE || mode == FC_FULL) */\n };\n \n+/* Enable or disable autonegotiation. */\n+#define RTE_AUTONEG_DISABLE         0x00\n+#define RTE_AUTONEG_ENABLE          0x01\n+\n+/* MDI or MDI-X status/control - if MDI/MDI_X/AUTO is set then\n+ * the driver is required to renegotiate link\n+ */\n+#define RTE_TP_MDI_INVALID      0x00 /* status: unknown; control: unsupported */\n+#define RTE_TP_MDI              0x01 /* status: MDI;     control: force MDI */\n+#define RTE_TP_MDI_X            0x02 /* status: MDI-X;   control: force MDI-X */\n+#define RTE_TP_MDI_AUTO         0x03 /*                  control: auto-select */\n+\n+/* Link mode bit indices */\n+enum rte_link_mode_bit_indices {\n+\tRTE_LINK_MODE_10baseT_Half_BIT\t= 0,\n+\tRTE_LINK_MODE_10baseT_Full_BIT\t= 1,\n+\tRTE_LINK_MODE_100baseT_Half_BIT\t= 2,\n+\tRTE_LINK_MODE_100baseT_Full_BIT\t= 3,\n+\tRTE_LINK_MODE_1000baseT_Half_BIT\t= 4,\n+\tRTE_LINK_MODE_1000baseT_Full_BIT\t= 5,\n+\tRTE_LINK_MODE_Autoneg_BIT\t\t= 6,\n+\tRTE_LINK_MODE_TP_BIT\t\t= 7,\n+\tRTE_LINK_MODE_AUI_BIT\t\t= 8,\n+\tRTE_LINK_MODE_MII_BIT\t\t= 9,\n+\tRTE_LINK_MODE_FIBRE_BIT\t\t= 10,\n+\tRTE_LINK_MODE_BNC_BIT\t\t= 11,\n+\tRTE_LINK_MODE_10000baseT_Full_BIT\t= 12,\n+\tRTE_LINK_MODE_Pause_BIT\t\t= 13,\n+\tRTE_LINK_MODE_Asym_Pause_BIT\t= 14,\n+\tRTE_LINK_MODE_2500baseX_Full_BIT\t= 15,\n+\tRTE_LINK_MODE_Backplane_BIT\t\t= 16,\n+\tRTE_LINK_MODE_1000baseKX_Full_BIT\t= 17,\n+\tRTE_LINK_MODE_10000baseKX4_Full_BIT\t= 18,\n+\tRTE_LINK_MODE_10000baseKR_Full_BIT\t= 19,\n+\tRTE_LINK_MODE_10000baseR_FEC_BIT\t= 20,\n+\tRTE_LINK_MODE_20000baseMLD2_Full_BIT = 21,\n+\tRTE_LINK_MODE_20000baseKR2_Full_BIT\t= 22,\n+\tRTE_LINK_MODE_40000baseKR4_Full_BIT\t= 23,\n+\tRTE_LINK_MODE_40000baseCR4_Full_BIT\t= 24,\n+\tRTE_LINK_MODE_40000baseSR4_Full_BIT\t= 25,\n+\tRTE_LINK_MODE_40000baseLR4_Full_BIT\t= 26,\n+\tRTE_LINK_MODE_56000baseKR4_Full_BIT\t= 27,\n+\tRTE_LINK_MODE_56000baseCR4_Full_BIT\t= 28,\n+\tRTE_LINK_MODE_56000baseSR4_Full_BIT\t= 29,\n+\tRTE_LINK_MODE_56000baseLR4_Full_BIT\t= 30,\n+\tRTE_LINK_MODE_25000baseCR_Full_BIT\t= 31,\n+\tRTE_LINK_MODE_25000baseKR_Full_BIT\t= 32,\n+\tRTE_LINK_MODE_25000baseSR_Full_BIT\t= 33,\n+\tRTE_LINK_MODE_50000baseCR2_Full_BIT\t= 34,\n+\tRTE_LINK_MODE_50000baseKR2_Full_BIT\t= 35,\n+\tRTE_LINK_MODE_100000baseKR4_Full_BIT\t= 36,\n+\tRTE_LINK_MODE_100000baseSR4_Full_BIT\t= 37,\n+\tRTE_LINK_MODE_100000baseCR4_Full_BIT\t= 38,\n+\tRTE_LINK_MODE_100000baseLR4_ER4_Full_BIT\t= 39,\n+\tRTE_LINK_MODE_50000baseSR2_Full_BIT\t\t= 40,\n+\tRTE_LINK_MODE_1000baseX_Full_BIT\t= 41,\n+\tRTE_LINK_MODE_10000baseCR_Full_BIT\t= 42,\n+\tRTE_LINK_MODE_10000baseSR_Full_BIT\t= 43,\n+\tRTE_LINK_MODE_10000baseLR_Full_BIT\t= 44,\n+\tRTE_LINK_MODE_10000baseLRM_Full_BIT\t= 45,\n+\tRTE_LINK_MODE_10000baseER_Full_BIT\t= 46,\n+\tRTE_LINK_MODE_2500baseT_Full_BIT\t= 47,\n+\tRTE_LINK_MODE_5000baseT_Full_BIT\t= 48,\n+\n+\tRTE_LINK_MODE_FEC_NONE_BIT\t= 49,\n+\tRTE_LINK_MODE_FEC_RS_BIT\t= 50,\n+\tRTE_LINK_MODE_FEC_BASER_BIT\t= 51,\n+\tRTE_LINK_MODE_50000baseKR_Full_BIT\t\t = 52,\n+\tRTE_LINK_MODE_50000baseSR_Full_BIT\t\t = 53,\n+\tRTE_LINK_MODE_50000baseCR_Full_BIT\t\t = 54,\n+\tRTE_LINK_MODE_50000baseLR_ER_FR_Full_BIT\t = 55,\n+\tRTE_LINK_MODE_50000baseDR_Full_BIT\t\t = 56,\n+\tRTE_LINK_MODE_100000baseKR2_Full_BIT\t = 57,\n+\tRTE_LINK_MODE_100000baseSR2_Full_BIT\t = 58,\n+\tRTE_LINK_MODE_100000baseCR2_Full_BIT\t = 59,\n+\tRTE_LINK_MODE_100000baseLR2_ER2_FR2_Full_BIT = 60,\n+\tRTE_LINK_MODE_100000baseDR2_Full_BIT\t = 61,\n+\tRTE_LINK_MODE_200000baseKR4_Full_BIT\t = 62,\n+\tRTE_LINK_MODE_200000baseSR4_Full_BIT\t = 63,\n+\tRTE_LINK_MODE_200000baseLR4_ER4_FR4_Full_BIT = 64,\n+\tRTE_LINK_MODE_200000baseDR4_Full_BIT\t = 65,\n+\tRTE_LINK_MODE_200000baseCR4_Full_BIT\t = 66,\n+\tRTE_LINK_MODE_100baseT1_Full_BIT\t\t = 67,\n+\tRTE_LINK_MODE_1000baseT1_Full_BIT\t\t = 68,\n+\tRTE_LINK_MODE_400000baseKR8_Full_BIT\t = 69,\n+\tRTE_LINK_MODE_400000baseSR8_Full_BIT\t = 70,\n+\tRTE_LINK_MODE_400000baseLR8_ER8_FR8_Full_BIT = 71,\n+\tRTE_LINK_MODE_400000baseDR8_Full_BIT\t = 72,\n+\tRTE_LINK_MODE_400000baseCR8_Full_BIT\t = 73,\n+\tRTE_LINK_MODE_FEC_LLRS_BIT\t\t\t = 74,\n+\tRTE_LINK_MODE_100000baseKR_Full_BIT\t\t = 75,\n+\tRTE_LINK_MODE_100000baseSR_Full_BIT\t\t = 76,\n+\tRTE_LINK_MODE_100000baseLR_ER_FR_Full_BIT\t = 77,\n+\tRTE_LINK_MODE_100000baseCR_Full_BIT\t\t = 78,\n+\tRTE_LINK_MODE_100000baseDR_Full_BIT\t\t = 79,\n+\tRTE_LINK_MODE_200000baseKR2_Full_BIT\t = 80,\n+\tRTE_LINK_MODE_200000baseSR2_Full_BIT\t = 81,\n+\tRTE_LINK_MODE_200000baseLR2_ER2_FR2_Full_BIT = 82,\n+\tRTE_LINK_MODE_200000baseDR2_Full_BIT\t = 83,\n+\tRTE_LINK_MODE_200000baseCR2_Full_BIT\t = 84,\n+\tRTE_LINK_MODE_400000baseKR4_Full_BIT\t = 85,\n+\tRTE_LINK_MODE_400000baseSR4_Full_BIT\t = 86,\n+\tRTE_LINK_MODE_400000baseLR4_ER4_FR4_Full_BIT = 87,\n+\tRTE_LINK_MODE_400000baseDR4_Full_BIT\t = 88,\n+\tRTE_LINK_MODE_400000baseCR4_Full_BIT\t = 89,\n+\tRTE_LINK_MODE_100baseFX_Half_BIT\t\t = 90,\n+\tRTE_LINK_MODE_100baseFX_Full_BIT\t\t = 91,\n+\t/* must be last entry */\n+\t__RTE_LINK_MODE_MASK_NBITS\n+};\n+\n+/* number of 32-bit words to store the user's link mode bitmaps */\n+#define RTE_DIV_ROUND_UP(n, d) (((n) + (d) - 1) / (d))\n+#define __RTE_LINK_MODE_MASK_NU32                   \\\n+\tRTE_DIV_ROUND_UP(__RTE_LINK_MODE_MASK_NBITS, 32)\n+\n+/**\n+ * Link control and status\n+ * @speed: Link speed (Mbps)\n+ * @duplex: Duplex mode; one of %DUPLEX_*\n+ * @port: Physical connector type; one of %PORT_*\n+ * @autoneg: Enable/disable autonegotiation and auto-detection;\n+ *\teither %AUTONEG_DISABLE or %AUTONEG_ENABLE\n+ */\n+struct rte_link_base_settings {\n+\tstruct rte_eth_link link;\n+\tuint8_t port;\n+\tuint8_t phy_address;\n+\tuint8_t eth_tp_mdix;\n+\tuint8_t eth_tp_mdix_ctrl;\n+};\n+\n+struct rte_link_settings {\n+\tstruct rte_link_base_settings base;\n+\tstruct {\n+\t\tuint32_t supported[__RTE_LINK_MODE_MASK_NU32];\n+\t\tuint32_t advertising[__RTE_LINK_MODE_MASK_NU32];\n+\t\tuint32_t lp_advertising[__RTE_LINK_MODE_MASK_NU32];\n+\t} link_modes;\n+};\n+\n /**\n  * Tunnel type for device-specific classifier configuration.\n  * @see rte_eth_udp_tunnel\n@@ -5936,6 +6091,50 @@ int rte_eth_cman_config_init(uint16_t port_id, struct rte_eth_cman_config *confi\n __rte_experimental\n int rte_eth_cman_config_set(uint16_t port_id, const struct rte_eth_cman_config *config);\n \n+/**\n+ * @warning\n+ * @b EXPERIMENTAL: this API may change, or be removed, without prior notice\n+ *\n+ * Retrieve link settings\n+ *\n+ * @param port_id\n+ *   The port identifier of the Ethernet device.\n+ * @param settings\n+ *   A pointer to a structure of type *rte_link_settings* to retrieve\n+ *   link settings parameters for the given port.\n+ *\n+ * @return\n+ *   - (0) if successful.\n+ *   - (-ENOTSUP) if support for cman_config_get does not exist.\n+ *   - (-ENODEV) if *port_id* invalid.\n+ *   - (-EINVAL) if bad parameter.\n+ */\n+__rte_experimental\n+int rte_eth_dev_get_link_settings(uint16_t port_id,\n+\t\t\t\t  struct rte_link_settings *settings);\n+\n+/**\n+ * @warning\n+ * @b EXPERIMENTAL: this API may change, or be removed, without prior notice\n+ *\n+ * Configure link settings\n+ *\n+ * @param port_id\n+ *   The port identifier of the Ethernet device.\n+ * @param settings\n+ *   A pointer to a structure of type *rte_link_settings* to configure\n+ *   link settings parameters for the given port.\n+ *\n+ * @return\n+ *   - (0) if successful.\n+ *   - (-ENOTSUP) if support for cman_config_get does not exist.\n+ *   - (-ENODEV) if *port_id* invalid.\n+ *   - (-EINVAL) if bad parameter.\n+ */\n+__rte_experimental\n+int rte_eth_dev_set_link_settings(uint16_t port_id,\n+\t\t\t\t  const struct rte_link_settings *settings);\n+\n /**\n  * @warning\n  * @b EXPERIMENTAL: this API may change, or be removed, without prior notice\ndiff --git a/lib/ethdev/version.map b/lib/ethdev/version.map\nindex 79f6f5293b..5e138a3d10 100644\n--- a/lib/ethdev/version.map\n+++ b/lib/ethdev/version.map\n@@ -325,6 +325,9 @@ EXPERIMENTAL {\n \trte_flow_template_table_resizable;\n \trte_flow_template_table_resize;\n \trte_flow_template_table_resize_complete;\n+\trte_eth_dev_get_link_settings;\n+\trte_eth_dev_set_link_settings;\n+\n };\n \n INTERNAL {\n",
    "prefixes": []
}