get:
Show a patch.

patch:
Update a patch.

put:
Update a patch.

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

{
    "id": 79631,
    "url": "https://patches.dpdk.org/api/patches/79631/?format=api",
    "web_url": "https://patches.dpdk.org/project/dpdk/patch/20201005120910.189343-16-jiawenwu@trustnetic.com/",
    "project": {
        "id": 1,
        "url": "https://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": "<20201005120910.189343-16-jiawenwu@trustnetic.com>",
    "list_archive_url": "https://inbox.dpdk.org/dev/20201005120910.189343-16-jiawenwu@trustnetic.com",
    "date": "2020-10-05T12:08:29",
    "name": "[v2,15/56] net/txgbe: add link status change",
    "commit_ref": null,
    "pull_url": null,
    "state": "changes-requested",
    "archived": true,
    "hash": "0d105f3aac0b70427ae6b9d44013dfa672a835d2",
    "submitter": {
        "id": 1932,
        "url": "https://patches.dpdk.org/api/people/1932/?format=api",
        "name": "Jiawen Wu",
        "email": "jiawenwu@trustnetic.com"
    },
    "delegate": {
        "id": 319,
        "url": "https://patches.dpdk.org/api/users/319/?format=api",
        "username": "fyigit",
        "first_name": "Ferruh",
        "last_name": "Yigit",
        "email": "ferruh.yigit@amd.com"
    },
    "mbox": "https://patches.dpdk.org/project/dpdk/patch/20201005120910.189343-16-jiawenwu@trustnetic.com/mbox/",
    "series": [
        {
            "id": 12690,
            "url": "https://patches.dpdk.org/api/series/12690/?format=api",
            "web_url": "https://patches.dpdk.org/project/dpdk/list/?series=12690",
            "date": "2020-10-05T12:08:14",
            "name": "net: txgbe PMD",
            "version": 2,
            "mbox": "https://patches.dpdk.org/series/12690/mbox/"
        }
    ],
    "comments": "https://patches.dpdk.org/api/patches/79631/comments/",
    "check": "warning",
    "checks": "https://patches.dpdk.org/api/patches/79631/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 dpdk.org (dpdk.org [92.243.14.124])\n\tby inbox.dpdk.org (Postfix) with ESMTP id 138A4A04B1;\n\tMon,  5 Oct 2020 14:14:34 +0200 (CEST)",
            "from [92.243.14.124] (localhost [127.0.0.1])\n\tby dpdk.org (Postfix) with ESMTP id 7027A1BC6F;\n\tMon,  5 Oct 2020 14:09:12 +0200 (CEST)",
            "from smtpbguseast2.qq.com (smtpbguseast2.qq.com [54.204.34.130])\n by dpdk.org (Postfix) with ESMTP id 5C3A61BAB6\n for <dev@dpdk.org>; Mon,  5 Oct 2020 14:09:01 +0200 (CEST)",
            "from localhost.localdomain.com (unknown [183.129.236.74])\n by esmtp6.qq.com (ESMTP) with\n id ; Mon, 05 Oct 2020 20:08:57 +0800 (CST)"
        ],
        "X-QQ-mid": "bizesmtp9t1601899738tz2uo2iia",
        "X-QQ-SSF": "01400000002000C0C000B00A0000000",
        "X-QQ-FEAT": "0ESs8nxzjD96m9Gsa1hf3LBOc2dXIa9Mor9jTsuT5+ItW9FMTPA2EBzyikF5i\n T2HcN9UeXv/bcVFsk1DDnoKG7GHHvP1S3rX7uzP4CzBloUl+8b/KeCxhIuTEK63n8xERGMC\n c1BYVvb9iA0qSGibkO0wJ8SH2Az40RP2s+0uITAxUlXt10jm96oSA7d7MW1dLEO+DQbT+oC\n 3Hvn4y9afwM8YTlVNfvPjqagbuZArrD54XqWz3q06DVOM/XQAnJQ4NhkyiDE7zjUn2nrLsW\n vvyHhbY2fE+1H8jolmxKOX/D/WvMiItpWs1s2cCZSC2f3w/kq0l/5PwtPvv0d3z+bGp486x\n orGZZ7N",
        "X-QQ-GoodBg": "2",
        "From": "Jiawen Wu <jiawenwu@trustnetic.com>",
        "To": "dev@dpdk.org",
        "Cc": "jiawenwu <jiawenwu@trustnetic.com>",
        "Date": "Mon,  5 Oct 2020 20:08:29 +0800",
        "Message-Id": "<20201005120910.189343-16-jiawenwu@trustnetic.com>",
        "X-Mailer": "git-send-email 2.18.4",
        "In-Reply-To": "<20201005120910.189343-1-jiawenwu@trustnetic.com>",
        "References": "<20201005120910.189343-1-jiawenwu@trustnetic.com>",
        "X-QQ-SENDSIZE": "520",
        "Feedback-ID": "bizesmtp:trustnetic.com:qybgforeign:qybgforeign5",
        "X-QQ-Bgrelay": "1",
        "Subject": "[dpdk-dev] [PATCH v2 15/56] net/txgbe: add link status change",
        "X-BeenThere": "dev@dpdk.org",
        "X-Mailman-Version": "2.1.15",
        "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",
        "Sender": "\"dev\" <dev-bounces@dpdk.org>"
    },
    "content": "From: jiawenwu <jiawenwu@trustnetic.com>\n\nAdd ethdev link interrupt handler, MAC setup link and check link status and get capabilities.\n\nSigned-off-by: jiawenwu <jiawenwu@trustnetic.com>\n---\n drivers/net/txgbe/base/txgbe_eeprom.h |   3 +\n drivers/net/txgbe/base/txgbe_hw.c     | 504 +++++++++++++++++++++++++-\n drivers/net/txgbe/base/txgbe_hw.h     |  15 +\n drivers/net/txgbe/base/txgbe_phy.c    | 312 ++++++++++++++++\n drivers/net/txgbe/base/txgbe_phy.h    |  12 +\n drivers/net/txgbe/base/txgbe_type.h   |  21 ++\n drivers/net/txgbe/txgbe_ethdev.c      | 148 +++++++-\n drivers/net/txgbe/txgbe_ethdev.h      |   8 +-\n 8 files changed, 1018 insertions(+), 5 deletions(-)",
    "diff": "diff --git a/drivers/net/txgbe/base/txgbe_eeprom.h b/drivers/net/txgbe/base/txgbe_eeprom.h\nindex 29973e624..3b7f75a5c 100644\n--- a/drivers/net/txgbe/base/txgbe_eeprom.h\n+++ b/drivers/net/txgbe/base/txgbe_eeprom.h\n@@ -24,6 +24,9 @@\n #define TXGBE_ISCSI_BOOT_CONFIG         0x07\n \n #define TXGBE_DEVICE_CAPS_ALLOW_ANY_SFP\t\t0x1\n+#define TXGBE_FW_LESM_PARAMETERS_PTR\t\t0x2\n+#define TXGBE_FW_LESM_STATE_1\t\t\t0x1\n+#define TXGBE_FW_LESM_STATE_ENABLED\t\t0x8000 /* LESM Enable bit */\n \n s32 txgbe_init_eeprom_params(struct txgbe_hw *hw);\n s32 txgbe_calc_eeprom_checksum(struct txgbe_hw *hw);\ndiff --git a/drivers/net/txgbe/base/txgbe_hw.c b/drivers/net/txgbe/base/txgbe_hw.c\nindex 084879331..385a0f892 100644\n--- a/drivers/net/txgbe/base/txgbe_hw.c\n+++ b/drivers/net/txgbe/base/txgbe_hw.c\n@@ -12,6 +12,10 @@\n #define TXGBE_RAPTOR_MAX_RX_QUEUES 128\n #define TXGBE_RAPTOR_RAR_ENTRIES   128\n \n+STATIC s32 txgbe_setup_copper_link_raptor(struct txgbe_hw *hw,\n+\t\t\t\t\t u32 speed,\n+\t\t\t\t\t bool autoneg_wait_to_complete);\n+\n /**\n  *  txgbe_init_hw - Generic hardware initialization\n  *  @hw: pointer to hardware structure\n@@ -96,6 +100,118 @@ s32 txgbe_validate_mac_addr(u8 *mac_addr)\n \treturn status;\n }\n \n+/**\n+ *  txgbe_need_crosstalk_fix - Determine if we need to do cross talk fix\n+ *  @hw: pointer to hardware structure\n+ *\n+ *  Contains the logic to identify if we need to verify link for the\n+ *  crosstalk fix\n+ **/\n+static bool txgbe_need_crosstalk_fix(struct txgbe_hw *hw)\n+{\n+\n+\t/* Does FW say we need the fix */\n+\tif (!hw->need_crosstalk_fix)\n+\t\treturn false;\n+\n+\t/* Only consider SFP+ PHYs i.e. media type fiber */\n+\tswitch (hw->phy.media_type) {\n+\tcase txgbe_media_type_fiber:\n+\tcase txgbe_media_type_fiber_qsfp:\n+\t\tbreak;\n+\tdefault:\n+\t\treturn false;\n+\t}\n+\n+\treturn true;\n+}\n+\n+/**\n+ *  txgbe_check_mac_link - Determine link and speed status\n+ *  @hw: pointer to hardware structure\n+ *  @speed: pointer to link speed\n+ *  @link_up: true when link is up\n+ *  @link_up_wait_to_complete: bool used to wait for link up or not\n+ *\n+ *  Reads the links register to determine if link is up and the current speed\n+ **/\n+s32 txgbe_check_mac_link(struct txgbe_hw *hw, u32 *speed,\n+\t\t\t\t bool *link_up, bool link_up_wait_to_complete)\n+{\n+\tu32 links_reg, links_orig;\n+\tu32 i;\n+\n+\tDEBUGFUNC(\"txgbe_check_mac_link\");\n+\n+\t/* If Crosstalk fix enabled do the sanity check of making sure\n+\t * the SFP+ cage is full.\n+\t */\n+\tif (txgbe_need_crosstalk_fix(hw)) {\n+\t\tu32 sfp_cage_full;\n+\n+\t\tswitch (hw->mac.type) {\n+\t\tcase txgbe_mac_raptor:\n+\t\t\tsfp_cage_full = !rd32m(hw, TXGBE_GPIODATA,\n+\t\t\t\t\tTXGBE_GPIOBIT_2);\n+\t\t\tbreak;\n+\t\tdefault:\n+\t\t\t/* sanity check - No SFP+ devices here */\n+\t\t\tsfp_cage_full = false;\n+\t\t\tbreak;\n+\t\t}\n+\n+\t\tif (!sfp_cage_full) {\n+\t\t\t*link_up = false;\n+\t\t\t*speed = TXGBE_LINK_SPEED_UNKNOWN;\n+\t\t\treturn 0;\n+\t\t}\n+\t}\n+\n+\t/* clear the old state */\n+\tlinks_orig = rd32(hw, TXGBE_PORTSTAT);\n+\n+\tlinks_reg = rd32(hw, TXGBE_PORTSTAT);\n+\n+\tif (links_orig != links_reg) {\n+\t\tDEBUGOUT(\"LINKS changed from %08X to %08X\\n\",\n+\t\t\t  links_orig, links_reg);\n+\t}\n+\n+\tif (link_up_wait_to_complete) {\n+\t\tfor (i = 0; i < hw->mac.max_link_up_time; i++) {\n+\t\t\tif (links_reg & TXGBE_PORTSTAT_UP) {\n+\t\t\t\t*link_up = true;\n+\t\t\t\tbreak;\n+\t\t\t} else {\n+\t\t\t\t*link_up = false;\n+\t\t\t}\n+\t\t\tmsec_delay(100);\n+\t\t\tlinks_reg = rd32(hw, TXGBE_PORTSTAT);\n+\t\t}\n+\t} else {\n+\t\tif (links_reg & TXGBE_PORTSTAT_UP)\n+\t\t\t*link_up = true;\n+\t\telse\n+\t\t\t*link_up = false;\n+\t}\n+\n+\tswitch (links_reg & TXGBE_PORTSTAT_BW_MASK) {\n+\tcase TXGBE_PORTSTAT_BW_10G:\n+\t\t*speed = TXGBE_LINK_SPEED_10GB_FULL;\n+\t\tbreak;\n+\tcase TXGBE_PORTSTAT_BW_1G:\n+\t\t*speed = TXGBE_LINK_SPEED_1GB_FULL;\n+\t\tbreak;\n+\tcase TXGBE_PORTSTAT_BW_100M:\n+\t\t*speed = TXGBE_LINK_SPEED_100M_FULL;\n+\t\tbreak;\n+\tdefault:\n+\t\t*speed = TXGBE_LINK_SPEED_UNKNOWN;\n+\t}\n+\n+\treturn 0;\n+}\n+\n /**\n  * txgbe_clear_tx_pending - Clear pending TX work from the PCIe fifo\n  * @hw: pointer to the hardware structure\n@@ -236,7 +352,8 @@ void txgbe_init_mac_link_ops(struct txgbe_hw *hw)\n \tstruct txgbe_mac_info *mac = &hw->mac;\n \n \tDEBUGFUNC(\"txgbe_init_mac_link_ops\");\n-\tRTE_SET_USED(mac);\n+\n+\tmac->setup_link = txgbe_setup_mac_link;\n }\n \n /**\n@@ -250,6 +367,7 @@ void txgbe_init_mac_link_ops(struct txgbe_hw *hw)\n  **/\n s32 txgbe_init_phy_raptor(struct txgbe_hw *hw)\n {\n+\tstruct txgbe_mac_info *mac = &hw->mac;\n \tstruct txgbe_phy_info *phy = &hw->phy;\n \ts32 err = 0;\n \n@@ -271,6 +389,23 @@ s32 txgbe_init_phy_raptor(struct txgbe_hw *hw)\n \t/* Setup function pointers based on detected SFP module and speeds */\n \ttxgbe_init_mac_link_ops(hw);\n \n+\t/* If copper media, overwrite with copper function pointers */\n+\tif (phy->media_type == txgbe_media_type_copper) {\n+\t\tmac->setup_link = txgbe_setup_copper_link_raptor;\n+\t\tmac->get_link_capabilities =\n+\t\t\t\t  txgbe_get_copper_link_capabilities;\n+\t}\n+\n+\t/* Set necessary function pointers based on PHY type */\n+\tswitch (hw->phy.type) {\n+\tcase txgbe_phy_tn:\n+\t\tphy->setup_link = txgbe_setup_phy_link_tnx;\n+\t\tphy->check_link = txgbe_check_phy_link_tnx;\n+\t\tbreak;\n+\tdefault:\n+\t\tbreak;\n+\t}\n+\n init_phy_ops_out:\n \treturn err;\n }\n@@ -301,6 +436,8 @@ s32 txgbe_init_ops_pf(struct txgbe_hw *hw)\n \tphy->write_reg = txgbe_write_phy_reg;\n \tphy->read_reg_mdi = txgbe_read_phy_reg_mdi;\n \tphy->write_reg_mdi = txgbe_write_phy_reg_mdi;\n+\tphy->setup_link = txgbe_setup_phy_link;\n+\tphy->setup_link_speed = txgbe_setup_phy_link_speed;\n \tphy->read_i2c_byte = txgbe_read_i2c_byte;\n \tphy->write_i2c_byte = txgbe_write_i2c_byte;\n \tphy->read_i2c_eeprom = txgbe_read_i2c_eeprom;\n@@ -311,6 +448,10 @@ s32 txgbe_init_ops_pf(struct txgbe_hw *hw)\n \tmac->init_hw = txgbe_init_hw;\n \tmac->reset_hw = txgbe_reset_hw;\n \n+\t/* Link */\n+\tmac->get_link_capabilities = txgbe_get_link_capabilities_raptor;\n+\tmac->check_link = txgbe_check_mac_link;\n+\n \t/* EEPROM */\n \trom->init_params = txgbe_init_eeprom_params;\n \trom->read16 = txgbe_ee_read16;\n@@ -332,6 +473,291 @@ s32 txgbe_init_ops_pf(struct txgbe_hw *hw)\n \treturn 0;\n }\n \n+/**\n+ *  txgbe_get_link_capabilities_raptor - Determines link capabilities\n+ *  @hw: pointer to hardware structure\n+ *  @speed: pointer to link speed\n+ *  @autoneg: true when autoneg or autotry is enabled\n+ *\n+ *  Determines the link capabilities by reading the AUTOC register.\n+ **/\n+s32 txgbe_get_link_capabilities_raptor(struct txgbe_hw *hw,\n+\t\t\t\t      u32 *speed,\n+\t\t\t\t      bool *autoneg)\n+{\n+\ts32 status = 0;\n+\tu32 autoc = 0;\n+\n+\tDEBUGFUNC(\"txgbe_get_link_capabilities_raptor\");\n+\n+\t/* Check if 1G SFP module. */\n+\tif (hw->phy.sfp_type == txgbe_sfp_type_1g_cu_core0 ||\n+\t    hw->phy.sfp_type == txgbe_sfp_type_1g_cu_core1 ||\n+\t    hw->phy.sfp_type == txgbe_sfp_type_1g_lx_core0 ||\n+\t    hw->phy.sfp_type == txgbe_sfp_type_1g_lx_core1 ||\n+\t    hw->phy.sfp_type == txgbe_sfp_type_1g_sx_core0 ||\n+\t    hw->phy.sfp_type == txgbe_sfp_type_1g_sx_core1) {\n+\t\t*speed = TXGBE_LINK_SPEED_1GB_FULL;\n+\t\t*autoneg = true;\n+\t\treturn 0;\n+\t}\n+\n+\t/*\n+\t * Determine link capabilities based on the stored value of AUTOC,\n+\t * which represents EEPROM defaults.  If AUTOC value has not\n+\t * been stored, use the current register values.\n+\t */\n+\tif (hw->mac.orig_link_settings_stored)\n+\t\tautoc = hw->mac.orig_autoc;\n+\telse\n+\t\tautoc = hw->mac.autoc_read(hw);\n+\n+\tswitch (autoc & TXGBE_AUTOC_LMS_MASK) {\n+\tcase TXGBE_AUTOC_LMS_1G_LINK_NO_AN:\n+\t\t*speed = TXGBE_LINK_SPEED_1GB_FULL;\n+\t\t*autoneg = false;\n+\t\tbreak;\n+\n+\tcase TXGBE_AUTOC_LMS_10G_LINK_NO_AN:\n+\t\t*speed = TXGBE_LINK_SPEED_10GB_FULL;\n+\t\t*autoneg = false;\n+\t\tbreak;\n+\n+\tcase TXGBE_AUTOC_LMS_1G_AN:\n+\t\t*speed = TXGBE_LINK_SPEED_1GB_FULL;\n+\t\t*autoneg = true;\n+\t\tbreak;\n+\n+\tcase TXGBE_AUTOC_LMS_10Gs:\n+\t\t*speed = TXGBE_LINK_SPEED_10GB_FULL;\n+\t\t*autoneg = false;\n+\t\tbreak;\n+\n+\tcase TXGBE_AUTOC_LMS_KX4_KX_KR:\n+\tcase TXGBE_AUTOC_LMS_KX4_KX_KR_1G_AN:\n+\t\t*speed = TXGBE_LINK_SPEED_UNKNOWN;\n+\t\tif (autoc & TXGBE_AUTOC_KR_SUPP)\n+\t\t\t*speed |= TXGBE_LINK_SPEED_10GB_FULL;\n+\t\tif (autoc & TXGBE_AUTOC_KX4_SUPP)\n+\t\t\t*speed |= TXGBE_LINK_SPEED_10GB_FULL;\n+\t\tif (autoc & TXGBE_AUTOC_KX_SUPP)\n+\t\t\t*speed |= TXGBE_LINK_SPEED_1GB_FULL;\n+\t\t*autoneg = true;\n+\t\tbreak;\n+\n+\tcase TXGBE_AUTOC_LMS_KX4_KX_KR_SGMII:\n+\t\t*speed = TXGBE_LINK_SPEED_100M_FULL;\n+\t\tif (autoc & TXGBE_AUTOC_KR_SUPP)\n+\t\t\t*speed |= TXGBE_LINK_SPEED_10GB_FULL;\n+\t\tif (autoc & TXGBE_AUTOC_KX4_SUPP)\n+\t\t\t*speed |= TXGBE_LINK_SPEED_10GB_FULL;\n+\t\tif (autoc & TXGBE_AUTOC_KX_SUPP)\n+\t\t\t*speed |= TXGBE_LINK_SPEED_1GB_FULL;\n+\t\t*autoneg = true;\n+\t\tbreak;\n+\n+\tcase TXGBE_AUTOC_LMS_SGMII_1G_100M:\n+\t\t*speed = TXGBE_LINK_SPEED_1GB_FULL |\n+\t\t\t TXGBE_LINK_SPEED_100M_FULL |\n+\t\t\t TXGBE_LINK_SPEED_10M_FULL;\n+\t\t*autoneg = false;\n+\t\tbreak;\n+\n+\tdefault:\n+\t\treturn TXGBE_ERR_LINK_SETUP;\n+\t}\n+\n+\treturn status;\n+}\n+\n+/**\n+ *  txgbe_start_mac_link_raptor - Setup MAC link settings\n+ *  @hw: pointer to hardware structure\n+ *  @autoneg_wait_to_complete: true when waiting for completion is needed\n+ *\n+ *  Configures link settings based on values in the txgbe_hw struct.\n+ *  Restarts the link.  Performs autonegotiation if needed.\n+ **/\n+s32 txgbe_start_mac_link_raptor(struct txgbe_hw *hw,\n+\t\t\t       bool autoneg_wait_to_complete)\n+{\n+\ts32 status = 0;\n+\tbool got_lock = false;\n+\n+\tDEBUGFUNC(\"txgbe_start_mac_link_raptor\");\n+\n+\tUNREFERENCED_PARAMETER(autoneg_wait_to_complete);\n+\n+\t/*  reset_pipeline requires us to hold this lock as it writes to\n+\t *  AUTOC.\n+\t */\n+\tif (txgbe_verify_lesm_fw_enabled_raptor(hw)) {\n+\t\tstatus = hw->mac.acquire_swfw_sync(hw, TXGBE_MNGSEM_SWPHY);\n+\t\tif (status != 0)\n+\t\t\tgoto out;\n+\n+\t\tgot_lock = true;\n+\t}\n+\n+\t/* Restart link */\n+\ttxgbe_reset_pipeline_raptor(hw);\n+\n+\tif (got_lock)\n+\t\thw->mac.release_swfw_sync(hw, TXGBE_MNGSEM_SWPHY);\n+\n+\t/* Add delay to filter out noises during initial link setup */\n+\tmsec_delay(50);\n+\n+out:\n+\treturn status;\n+}\n+\n+/**\n+ *  txgbe_setup_mac_link - Set MAC link speed\n+ *  @hw: pointer to hardware structure\n+ *  @speed: new link speed\n+ *  @autoneg_wait_to_complete: true when waiting for completion is needed\n+ *\n+ *  Set the link speed in the AUTOC register and restarts link.\n+ **/\n+s32 txgbe_setup_mac_link(struct txgbe_hw *hw,\n+\t\t\t       u32 speed,\n+\t\t\t       bool autoneg_wait_to_complete)\n+{\n+\tbool autoneg = false;\n+\ts32 status = 0;\n+\n+\tu64 autoc = hw->mac.autoc_read(hw);\n+\tu64 pma_pmd_10gs = autoc & TXGBE_AUTOC_10Gs_PMA_PMD_MASK;\n+\tu64 pma_pmd_1g = autoc & TXGBE_AUTOC_1G_PMA_PMD_MASK;\n+\tu64 link_mode = autoc & TXGBE_AUTOC_LMS_MASK;\n+\tu64 current_autoc = autoc;\n+\tu64 orig_autoc = 0;\n+\tu32 links_reg;\n+\tu32 i;\n+\tu32 link_capabilities = TXGBE_LINK_SPEED_UNKNOWN;\n+\n+\tDEBUGFUNC(\"txgbe_setup_mac_link\");\n+\n+\t/* Check to see if speed passed in is supported. */\n+\tstatus = hw->mac.get_link_capabilities(hw,\n+\t\t\t&link_capabilities, &autoneg);\n+\tif (status)\n+\t\treturn status;\n+\n+\tspeed &= link_capabilities;\n+\tif (speed == TXGBE_LINK_SPEED_UNKNOWN) {\n+\t\treturn TXGBE_ERR_LINK_SETUP;\n+\t}\n+\n+\t/* Use stored value (EEPROM defaults) of AUTOC to find KR/KX4 support*/\n+\tif (hw->mac.orig_link_settings_stored)\n+\t\torig_autoc = hw->mac.orig_autoc;\n+\telse\n+\t\torig_autoc = autoc;\n+\n+\tlink_mode = autoc & TXGBE_AUTOC_LMS_MASK;\n+\tpma_pmd_1g = autoc & TXGBE_AUTOC_1G_PMA_PMD_MASK;\n+\n+\tif (link_mode == TXGBE_AUTOC_LMS_KX4_KX_KR ||\n+\t    link_mode == TXGBE_AUTOC_LMS_KX4_KX_KR_1G_AN ||\n+\t    link_mode == TXGBE_AUTOC_LMS_KX4_KX_KR_SGMII) {\n+\t\t/* Set KX4/KX/KR support according to speed requested */\n+\t\tautoc &= ~(TXGBE_AUTOC_KX_SUPP |\n+\t\t\t   TXGBE_AUTOC_KX4_SUPP |\n+\t\t\t   TXGBE_AUTOC_KR_SUPP);\n+\t\tif (speed & TXGBE_LINK_SPEED_10GB_FULL) {\n+\t\t\tif (orig_autoc & TXGBE_AUTOC_KX4_SUPP)\n+\t\t\t\tautoc |= TXGBE_AUTOC_KX4_SUPP;\n+\t\t\tif ((orig_autoc & TXGBE_AUTOC_KR_SUPP) &&\n+\t\t\t    (hw->phy.smart_speed_active == false))\n+\t\t\t\tautoc |= TXGBE_AUTOC_KR_SUPP;\n+\t\t}\n+\t\tif (speed & TXGBE_LINK_SPEED_1GB_FULL)\n+\t\t\tautoc |= TXGBE_AUTOC_KX_SUPP;\n+\t} else if ((pma_pmd_1g == TXGBE_AUTOC_1G_SFI) &&\n+\t\t   (link_mode == TXGBE_AUTOC_LMS_1G_LINK_NO_AN ||\n+\t\t    link_mode == TXGBE_AUTOC_LMS_1G_AN)) {\n+\t\t/* Switch from 1G SFI to 10G SFI if requested */\n+\t\tif ((speed == TXGBE_LINK_SPEED_10GB_FULL) &&\n+\t\t    (pma_pmd_10gs == TXGBE_AUTOC_10Gs_SFI)) {\n+\t\t\tautoc &= ~TXGBE_AUTOC_LMS_MASK;\n+\t\t\tautoc |= TXGBE_AUTOC_LMS_10Gs;\n+\t\t}\n+\t} else if ((pma_pmd_10gs == TXGBE_AUTOC_10Gs_SFI) &&\n+\t\t   (link_mode == TXGBE_AUTOC_LMS_10Gs)) {\n+\t\t/* Switch from 10G SFI to 1G SFI if requested */\n+\t\tif ((speed == TXGBE_LINK_SPEED_1GB_FULL) &&\n+\t\t    (pma_pmd_1g == TXGBE_AUTOC_1G_SFI)) {\n+\t\t\tautoc &= ~TXGBE_AUTOC_LMS_MASK;\n+\t\t\tif (autoneg || hw->phy.type == txgbe_phy_qsfp_intel)\n+\t\t\t\tautoc |= TXGBE_AUTOC_LMS_1G_AN;\n+\t\t\telse\n+\t\t\t\tautoc |= TXGBE_AUTOC_LMS_1G_LINK_NO_AN;\n+\t\t}\n+\t}\n+\n+\tif (autoc == current_autoc) {\n+\t\treturn status;\n+\t}\n+\n+\tautoc &= ~TXGBE_AUTOC_SPEED_MASK;\n+\tautoc |= TXGBE_AUTOC_SPEED(speed);\n+\tautoc |= (autoneg ? TXGBE_AUTOC_AUTONEG : 0);\n+\n+\t/* Restart link */\n+\thw->mac.autoc_write(hw, autoc);\n+\n+\t/* Only poll for autoneg to complete if specified to do so */\n+\tif (autoneg_wait_to_complete) {\n+\t\tif (link_mode == TXGBE_AUTOC_LMS_KX4_KX_KR ||\n+\t\t    link_mode == TXGBE_AUTOC_LMS_KX4_KX_KR_1G_AN ||\n+\t\t    link_mode == TXGBE_AUTOC_LMS_KX4_KX_KR_SGMII) {\n+\t\t\tlinks_reg = 0; /*Just in case Autoneg time=0*/\n+\t\t\tfor (i = 0; i < TXGBE_AUTO_NEG_TIME; i++) {\n+\t\t\t\tlinks_reg = rd32(hw, TXGBE_PORTSTAT);\n+\t\t\t\tif (links_reg & TXGBE_PORTSTAT_UP)\n+\t\t\t\t\tbreak;\n+\t\t\t\tmsec_delay(100);\n+\t\t\t}\n+\t\t\tif (!(links_reg & TXGBE_PORTSTAT_UP)) {\n+\t\t\t\tstatus = TXGBE_ERR_AUTONEG_NOT_COMPLETE;\n+\t\t\t\tDEBUGOUT(\"Autoneg did not complete.\\n\");\n+\t\t\t}\n+\t\t}\n+\t}\n+\n+\t/* Add delay to filter out noises during initial link setup */\n+\tmsec_delay(50);\n+\n+\treturn status;\n+}\n+\n+/**\n+ *  txgbe_setup_copper_link_raptor - Set the PHY autoneg advertised field\n+ *  @hw: pointer to hardware structure\n+ *  @speed: new link speed\n+ *  @autoneg_wait_to_complete: true if waiting is needed to complete\n+ *\n+ *  Restarts link on PHY and MAC based on settings passed in.\n+ **/\n+STATIC s32 txgbe_setup_copper_link_raptor(struct txgbe_hw *hw,\n+\t\t\t\t\t u32 speed,\n+\t\t\t\t\t bool autoneg_wait_to_complete)\n+{\n+\ts32 status;\n+\n+\tDEBUGFUNC(\"txgbe_setup_copper_link_raptor\");\n+\n+\t/* Setup the PHY according to input speed */\n+\tstatus = hw->phy.setup_link_speed(hw, speed,\n+\t\t\t\t\t      autoneg_wait_to_complete);\n+\t/* Set up MAC */\n+\ttxgbe_start_mac_link_raptor(hw, autoneg_wait_to_complete);\n+\n+\treturn status;\n+}\n+\n static int\n txgbe_check_flash_load(struct txgbe_hw *hw, u32 check_bit)\n {\n@@ -486,3 +912,79 @@ s32 txgbe_reset_hw(struct txgbe_hw *hw)\n \treturn status;\n }\n \n+/**\n+ *  txgbe_verify_lesm_fw_enabled_raptor - Checks LESM FW module state.\n+ *  @hw: pointer to hardware structure\n+ *\n+ *  Returns true if the LESM FW module is present and enabled. Otherwise\n+ *  returns false. Smart Speed must be disabled if LESM FW module is enabled.\n+ **/\n+bool txgbe_verify_lesm_fw_enabled_raptor(struct txgbe_hw *hw)\n+{\n+\tbool lesm_enabled = false;\n+\tu16 fw_offset, fw_lesm_param_offset, fw_lesm_state;\n+\ts32 status;\n+\n+\tDEBUGFUNC(\"txgbe_verify_lesm_fw_enabled_raptor\");\n+\n+\t/* get the offset to the Firmware Module block */\n+\tstatus = hw->rom.read16(hw, TXGBE_FW_PTR, &fw_offset);\n+\n+\tif ((status != 0) ||\n+\t    (fw_offset == 0) || (fw_offset == 0xFFFF))\n+\t\tgoto out;\n+\n+\t/* get the offset to the LESM Parameters block */\n+\tstatus = hw->rom.read16(hw, (fw_offset +\n+\t\t\t\t     TXGBE_FW_LESM_PARAMETERS_PTR),\n+\t\t\t\t     &fw_lesm_param_offset);\n+\n+\tif ((status != 0) ||\n+\t    (fw_lesm_param_offset == 0) || (fw_lesm_param_offset == 0xFFFF))\n+\t\tgoto out;\n+\n+\t/* get the LESM state word */\n+\tstatus = hw->rom.read16(hw, (fw_lesm_param_offset +\n+\t\t\t\t     TXGBE_FW_LESM_STATE_1),\n+\t\t\t\t     &fw_lesm_state);\n+\n+\tif ((status == 0) &&\n+\t    (fw_lesm_state & TXGBE_FW_LESM_STATE_ENABLED))\n+\t\tlesm_enabled = true;\n+\n+out:\n+\tlesm_enabled = false;\n+\treturn lesm_enabled;\n+}\n+\n+/**\n+ * txgbe_reset_pipeline_raptor - perform pipeline reset\n+ *\n+ *  @hw: pointer to hardware structure\n+ *\n+ * Reset pipeline by asserting Restart_AN together with LMS change to ensure\n+ * full pipeline reset.  This function assumes the SW/FW lock is held.\n+ **/\n+s32 txgbe_reset_pipeline_raptor(struct txgbe_hw *hw)\n+{\n+\ts32 err = 0;\n+\tu64 autoc;\n+\n+\tautoc = hw->mac.autoc_read(hw);\n+\n+\t/* Enable link if disabled in NVM */\n+\tif (autoc & TXGBE_AUTOC_LINK_DIA_MASK) {\n+\t\tautoc &= ~TXGBE_AUTOC_LINK_DIA_MASK;\n+\t}\n+\n+\tautoc |= TXGBE_AUTOC_AN_RESTART;\n+\t/* Write AUTOC register with toggled LMS[2] bit and Restart_AN */\n+\thw->mac.autoc_write(hw, autoc ^ TXGBE_AUTOC_LMS_AN);\n+\n+\t/* Write AUTOC register with original LMS field and Restart_AN */\n+\thw->mac.autoc_write(hw, autoc);\n+\ttxgbe_flush(hw);\n+\n+\treturn err;\n+}\n+\ndiff --git a/drivers/net/txgbe/base/txgbe_hw.h b/drivers/net/txgbe/base/txgbe_hw.h\nindex 22a54da37..4ee4d5654 100644\n--- a/drivers/net/txgbe/base/txgbe_hw.h\n+++ b/drivers/net/txgbe/base/txgbe_hw.h\n@@ -12,11 +12,26 @@ s32 txgbe_init_hw(struct txgbe_hw *hw);\n void txgbe_set_lan_id_multi_port(struct txgbe_hw *hw);\n \n s32 txgbe_validate_mac_addr(u8 *mac_addr);\n+\n+s32 txgbe_check_mac_link(struct txgbe_hw *hw,\n+\t\t\t       u32 *speed,\n+\t\t\t       bool *link_up, bool link_up_wait_to_complete);\n+\n void txgbe_clear_tx_pending(struct txgbe_hw *hw);\n+\n+extern s32 txgbe_reset_pipeline_raptor(struct txgbe_hw *hw);\n+\n s32 txgbe_init_shared_code(struct txgbe_hw *hw);\n s32 txgbe_set_mac_type(struct txgbe_hw *hw);\n s32 txgbe_init_ops_pf(struct txgbe_hw *hw);\n+s32 txgbe_get_link_capabilities_raptor(struct txgbe_hw *hw,\n+\t\t\t\t      u32 *speed, bool *autoneg);\n+s32 txgbe_start_mac_link_raptor(struct txgbe_hw *hw,\n+\t\t\t       bool autoneg_wait_to_complete);\n+s32 txgbe_setup_mac_link(struct txgbe_hw *hw, u32 speed,\n+\t\t\t       bool autoneg_wait_to_complete);\n void txgbe_init_mac_link_ops(struct txgbe_hw *hw);\n s32 txgbe_reset_hw(struct txgbe_hw *hw);\n s32 txgbe_init_phy_raptor(struct txgbe_hw *hw);\n+bool txgbe_verify_lesm_fw_enabled_raptor(struct txgbe_hw *hw);\n #endif /* _TXGBE_HW_H_ */\ndiff --git a/drivers/net/txgbe/base/txgbe_phy.c b/drivers/net/txgbe/base/txgbe_phy.c\nindex 5e42dfa23..59d28506e 100644\n--- a/drivers/net/txgbe/base/txgbe_phy.c\n+++ b/drivers/net/txgbe/base/txgbe_phy.c\n@@ -426,6 +426,318 @@ s32 txgbe_write_phy_reg(struct txgbe_hw *hw, u32 reg_addr,\n \n \treturn err;\n }\n+\n+/**\n+ *  txgbe_setup_phy_link - Set and restart auto-neg\n+ *  @hw: pointer to hardware structure\n+ *\n+ *  Restart auto-negotiation and PHY and waits for completion.\n+ **/\n+s32 txgbe_setup_phy_link(struct txgbe_hw *hw)\n+{\n+\ts32 err = 0;\n+\tu16 autoneg_reg = TXGBE_MII_AUTONEG_REG;\n+\tbool autoneg = false;\n+\tu32 speed;\n+\n+\tDEBUGFUNC(\"txgbe_setup_phy_link\");\n+\n+\ttxgbe_get_copper_link_capabilities(hw, &speed, &autoneg);\n+\n+\t/* Set or unset auto-negotiation 10G advertisement */\n+\thw->phy.read_reg(hw, TXGBE_MII_10GBASE_T_AUTONEG_CTRL_REG,\n+\t\t\t     TXGBE_MD_DEV_AUTO_NEG,\n+\t\t\t     &autoneg_reg);\n+\n+\tautoneg_reg &= ~TXGBE_MII_10GBASE_T_ADVERTISE;\n+\tif ((hw->phy.autoneg_advertised & TXGBE_LINK_SPEED_10GB_FULL) &&\n+\t    (speed & TXGBE_LINK_SPEED_10GB_FULL))\n+\t\tautoneg_reg |= TXGBE_MII_10GBASE_T_ADVERTISE;\n+\n+\thw->phy.write_reg(hw, TXGBE_MII_10GBASE_T_AUTONEG_CTRL_REG,\n+\t\t\t      TXGBE_MD_DEV_AUTO_NEG,\n+\t\t\t      autoneg_reg);\n+\n+\thw->phy.read_reg(hw, TXGBE_MII_AUTONEG_VENDOR_PROVISION_1_REG,\n+\t\t\t     TXGBE_MD_DEV_AUTO_NEG,\n+\t\t\t     &autoneg_reg);\n+\n+\t/* Set or unset auto-negotiation 5G advertisement */\n+\tautoneg_reg &= ~TXGBE_MII_5GBASE_T_ADVERTISE;\n+\tif ((hw->phy.autoneg_advertised & TXGBE_LINK_SPEED_5GB_FULL) &&\n+\t    (speed & TXGBE_LINK_SPEED_5GB_FULL))\n+\t\tautoneg_reg |= TXGBE_MII_5GBASE_T_ADVERTISE;\n+\n+\t/* Set or unset auto-negotiation 2.5G advertisement */\n+\tautoneg_reg &= ~TXGBE_MII_2_5GBASE_T_ADVERTISE;\n+\tif ((hw->phy.autoneg_advertised &\n+\t     TXGBE_LINK_SPEED_2_5GB_FULL) &&\n+\t    (speed & TXGBE_LINK_SPEED_2_5GB_FULL))\n+\t\tautoneg_reg |= TXGBE_MII_2_5GBASE_T_ADVERTISE;\n+\t/* Set or unset auto-negotiation 1G advertisement */\n+\tautoneg_reg &= ~TXGBE_MII_1GBASE_T_ADVERTISE;\n+\tif ((hw->phy.autoneg_advertised & TXGBE_LINK_SPEED_1GB_FULL) &&\n+\t    (speed & TXGBE_LINK_SPEED_1GB_FULL))\n+\t\tautoneg_reg |= TXGBE_MII_1GBASE_T_ADVERTISE;\n+\n+\thw->phy.write_reg(hw, TXGBE_MII_AUTONEG_VENDOR_PROVISION_1_REG,\n+\t\t\t      TXGBE_MD_DEV_AUTO_NEG,\n+\t\t\t      autoneg_reg);\n+\n+\t/* Set or unset auto-negotiation 100M advertisement */\n+\thw->phy.read_reg(hw, TXGBE_MII_AUTONEG_ADVERTISE_REG,\n+\t\t\t     TXGBE_MD_DEV_AUTO_NEG,\n+\t\t\t     &autoneg_reg);\n+\n+\tautoneg_reg &= ~(TXGBE_MII_100BASE_T_ADVERTISE |\n+\t\t\t TXGBE_MII_100BASE_T_ADVERTISE_HALF);\n+\tif ((hw->phy.autoneg_advertised & TXGBE_LINK_SPEED_100M_FULL) &&\n+\t    (speed & TXGBE_LINK_SPEED_100M_FULL))\n+\t\tautoneg_reg |= TXGBE_MII_100BASE_T_ADVERTISE;\n+\n+\thw->phy.write_reg(hw, TXGBE_MII_AUTONEG_ADVERTISE_REG,\n+\t\t\t      TXGBE_MD_DEV_AUTO_NEG,\n+\t\t\t      autoneg_reg);\n+\n+\t/* Blocked by MNG FW so don't reset PHY */\n+\tif (txgbe_check_reset_blocked(hw))\n+\t\treturn err;\n+\n+\t/* Restart PHY auto-negotiation. */\n+\thw->phy.read_reg(hw, TXGBE_MD_AUTO_NEG_CONTROL,\n+\t\t\t     TXGBE_MD_DEV_AUTO_NEG, &autoneg_reg);\n+\n+\tautoneg_reg |= TXGBE_MII_RESTART;\n+\n+\thw->phy.write_reg(hw, TXGBE_MD_AUTO_NEG_CONTROL,\n+\t\t\t      TXGBE_MD_DEV_AUTO_NEG, autoneg_reg);\n+\n+\treturn err;\n+}\n+\n+/**\n+ *  txgbe_setup_phy_link_speed - Sets the auto advertised capabilities\n+ *  @hw: pointer to hardware structure\n+ *  @speed: new link speed\n+ *  @autoneg_wait_to_complete: unused\n+ **/\n+s32 txgbe_setup_phy_link_speed(struct txgbe_hw *hw,\n+\t\t\t\t       u32 speed,\n+\t\t\t\t       bool autoneg_wait_to_complete)\n+{\n+\tUNREFERENCED_PARAMETER(autoneg_wait_to_complete);\n+\n+\tDEBUGFUNC(\"txgbe_setup_phy_link_speed\");\n+\n+\t/*\n+\t * Clear autoneg_advertised and set new values based on input link\n+\t * speed.\n+\t */\n+\thw->phy.autoneg_advertised = 0;\n+\n+\tif (speed & TXGBE_LINK_SPEED_10GB_FULL)\n+\t\thw->phy.autoneg_advertised |= TXGBE_LINK_SPEED_10GB_FULL;\n+\n+\tif (speed & TXGBE_LINK_SPEED_5GB_FULL)\n+\t\thw->phy.autoneg_advertised |= TXGBE_LINK_SPEED_5GB_FULL;\n+\n+\tif (speed & TXGBE_LINK_SPEED_2_5GB_FULL)\n+\t\thw->phy.autoneg_advertised |= TXGBE_LINK_SPEED_2_5GB_FULL;\n+\n+\tif (speed & TXGBE_LINK_SPEED_1GB_FULL)\n+\t\thw->phy.autoneg_advertised |= TXGBE_LINK_SPEED_1GB_FULL;\n+\n+\tif (speed & TXGBE_LINK_SPEED_100M_FULL)\n+\t\thw->phy.autoneg_advertised |= TXGBE_LINK_SPEED_100M_FULL;\n+\n+\tif (speed & TXGBE_LINK_SPEED_10M_FULL)\n+\t\thw->phy.autoneg_advertised |= TXGBE_LINK_SPEED_10M_FULL;\n+\n+\t/* Setup link based on the new speed settings */\n+\thw->phy.setup_link(hw);\n+\n+\treturn 0;\n+}\n+\n+/**\n+ * txgbe_get_copper_speeds_supported - Get copper link speeds from phy\n+ * @hw: pointer to hardware structure\n+ *\n+ * Determines the supported link capabilities by reading the PHY auto\n+ * negotiation register.\n+ **/\n+static s32 txgbe_get_copper_speeds_supported(struct txgbe_hw *hw)\n+{\n+\ts32 err;\n+\tu16 speed_ability;\n+\n+\terr = hw->phy.read_reg(hw, TXGBE_MD_PHY_SPEED_ABILITY,\n+\t\t\t\t      TXGBE_MD_DEV_PMA_PMD,\n+\t\t\t\t      &speed_ability);\n+\tif (err)\n+\t\treturn err;\n+\n+\tif (speed_ability & TXGBE_MD_PHY_SPEED_10G)\n+\t\thw->phy.speeds_supported |= TXGBE_LINK_SPEED_10GB_FULL;\n+\tif (speed_ability & TXGBE_MD_PHY_SPEED_1G)\n+\t\thw->phy.speeds_supported |= TXGBE_LINK_SPEED_1GB_FULL;\n+\tif (speed_ability & TXGBE_MD_PHY_SPEED_100M)\n+\t\thw->phy.speeds_supported |= TXGBE_LINK_SPEED_100M_FULL;\n+\n+\treturn err;\n+}\n+\n+/**\n+ *  txgbe_get_copper_link_capabilities - Determines link capabilities\n+ *  @hw: pointer to hardware structure\n+ *  @speed: pointer to link speed\n+ *  @autoneg: boolean auto-negotiation value\n+ **/\n+s32 txgbe_get_copper_link_capabilities(struct txgbe_hw *hw,\n+\t\t\t\t\t       u32 *speed,\n+\t\t\t\t\t       bool *autoneg)\n+{\n+\ts32 err = 0;\n+\n+\tDEBUGFUNC(\"txgbe_get_copper_link_capabilities\");\n+\n+\t*autoneg = true;\n+\tif (!hw->phy.speeds_supported)\n+\t\terr = txgbe_get_copper_speeds_supported(hw);\n+\n+\t*speed = hw->phy.speeds_supported;\n+\treturn err;\n+}\n+\n+/**\n+ *  txgbe_check_phy_link_tnx - Determine link and speed status\n+ *  @hw: pointer to hardware structure\n+ *  @speed: current link speed\n+ *  @link_up: true is link is up, false otherwise\n+ *\n+ *  Reads the VS1 register to determine if link is up and the current speed for\n+ *  the PHY.\n+ **/\n+s32 txgbe_check_phy_link_tnx(struct txgbe_hw *hw, u32 *speed,\n+\t\t\t     bool *link_up)\n+{\n+\ts32 err = 0;\n+\tu32 time_out;\n+\tu32 max_time_out = 10;\n+\tu16 phy_link = 0;\n+\tu16 phy_speed = 0;\n+\tu16 phy_data = 0;\n+\n+\tDEBUGFUNC(\"txgbe_check_phy_link_tnx\");\n+\n+\t/* Initialize speed and link to default case */\n+\t*link_up = false;\n+\t*speed = TXGBE_LINK_SPEED_10GB_FULL;\n+\n+\t/*\n+\t * Check current speed and link status of the PHY register.\n+\t * This is a vendor specific register and may have to\n+\t * be changed for other copper PHYs.\n+\t */\n+\tfor (time_out = 0; time_out < max_time_out; time_out++) {\n+\t\tusec_delay(10);\n+\t\terr = hw->phy.read_reg(hw,\n+\t\t\t\t\tTXGBE_MD_VENDOR_SPECIFIC_1_STATUS,\n+\t\t\t\t\tTXGBE_MD_DEV_VENDOR_1,\n+\t\t\t\t\t&phy_data);\n+\t\tphy_link = phy_data & TXGBE_MD_VENDOR_SPECIFIC_1_LINK_STATUS;\n+\t\tphy_speed = phy_data &\n+\t\t\t\t TXGBE_MD_VENDOR_SPECIFIC_1_SPEED_STATUS;\n+\t\tif (phy_link == TXGBE_MD_VENDOR_SPECIFIC_1_LINK_STATUS) {\n+\t\t\t*link_up = true;\n+\t\t\tif (phy_speed ==\n+\t\t\t    TXGBE_MD_VENDOR_SPECIFIC_1_SPEED_STATUS)\n+\t\t\t\t*speed = TXGBE_LINK_SPEED_1GB_FULL;\n+\t\t\tbreak;\n+\t\t}\n+\t}\n+\n+\treturn err;\n+}\n+\n+/**\n+ *  txgbe_setup_phy_link_tnx - Set and restart auto-neg\n+ *  @hw: pointer to hardware structure\n+ *\n+ *  Restart auto-negotiation and PHY and waits for completion.\n+ **/\n+s32 txgbe_setup_phy_link_tnx(struct txgbe_hw *hw)\n+{\n+\ts32 err = 0;\n+\tu16 autoneg_reg = TXGBE_MII_AUTONEG_REG;\n+\tbool autoneg = false;\n+\tu32 speed;\n+\n+\tDEBUGFUNC(\"txgbe_setup_phy_link_tnx\");\n+\n+\ttxgbe_get_copper_link_capabilities(hw, &speed, &autoneg);\n+\n+\tif (speed & TXGBE_LINK_SPEED_10GB_FULL) {\n+\t\t/* Set or unset auto-negotiation 10G advertisement */\n+\t\thw->phy.read_reg(hw, TXGBE_MII_10GBASE_T_AUTONEG_CTRL_REG,\n+\t\t\t\t     TXGBE_MD_DEV_AUTO_NEG,\n+\t\t\t\t     &autoneg_reg);\n+\n+\t\tautoneg_reg &= ~TXGBE_MII_10GBASE_T_ADVERTISE;\n+\t\tif (hw->phy.autoneg_advertised & TXGBE_LINK_SPEED_10GB_FULL)\n+\t\t\tautoneg_reg |= TXGBE_MII_10GBASE_T_ADVERTISE;\n+\n+\t\thw->phy.write_reg(hw, TXGBE_MII_10GBASE_T_AUTONEG_CTRL_REG,\n+\t\t\t\t      TXGBE_MD_DEV_AUTO_NEG,\n+\t\t\t\t      autoneg_reg);\n+\t}\n+\n+\tif (speed & TXGBE_LINK_SPEED_1GB_FULL) {\n+\t\t/* Set or unset auto-negotiation 1G advertisement */\n+\t\thw->phy.read_reg(hw, TXGBE_MII_AUTONEG_XNP_TX_REG,\n+\t\t\t\t     TXGBE_MD_DEV_AUTO_NEG,\n+\t\t\t\t     &autoneg_reg);\n+\n+\t\tautoneg_reg &= ~TXGBE_MII_1GBASE_T_ADVERTISE_XNP_TX;\n+\t\tif (hw->phy.autoneg_advertised & TXGBE_LINK_SPEED_1GB_FULL)\n+\t\t\tautoneg_reg |= TXGBE_MII_1GBASE_T_ADVERTISE_XNP_TX;\n+\n+\t\thw->phy.write_reg(hw, TXGBE_MII_AUTONEG_XNP_TX_REG,\n+\t\t\t\t      TXGBE_MD_DEV_AUTO_NEG,\n+\t\t\t\t      autoneg_reg);\n+\t}\n+\n+\tif (speed & TXGBE_LINK_SPEED_100M_FULL) {\n+\t\t/* Set or unset auto-negotiation 100M advertisement */\n+\t\thw->phy.read_reg(hw, TXGBE_MII_AUTONEG_ADVERTISE_REG,\n+\t\t\t\t     TXGBE_MD_DEV_AUTO_NEG,\n+\t\t\t\t     &autoneg_reg);\n+\n+\t\tautoneg_reg &= ~TXGBE_MII_100BASE_T_ADVERTISE;\n+\t\tif (hw->phy.autoneg_advertised & TXGBE_LINK_SPEED_100M_FULL)\n+\t\t\tautoneg_reg |= TXGBE_MII_100BASE_T_ADVERTISE;\n+\n+\t\thw->phy.write_reg(hw, TXGBE_MII_AUTONEG_ADVERTISE_REG,\n+\t\t\t\t      TXGBE_MD_DEV_AUTO_NEG,\n+\t\t\t\t      autoneg_reg);\n+\t}\n+\n+\t/* Blocked by MNG FW so don't reset PHY */\n+\tif (txgbe_check_reset_blocked(hw))\n+\t\treturn err;\n+\n+\t/* Restart PHY auto-negotiation. */\n+\thw->phy.read_reg(hw, TXGBE_MD_AUTO_NEG_CONTROL,\n+\t\t\t     TXGBE_MD_DEV_AUTO_NEG, &autoneg_reg);\n+\n+\tautoneg_reg |= TXGBE_MII_RESTART;\n+\n+\thw->phy.write_reg(hw, TXGBE_MD_AUTO_NEG_CONTROL,\n+\t\t\t      TXGBE_MD_DEV_AUTO_NEG, autoneg_reg);\n+\n+\treturn err;\n+}\n+\n /**\n  *  txgbe_identify_module - Identifies module type\n  *  @hw: pointer to hardware structure\ndiff --git a/drivers/net/txgbe/base/txgbe_phy.h b/drivers/net/txgbe/base/txgbe_phy.h\nindex 318dca61c..56959b837 100644\n--- a/drivers/net/txgbe/base/txgbe_phy.h\n+++ b/drivers/net/txgbe/base/txgbe_phy.h\n@@ -336,9 +336,21 @@ s32 txgbe_read_phy_reg(struct txgbe_hw *hw, u32 reg_addr,\n \t\t\t       u32 device_type, u16 *phy_data);\n s32 txgbe_write_phy_reg(struct txgbe_hw *hw, u32 reg_addr,\n \t\t\t\tu32 device_type, u16 phy_data);\n+s32 txgbe_setup_phy_link(struct txgbe_hw *hw);\n+s32 txgbe_setup_phy_link_speed(struct txgbe_hw *hw,\n+\t\t\t\t       u32 speed,\n+\t\t\t\t       bool autoneg_wait_to_complete);\n+s32 txgbe_get_copper_link_capabilities(struct txgbe_hw *hw,\n+\t\t\t\t\t       u32 *speed,\n+\t\t\t\t\t       bool *autoneg);\n s32 txgbe_check_reset_blocked(struct txgbe_hw *hw);\n \n /* PHY specific */\n+s32 txgbe_check_phy_link_tnx(struct txgbe_hw *hw,\n+\t\t\t     u32 *speed,\n+\t\t\t     bool *link_up);\n+s32 txgbe_setup_phy_link_tnx(struct txgbe_hw *hw);\n+\n s32 txgbe_identify_module(struct txgbe_hw *hw);\n s32 txgbe_identify_sfp_module(struct txgbe_hw *hw);\n s32 txgbe_identify_qsfp_module(struct txgbe_hw *hw);\ndiff --git a/drivers/net/txgbe/base/txgbe_type.h b/drivers/net/txgbe/base/txgbe_type.h\nindex 499603c61..39f8b3565 100644\n--- a/drivers/net/txgbe/base/txgbe_type.h\n+++ b/drivers/net/txgbe/base/txgbe_type.h\n@@ -6,6 +6,7 @@\n #define _TXGBE_TYPE_H_\n \n #define TXGBE_LINK_UP_TIME\t90 /* 9.0 Seconds */\n+#define TXGBE_AUTO_NEG_TIME\t45 /* 4.5 Seconds */\n \n #define TXGBE_ALIGN\t\t\t\t128 /* as intel did */\n \n@@ -100,6 +101,15 @@ enum txgbe_media_type {\n \ttxgbe_media_type_virtual\n };\n \n+\n+/* Smart Speed Settings */\n+#define TXGBE_SMARTSPEED_MAX_RETRIES\t3\n+enum txgbe_smart_speed {\n+\ttxgbe_smart_speed_auto = 0,\n+\ttxgbe_smart_speed_on,\n+\ttxgbe_smart_speed_off\n+};\n+\n /* PCI bus types */\n enum txgbe_bus_type {\n \ttxgbe_bus_type_unknown = 0,\n@@ -320,6 +330,7 @@ struct txgbe_mac_info {\n \tu32 max_rx_queues;\n \n \tu8  san_mac_rar_index;\n+\tbool get_link_status;\n \tu64 orig_autoc;  /* cached value of AUTOC */\n \tbool orig_link_settings_stored;\n \tbool autotry_restart;\n@@ -366,6 +377,10 @@ struct txgbe_phy_info {\n \tu32 media_type;\n \tu32 phy_semaphore_mask;\n \tbool reset_disable;\n+\tu32 autoneg_advertised;\n+\tu32 speeds_supported;\n+\tenum txgbe_smart_speed smart_speed;\n+\tbool smart_speed_active;\n \tbool multispeed_fiber;\n \tbool qsfp_shared_i2c_bus;\n \tu32 nw_mng_if_sel;\n@@ -406,9 +421,15 @@ struct txgbe_hw {\n \tu16 subsystem_vendor_id;\n \n \tbool allow_unsupported_sfp;\n+\tbool need_crosstalk_fix;\n \n \tuint64_t isb_dma;\n \tvoid IOMEM *isb_mem;\n+\tenum txgbe_link_status {\n+\t\tTXGBE_LINK_STATUS_NONE = 0,\n+\t\tTXGBE_LINK_STATUS_KX,\n+\t\tTXGBE_LINK_STATUS_KX4\n+\t} link_status;\n \tenum txgbe_reset_type {\n \t\tTXGBE_LAN_RESET = 0,\n \t\tTXGBE_SW_RESET,\ndiff --git a/drivers/net/txgbe/txgbe_ethdev.c b/drivers/net/txgbe/txgbe_ethdev.c\nindex 1389bd461..062007f02 100644\n--- a/drivers/net/txgbe/txgbe_ethdev.c\n+++ b/drivers/net/txgbe/txgbe_ethdev.c\n@@ -20,7 +20,11 @@\n #include \"txgbe_ethdev.h\"\n #include \"txgbe_rxtx.h\"\n \n+static int  txgbe_dev_set_link_up(struct rte_eth_dev *dev);\n+static int  txgbe_dev_set_link_down(struct rte_eth_dev *dev);\n static void txgbe_dev_close(struct rte_eth_dev *dev);\n+static int txgbe_dev_link_update(struct rte_eth_dev *dev,\n+\t\t\t\tint wait_to_complete);\n \n static void txgbe_dev_link_status_print(struct rte_eth_dev *dev);\n static int txgbe_dev_lsc_interrupt_setup(struct rte_eth_dev *dev, uint8_t on);\n@@ -508,6 +512,46 @@ txgbe_dev_phy_intr_setup(struct rte_eth_dev *dev)\n \tintr->mask_misc |= TXGBE_ICRMISC_GPIO;\n }\n \n+/*\n+ * Set device link up: enable tx.\n+ */\n+static int\n+txgbe_dev_set_link_up(struct rte_eth_dev *dev)\n+{\n+\tstruct txgbe_hw *hw = TXGBE_DEV_HW(dev);\n+\n+\tif (hw->phy.media_type == txgbe_media_type_copper) {\n+\t\t/* Turn on the copper */\n+\t\thw->phy.set_phy_power(hw, true);\n+\t} else {\n+\t\t/* Turn on the laser */\n+\t\thw->mac.enable_tx_laser(hw);\n+\t\ttxgbe_dev_link_update(dev, 0);\n+\t}\n+\n+\treturn 0;\n+}\n+\n+/*\n+ * Set device link down: disable tx.\n+ */\n+static int\n+txgbe_dev_set_link_down(struct rte_eth_dev *dev)\n+{\n+\tstruct txgbe_hw *hw = TXGBE_DEV_HW(dev);\n+\n+\tif (hw->phy.media_type == txgbe_media_type_copper) {\n+\t\t/* Turn off the copper */\n+\t\thw->phy.set_phy_power(hw, false);\n+\t} else {\n+\t\t/* Turn off the laser */\n+\t\thw->mac.disable_tx_laser(hw);\n+\t\ttxgbe_dev_link_update(dev, 0);\n+\t}\n+\n+\treturn 0;\n+}\n+\n /*\n  * Reset and stop device.\n  */\n@@ -612,12 +656,108 @@ txgbe_dev_info_get(struct rte_eth_dev *dev, struct rte_eth_dev_info *dev_info)\n \treturn 0;\n }\n \n+void\n+txgbe_dev_setup_link_alarm_handler(void *param)\n+{\n+\tstruct rte_eth_dev *dev = (struct rte_eth_dev *)param;\n+\tstruct txgbe_hw *hw = TXGBE_DEV_HW(dev);\n+\tstruct txgbe_interrupt *intr = TXGBE_DEV_INTR(dev);\n+\tu32 speed;\n+\tbool autoneg = false;\n+\n+\tspeed = hw->phy.autoneg_advertised;\n+\tif (!speed)\n+\t\thw->mac.get_link_capabilities(hw, &speed, &autoneg);\n+\n+\thw->mac.setup_link(hw, speed, true);\n+\n+\tintr->flags &= ~TXGBE_FLAG_NEED_LINK_CONFIG;\n+}\n+\n+/* return 0 means link status changed, -1 means not changed */\n+int\n+txgbe_dev_link_update_share(struct rte_eth_dev *dev,\n+\t\t\t    int wait_to_complete)\n+{\n+\tstruct txgbe_hw *hw = TXGBE_DEV_HW(dev);\n+\tstruct rte_eth_link link;\n+\tu32 link_speed = TXGBE_LINK_SPEED_UNKNOWN;\n+\tstruct txgbe_interrupt *intr = TXGBE_DEV_INTR(dev);\n+\tbool link_up;\n+\tint err;\n+\tint wait = 1;\n+\n+\tmemset(&link, 0, sizeof(link));\n+\tlink.link_status = ETH_LINK_DOWN;\n+\tlink.link_speed = ETH_SPEED_NUM_NONE;\n+\tlink.link_duplex = ETH_LINK_HALF_DUPLEX;\n+\tlink.link_autoneg = ETH_LINK_AUTONEG;\n+\n+\thw->mac.get_link_status = true;\n+\n+\tif (intr->flags & TXGBE_FLAG_NEED_LINK_CONFIG)\n+\t\treturn rte_eth_linkstatus_set(dev, &link);\n+\n+\t/* check if it needs to wait to complete, if lsc interrupt is enabled */\n+\tif (wait_to_complete == 0 || dev->data->dev_conf.intr_conf.lsc != 0)\n+\t\twait = 0;\n+\n+\terr = hw->mac.check_link(hw, &link_speed, &link_up, wait);\n+\n+\tif (err != 0) {\n+\t\tlink.link_speed = ETH_SPEED_NUM_100M;\n+\t\tlink.link_duplex = ETH_LINK_FULL_DUPLEX;\n+\t\treturn rte_eth_linkstatus_set(dev, &link);\n+\t}\n+\n+\tif (link_up == 0) {\n+\t\tif (hw->phy.media_type == txgbe_media_type_fiber) {\n+\t\t\tintr->flags |= TXGBE_FLAG_NEED_LINK_CONFIG;\n+\t\t\trte_eal_alarm_set(10,\n+\t\t\t\ttxgbe_dev_setup_link_alarm_handler, dev);\n+\t\t}\n+\t\treturn rte_eth_linkstatus_set(dev, &link);\n+\t}\n+\n+\tintr->flags &= ~TXGBE_FLAG_NEED_LINK_CONFIG;\n+\tlink.link_status = ETH_LINK_UP;\n+\tlink.link_duplex = ETH_LINK_FULL_DUPLEX;\n+\n+\tswitch (link_speed) {\n+\tdefault:\n+\tcase TXGBE_LINK_SPEED_UNKNOWN:\n+\t\tlink.link_duplex = ETH_LINK_FULL_DUPLEX;\n+\t\tlink.link_speed = ETH_SPEED_NUM_100M;\n+\t\tbreak;\n+\n+\tcase TXGBE_LINK_SPEED_100M_FULL:\n+\t\tlink.link_speed = ETH_SPEED_NUM_100M;\n+\t\tbreak;\n+\n+\tcase TXGBE_LINK_SPEED_1GB_FULL:\n+\t\tlink.link_speed = ETH_SPEED_NUM_1G;\n+\t\tbreak;\n+\n+\tcase TXGBE_LINK_SPEED_2_5GB_FULL:\n+\t\tlink.link_speed = ETH_SPEED_NUM_2_5G;\n+\t\tbreak;\n+\n+\tcase TXGBE_LINK_SPEED_5GB_FULL:\n+\t\tlink.link_speed = ETH_SPEED_NUM_5G;\n+\t\tbreak;\n+\n+\tcase TXGBE_LINK_SPEED_10GB_FULL:\n+\t\tlink.link_speed = ETH_SPEED_NUM_10G;\n+\t\tbreak;\n+\t}\n+\n+\treturn rte_eth_linkstatus_set(dev, &link);\n+}\n+\n static int\n txgbe_dev_link_update(struct rte_eth_dev *dev, int wait_to_complete)\n {\n-\tRTE_SET_USED(dev);\n-\tRTE_SET_USED(wait_to_complete);\n-\treturn 0;\n+\treturn txgbe_dev_link_update_share(dev, wait_to_complete);\n }\n \n /**\n@@ -1002,6 +1142,8 @@ txgbe_configure_msix(struct rte_eth_dev *dev)\n static const struct eth_dev_ops txgbe_eth_dev_ops = {\n \t.dev_configure              = txgbe_dev_configure,\n \t.dev_infos_get              = txgbe_dev_info_get,\n+\t.dev_set_link_up            = txgbe_dev_set_link_up,\n+\t.dev_set_link_down          = txgbe_dev_set_link_down,\n };\n \n RTE_PMD_REGISTER_PCI(net_txgbe, rte_txgbe_pmd);\ndiff --git a/drivers/net/txgbe/txgbe_ethdev.h b/drivers/net/txgbe/txgbe_ethdev.h\nindex a3f073b41..1b34ce15c 100644\n--- a/drivers/net/txgbe/txgbe_ethdev.h\n+++ b/drivers/net/txgbe/txgbe_ethdev.h\n@@ -59,7 +59,7 @@ struct txgbe_adapter {\n };\n \n #define TXGBE_DEV_ADAPTER(dev) \\\n-\t\t((struct txgbe_adapter *)(dev)->data->dev_private)\n+\t((struct txgbe_adapter *)(dev)->data->dev_private)\n \n #define TXGBE_DEV_HW(dev) \\\n \t(&((struct txgbe_adapter *)(dev)->data->dev_private)->hw)\n@@ -70,6 +70,10 @@ struct txgbe_adapter {\n void txgbe_set_ivar_map(struct txgbe_hw *hw, int8_t direction,\n \t\t\t       uint8_t queue, uint8_t msix_vector);\n \n+int\n+txgbe_dev_link_update_share(struct rte_eth_dev *dev,\n+\t\tint wait_to_complete);\n+\n #define TXGBE_LINK_DOWN_CHECK_TIMEOUT 4000 /* ms */\n #define TXGBE_LINK_UP_CHECK_TIMEOUT   1000 /* ms */\n #define TXGBE_VMDQ_NUM_UC_MAC         4096 /* Maximum nb. of UC MAC addr. */\n@@ -87,4 +91,6 @@ void txgbe_set_ivar_map(struct txgbe_hw *hw, int8_t direction,\n #define TXGBE_DEFAULT_TX_HTHRESH      0\n #define TXGBE_DEFAULT_TX_WTHRESH      0\n \n+void txgbe_dev_setup_link_alarm_handler(void *param);\n+\n #endif /* _TXGBE_ETHDEV_H_ */\n",
    "prefixes": [
        "v2",
        "15/56"
    ]
}