get:
Show a patch.

patch:
Update a patch.

put:
Update a patch.

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

{
    "id": 139852,
    "url": "https://patches.dpdk.org/api/patches/139852/?format=api",
    "web_url": "https://patches.dpdk.org/project/dpdk/patch/722a9e4acfb079fa8293c26c509c9783672da8bb.1714744629.git.anatoly.burakov@intel.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": "<722a9e4acfb079fa8293c26c509c9783672da8bb.1714744629.git.anatoly.burakov@intel.com>",
    "list_archive_url": "https://inbox.dpdk.org/dev/722a9e4acfb079fa8293c26c509c9783672da8bb.1714744629.git.anatoly.burakov@intel.com",
    "date": "2024-05-03T13:57:55",
    "name": "[v2,24/27] net/ixgbe/base: add link management support for E610 device",
    "commit_ref": null,
    "pull_url": null,
    "state": "new",
    "archived": false,
    "hash": "27a45a7bb972d36a1854907b5d48f0c4f1164176",
    "submitter": {
        "id": 4,
        "url": "https://patches.dpdk.org/api/people/4/?format=api",
        "name": "Burakov, Anatoly",
        "email": "anatoly.burakov@intel.com"
    },
    "delegate": null,
    "mbox": "https://patches.dpdk.org/project/dpdk/patch/722a9e4acfb079fa8293c26c509c9783672da8bb.1714744629.git.anatoly.burakov@intel.com/mbox/",
    "series": [
        {
            "id": 31875,
            "url": "https://patches.dpdk.org/api/series/31875/?format=api",
            "web_url": "https://patches.dpdk.org/project/dpdk/list/?series=31875",
            "date": "2024-05-03T13:57:31",
            "name": "Update IXGBE base driver",
            "version": 2,
            "mbox": "https://patches.dpdk.org/series/31875/mbox/"
        }
    ],
    "comments": "https://patches.dpdk.org/api/patches/139852/comments/",
    "check": "warning",
    "checks": "https://patches.dpdk.org/api/patches/139852/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 2758F43F76;\n\tFri,  3 May 2024 16:01:14 +0200 (CEST)",
            "from mails.dpdk.org (localhost [127.0.0.1])\n\tby mails.dpdk.org (Postfix) with ESMTP id BF70340EE6;\n\tFri,  3 May 2024 15:59:12 +0200 (CEST)",
            "from mgamail.intel.com (mgamail.intel.com [192.198.163.15])\n by mails.dpdk.org (Postfix) with ESMTP id 7E85840EE3\n for <dev@dpdk.org>; Fri,  3 May 2024 15:59:10 +0200 (CEST)",
            "from fmviesa002.fm.intel.com ([10.60.135.142])\n by fmvoesa109.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384;\n 03 May 2024 06:59:10 -0700",
            "from silpixa00401119.ir.intel.com ([10.55.129.167])\n by fmviesa002.fm.intel.com with ESMTP; 03 May 2024 06:59:08 -0700"
        ],
        "DKIM-Signature": "v=1; a=rsa-sha256; c=relaxed/simple;\n d=intel.com; i=@intel.com; q=dns/txt; s=Intel;\n t=1714744750; x=1746280750;\n h=from:to:cc:subject:date:message-id:in-reply-to:\n references:mime-version:content-transfer-encoding;\n bh=V3lEDW+CPmsPQfzET7BKrtg7AhllQO7F3qnWz77dvoU=;\n b=RXUCbOf9Dz0V2tqPUAPqjxKx2Vdm4ENEomm5y5Whoa6N1Ik9HFWqRs5d\n SMUUM6pPgiywn61FMwb2j3FGlu40qldw3LewFMjGtsKlFPhwqHsMUSzC9\n T05Ns7KE+PHnTy22qT9oeo7AWT/knlCEZVISnFvPOgQKeRXtFQQO1UXZS\n FAurBR2IJPic8ALKuKwqbdKV855inmPtq9tsHFmO0nEiLcvMBJDgx40tb\n UcfemEHNozCJmn/ftAep9G7AIDvIf7fHVnhGJsOmIIIm68FZpGJr403le\n 3QvdH3kOF8Ul+8yGBXKxoP/4p13cL7mq/44fBPlyYgMV3FIqfhbP51o/F Q==;",
        "X-CSE-ConnectionGUID": [
            "wydx5GKsQNeNW5c8Rpj3iA==",
            "CddYBPqeQ4CkeuOuqaUmig=="
        ],
        "X-CSE-MsgGUID": [
            "QBjw8nvmTqSkmAnwVaChRg==",
            "aCHie4V/Rd6i1/154B4oNw=="
        ],
        "X-IronPort-AV": [
            "E=McAfee;i=\"6600,9927,11063\"; a=\"10714981\"",
            "E=Sophos;i=\"6.07,251,1708416000\"; d=\"scan'208\";a=\"10714981\"",
            "E=Sophos;i=\"6.07,251,1708416000\"; d=\"scan'208\";a=\"50642058\""
        ],
        "X-ExtLoop1": "1",
        "From": "Anatoly Burakov <anatoly.burakov@intel.com>",
        "To": "dev@dpdk.org",
        "Cc": "Piotr Kwapulinski <piotr.kwapulinski@intel.com>,\n bruce.richardson@intel.com, vladimir.medvedkin@intel.com,\n Stefan Wegrzyn <stefan.wegrzyn@intel.com>,\n Jedrzej Jagielski <jedrzej.jagielski@intel.com>",
        "Subject": "[PATCH v2 24/27] net/ixgbe/base: add link management support for E610\n device",
        "Date": "Fri,  3 May 2024 14:57:55 +0100",
        "Message-ID": "\n <722a9e4acfb079fa8293c26c509c9783672da8bb.1714744629.git.anatoly.burakov@intel.com>",
        "X-Mailer": "git-send-email 2.43.0",
        "In-Reply-To": "<cover.1714744628.git.anatoly.burakov@intel.com>",
        "References": "<cover.1713964707.git.anatoly.burakov@intel.com>\n <cover.1714744628.git.anatoly.burakov@intel.com>",
        "MIME-Version": "1.0",
        "Content-Transfer-Encoding": "8bit",
        "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": "From: Piotr Kwapulinski <piotr.kwapulinski@intel.com>\n\nAdd low level link management support for E610 device. Link management\noperations are handled via the Admin Command Interface.\n\nSigned-off-by: Stefan Wegrzyn <stefan.wegrzyn@intel.com>\nSigned-off-by: Jedrzej Jagielski <jedrzej.jagielski@intel.com>\nSigned-off-by: Piotr Kwapulinski <piotr.kwapulinski@intel.com>\nSigned-off-by: Anatoly Burakov <anatoly.burakov@intel.com>\n---\n drivers/net/ixgbe/base/ixgbe_e610.c | 1313 +++++++++++++++++++++++++++\n drivers/net/ixgbe/base/ixgbe_e610.h |   44 +\n 2 files changed, 1357 insertions(+)",
    "diff": "diff --git a/drivers/net/ixgbe/base/ixgbe_e610.c b/drivers/net/ixgbe/base/ixgbe_e610.c\nindex 7f3eb0cf10..e7e37e794b 100644\n--- a/drivers/net/ixgbe/base/ixgbe_e610.c\n+++ b/drivers/net/ixgbe/base/ixgbe_e610.c\n@@ -1227,3 +1227,1316 @@ void ixgbe_copy_phy_caps_to_cfg(struct ixgbe_aci_cmd_get_phy_caps_data *caps,\n \tcfg->module_compliance_enforcement =\n \t\tcaps->module_compliance_enforcement;\n }\n+\n+/**\n+ * ixgbe_aci_set_phy_cfg - set PHY configuration\n+ * @hw: pointer to the HW struct\n+ * @cfg: structure with PHY configuration data to be set\n+ *\n+ * Set the various PHY configuration parameters supported on the Port\n+ * using ACI command (0x0601).\n+ * One or more of the Set PHY config parameters may be ignored in an MFP\n+ * mode as the PF may not have the privilege to set some of the PHY Config\n+ * parameters.\n+ *\n+ * Return: the exit code of the operation.\n+ */\n+s32 ixgbe_aci_set_phy_cfg(struct ixgbe_hw *hw,\n+\t\t\t  struct ixgbe_aci_cmd_set_phy_cfg_data *cfg)\n+{\n+\tstruct ixgbe_aci_desc desc;\n+\ts32 status;\n+\n+\tif (!cfg)\n+\t\treturn IXGBE_ERR_PARAM;\n+\n+\t/* Ensure that only valid bits of cfg->caps can be turned on. */\n+\tif (cfg->caps & ~IXGBE_ACI_PHY_ENA_VALID_MASK) {\n+\t\tcfg->caps &= IXGBE_ACI_PHY_ENA_VALID_MASK;\n+\t}\n+\n+\tixgbe_fill_dflt_direct_cmd_desc(&desc, ixgbe_aci_opc_set_phy_cfg);\n+\tdesc.flags |= IXGBE_CPU_TO_LE16(IXGBE_ACI_FLAG_RD);\n+\n+\tstatus = ixgbe_aci_send_cmd(hw, &desc, cfg, sizeof(*cfg));\n+\n+\tif (!status)\n+\t\thw->phy.curr_user_phy_cfg = *cfg;\n+\n+\treturn status;\n+}\n+\n+/**\n+ * ixgbe_aci_set_link_restart_an - set up link and restart AN\n+ * @hw: pointer to the HW struct\n+ * @ena_link: if true: enable link, if false: disable link\n+ *\n+ * Function sets up the link and restarts the Auto-Negotiation over the link.\n+ *\n+ * Return: the exit code of the operation.\n+ */\n+s32 ixgbe_aci_set_link_restart_an(struct ixgbe_hw *hw, bool ena_link)\n+{\n+\tstruct ixgbe_aci_cmd_restart_an *cmd;\n+\tstruct ixgbe_aci_desc desc;\n+\n+\tcmd = &desc.params.restart_an;\n+\n+\tixgbe_fill_dflt_direct_cmd_desc(&desc, ixgbe_aci_opc_restart_an);\n+\n+\tcmd->cmd_flags = IXGBE_ACI_RESTART_AN_LINK_RESTART;\n+\tif (ena_link)\n+\t\tcmd->cmd_flags |= IXGBE_ACI_RESTART_AN_LINK_ENABLE;\n+\telse\n+\t\tcmd->cmd_flags &= ~IXGBE_ACI_RESTART_AN_LINK_ENABLE;\n+\n+\treturn ixgbe_aci_send_cmd(hw, &desc, NULL, 0);\n+}\n+\n+/**\n+ * ixgbe_is_media_cage_present - check if media cage is present\n+ * @hw: pointer to the HW struct\n+ *\n+ * Identify presence of media cage using the ACI command (0x06E0).\n+ *\n+ * Return: true if media cage is present, else false. If no cage, then\n+ * media type is backplane or BASE-T.\n+ */\n+static bool ixgbe_is_media_cage_present(struct ixgbe_hw *hw)\n+{\n+\tstruct ixgbe_aci_cmd_get_link_topo *cmd;\n+\tstruct ixgbe_aci_desc desc;\n+\n+\tcmd = &desc.params.get_link_topo;\n+\n+\tixgbe_fill_dflt_direct_cmd_desc(&desc, ixgbe_aci_opc_get_link_topo);\n+\n+\tcmd->addr.topo_params.node_type_ctx =\n+\t\t(IXGBE_ACI_LINK_TOPO_NODE_CTX_PORT <<\n+\t\t IXGBE_ACI_LINK_TOPO_NODE_CTX_S);\n+\n+\t/* set node type */\n+\tcmd->addr.topo_params.node_type_ctx |=\n+\t\t(IXGBE_ACI_LINK_TOPO_NODE_TYPE_M &\n+\t\t IXGBE_ACI_LINK_TOPO_NODE_TYPE_CAGE);\n+\n+\t/* Node type cage can be used to determine if cage is present. If AQC\n+\t * returns error (ENOENT), then no cage present. If no cage present then\n+\t * connection type is backplane or BASE-T.\n+\t */\n+\treturn ixgbe_aci_get_netlist_node(hw, cmd, NULL, NULL);\n+}\n+\n+/**\n+ * ixgbe_get_media_type_from_phy_type - Gets media type based on phy type\n+ * @hw: pointer to the HW struct\n+ *\n+ * Try to identify the media type based on the phy type.\n+ * If more than one media type, the ixgbe_media_type_unknown is returned.\n+ * First, phy_type_low is checked, then phy_type_high.\n+ * If none are identified, the ixgbe_media_type_unknown is returned\n+ *\n+ * Return: type of a media based on phy type in form of enum.\n+ */\n+static enum ixgbe_media_type\n+ixgbe_get_media_type_from_phy_type(struct ixgbe_hw *hw)\n+{\n+\tstruct ixgbe_link_status *hw_link_info;\n+\n+\tif (!hw)\n+\t\treturn ixgbe_media_type_unknown;\n+\n+\thw_link_info = &hw->link.link_info;\n+\tif (hw_link_info->phy_type_low && hw_link_info->phy_type_high)\n+\t\t/* If more than one media type is selected, report unknown */\n+\t\treturn ixgbe_media_type_unknown;\n+\n+\tif (hw_link_info->phy_type_low) {\n+\t\t/* 1G SGMII is a special case where some DA cable PHYs\n+\t\t * may show this as an option when it really shouldn't\n+\t\t * be since SGMII is meant to be between a MAC and a PHY\n+\t\t * in a backplane. Try to detect this case and handle it\n+\t\t */\n+\t\tif (hw_link_info->phy_type_low == IXGBE_PHY_TYPE_LOW_1G_SGMII &&\n+\t\t    (hw_link_info->module_type[IXGBE_ACI_MOD_TYPE_IDENT] ==\n+\t\t    IXGBE_ACI_MOD_TYPE_BYTE1_SFP_PLUS_CU_ACTIVE ||\n+\t\t    hw_link_info->module_type[IXGBE_ACI_MOD_TYPE_IDENT] ==\n+\t\t    IXGBE_ACI_MOD_TYPE_BYTE1_SFP_PLUS_CU_PASSIVE))\n+\t\t\treturn ixgbe_media_type_da;\n+\n+\t\tswitch (hw_link_info->phy_type_low) {\n+\t\tcase IXGBE_PHY_TYPE_LOW_1000BASE_SX:\n+\t\tcase IXGBE_PHY_TYPE_LOW_1000BASE_LX:\n+\t\tcase IXGBE_PHY_TYPE_LOW_10GBASE_SR:\n+\t\tcase IXGBE_PHY_TYPE_LOW_10GBASE_LR:\n+\t\tcase IXGBE_PHY_TYPE_LOW_25GBASE_SR:\n+\t\tcase IXGBE_PHY_TYPE_LOW_25GBASE_LR:\n+\t\t\treturn ixgbe_media_type_fiber;\n+\t\tcase IXGBE_PHY_TYPE_LOW_10G_SFI_AOC_ACC:\n+\t\tcase IXGBE_PHY_TYPE_LOW_25G_AUI_AOC_ACC:\n+\t\t\treturn ixgbe_media_type_fiber;\n+\t\tcase IXGBE_PHY_TYPE_LOW_100BASE_TX:\n+\t\tcase IXGBE_PHY_TYPE_LOW_1000BASE_T:\n+\t\tcase IXGBE_PHY_TYPE_LOW_2500BASE_T:\n+\t\tcase IXGBE_PHY_TYPE_LOW_5GBASE_T:\n+\t\tcase IXGBE_PHY_TYPE_LOW_10GBASE_T:\n+\t\tcase IXGBE_PHY_TYPE_LOW_25GBASE_T:\n+\t\t\treturn ixgbe_media_type_copper;\n+\t\tcase IXGBE_PHY_TYPE_LOW_10G_SFI_DA:\n+\t\tcase IXGBE_PHY_TYPE_LOW_25GBASE_CR:\n+\t\tcase IXGBE_PHY_TYPE_LOW_25GBASE_CR_S:\n+\t\tcase IXGBE_PHY_TYPE_LOW_25GBASE_CR1:\n+\t\t\treturn ixgbe_media_type_da;\n+\t\tcase IXGBE_PHY_TYPE_LOW_25G_AUI_C2C:\n+\t\t\tif (ixgbe_is_media_cage_present(hw))\n+\t\t\t\treturn ixgbe_media_type_aui;\n+\t\t\treturn ixgbe_media_type_backplane;\n+\t\tcase IXGBE_PHY_TYPE_LOW_1000BASE_KX:\n+\t\tcase IXGBE_PHY_TYPE_LOW_2500BASE_KX:\n+\t\tcase IXGBE_PHY_TYPE_LOW_2500BASE_X:\n+\t\tcase IXGBE_PHY_TYPE_LOW_5GBASE_KR:\n+\t\tcase IXGBE_PHY_TYPE_LOW_10GBASE_KR_CR1:\n+\t\tcase IXGBE_PHY_TYPE_LOW_10G_SFI_C2C:\n+\t\tcase IXGBE_PHY_TYPE_LOW_25GBASE_KR:\n+\t\tcase IXGBE_PHY_TYPE_LOW_25GBASE_KR1:\n+\t\tcase IXGBE_PHY_TYPE_LOW_25GBASE_KR_S:\n+\t\t\treturn ixgbe_media_type_backplane;\n+\t\t}\n+\t} else {\n+\t\tswitch (hw_link_info->phy_type_high) {\n+\t\tcase IXGBE_PHY_TYPE_HIGH_10BASE_T:\n+\t\t\treturn ixgbe_media_type_copper;\n+\t\t}\n+\t}\n+\treturn ixgbe_media_type_unknown;\n+}\n+\n+/**\n+ * ixgbe_update_link_info - update status of the HW network link\n+ * @hw: pointer to the HW struct\n+ *\n+ * Update the status of the HW network link.\n+ *\n+ * Return: the exit code of the operation.\n+ */\n+s32 ixgbe_update_link_info(struct ixgbe_hw *hw)\n+{\n+\tstruct ixgbe_aci_cmd_get_phy_caps_data *pcaps;\n+\tstruct ixgbe_link_status *li;\n+\ts32 status;\n+\n+\tif (!hw)\n+\t\treturn IXGBE_ERR_PARAM;\n+\n+\tli = &hw->link.link_info;\n+\n+\tstatus = ixgbe_aci_get_link_info(hw, true, NULL);\n+\tif (status)\n+\t\treturn status;\n+\n+\tif (li->link_info & IXGBE_ACI_MEDIA_AVAILABLE) {\n+\t\tpcaps = (struct ixgbe_aci_cmd_get_phy_caps_data *)\n+\t\t\tixgbe_malloc(hw, sizeof(*pcaps));\n+\t\tif (!pcaps)\n+\t\t\treturn IXGBE_ERR_OUT_OF_MEM;\n+\n+\t\tstatus = ixgbe_aci_get_phy_caps(hw, false,\n+\t\t\t\t\t\tIXGBE_ACI_REPORT_TOPO_CAP_MEDIA,\n+\t\t\t\t\t\tpcaps);\n+\n+\t\tif (status == IXGBE_SUCCESS)\n+\t\t\tmemcpy(li->module_type, &pcaps->module_type,\n+\t\t\t       sizeof(li->module_type));\n+\n+\t\tixgbe_free(hw, pcaps);\n+\t}\n+\n+\treturn status;\n+}\n+\n+/**\n+ * ixgbe_get_link_status - get status of the HW network link\n+ * @hw: pointer to the HW struct\n+ * @link_up: pointer to bool (true/false = linkup/linkdown)\n+ *\n+ * Variable link_up is true if link is up, false if link is down.\n+ * The variable link_up is invalid if status is non zero. As a\n+ * result of this call, link status reporting becomes enabled\n+ *\n+ * Return: the exit code of the operation.\n+ */\n+s32 ixgbe_get_link_status(struct ixgbe_hw *hw, bool *link_up)\n+{\n+\ts32 status = IXGBE_SUCCESS;\n+\n+\tif (!hw || !link_up)\n+\t\treturn IXGBE_ERR_PARAM;\n+\n+\tif (hw->link.get_link_info) {\n+\t\tstatus = ixgbe_update_link_info(hw);\n+\t\tif (status) {\n+\t\t\treturn status;\n+\t\t}\n+\t}\n+\n+\t*link_up = hw->link.link_info.link_info & IXGBE_ACI_LINK_UP;\n+\n+\treturn status;\n+}\n+\n+/**\n+ * ixgbe_aci_get_link_info - get the link status\n+ * @hw: pointer to the HW struct\n+ * @ena_lse: enable/disable LinkStatusEvent reporting\n+ * @link: pointer to link status structure - optional\n+ *\n+ * Get the current Link Status using ACI command (0x607).\n+ * The current link can be optionally provided to update\n+ * the status.\n+ *\n+ * Return: the link status of the adapter.\n+ */\n+s32 ixgbe_aci_get_link_info(struct ixgbe_hw *hw, bool ena_lse,\n+\t\t\t    struct ixgbe_link_status *link)\n+{\n+\tstruct ixgbe_aci_cmd_get_link_status_data link_data = { 0 };\n+\tstruct ixgbe_aci_cmd_get_link_status *resp;\n+\tstruct ixgbe_link_status *li_old, *li;\n+\tstruct ixgbe_fc_info *hw_fc_info;\n+\tenum ixgbe_media_type *hw_media_type;\n+\tstruct ixgbe_aci_desc desc;\n+\tbool tx_pause, rx_pause;\n+\tu8 cmd_flags;\n+\ts32 status;\n+\n+\tif (!hw)\n+\t\treturn IXGBE_ERR_PARAM;\n+\n+\tli_old = &hw->link.link_info_old;\n+\thw_media_type = &hw->phy.media_type;\n+\tli = &hw->link.link_info;\n+\thw_fc_info = &hw->fc;\n+\n+\tixgbe_fill_dflt_direct_cmd_desc(&desc, ixgbe_aci_opc_get_link_status);\n+\tcmd_flags = (ena_lse) ? IXGBE_ACI_LSE_ENA : IXGBE_ACI_LSE_DIS;\n+\tresp = &desc.params.get_link_status;\n+\tresp->cmd_flags = cmd_flags;\n+\n+\tstatus = ixgbe_aci_send_cmd(hw, &desc, &link_data, sizeof(link_data));\n+\n+\tif (status != IXGBE_SUCCESS)\n+\t\treturn status;\n+\n+\t/* save off old link status information */\n+\t*li_old = *li;\n+\n+\t/* update current link status information */\n+\tli->link_speed = IXGBE_LE16_TO_CPU(link_data.link_speed);\n+\tli->phy_type_low = IXGBE_LE64_TO_CPU(link_data.phy_type_low);\n+\tli->phy_type_high = IXGBE_LE64_TO_CPU(link_data.phy_type_high);\n+\t*hw_media_type = ixgbe_get_media_type_from_phy_type(hw);\n+\tli->link_info = link_data.link_info;\n+\tli->link_cfg_err = link_data.link_cfg_err;\n+\tli->an_info = link_data.an_info;\n+\tli->ext_info = link_data.ext_info;\n+\tli->max_frame_size = IXGBE_LE16_TO_CPU(link_data.max_frame_size);\n+\tli->fec_info = link_data.cfg & IXGBE_ACI_FEC_MASK;\n+\tli->topo_media_conflict = link_data.topo_media_conflict;\n+\tli->pacing = link_data.cfg & (IXGBE_ACI_CFG_PACING_M |\n+\t\t\t\t      IXGBE_ACI_CFG_PACING_TYPE_M);\n+\n+\t/* update fc info */\n+\ttx_pause = !!(link_data.an_info & IXGBE_ACI_LINK_PAUSE_TX);\n+\trx_pause = !!(link_data.an_info & IXGBE_ACI_LINK_PAUSE_RX);\n+\tif (tx_pause && rx_pause)\n+\t\thw_fc_info->current_mode = ixgbe_fc_full;\n+\telse if (tx_pause)\n+\t\thw_fc_info->current_mode = ixgbe_fc_tx_pause;\n+\telse if (rx_pause)\n+\t\thw_fc_info->current_mode = ixgbe_fc_rx_pause;\n+\telse\n+\t\thw_fc_info->current_mode = ixgbe_fc_none;\n+\n+\tli->lse_ena = !!(resp->cmd_flags & IXGBE_ACI_LSE_IS_ENABLED);\n+\n+\t/* save link status information */\n+\tif (link)\n+\t\t*link = *li;\n+\n+\t/* flag cleared so calling functions don't call AQ again */\n+\thw->link.get_link_info = false;\n+\n+\treturn IXGBE_SUCCESS;\n+}\n+\n+/**\n+ * ixgbe_aci_set_event_mask - set event mask\n+ * @hw: pointer to the HW struct\n+ * @port_num: port number of the physical function\n+ * @mask: event mask to be set\n+ *\n+ * Set the event mask using ACI command (0x0613).\n+ *\n+ * Return: the exit code of the operation.\n+ */\n+s32 ixgbe_aci_set_event_mask(struct ixgbe_hw *hw, u8 port_num, u16 mask)\n+{\n+\tstruct ixgbe_aci_cmd_set_event_mask *cmd;\n+\tstruct ixgbe_aci_desc desc;\n+\n+\tcmd = &desc.params.set_event_mask;\n+\n+\tixgbe_fill_dflt_direct_cmd_desc(&desc, ixgbe_aci_opc_set_event_mask);\n+\n+\tcmd->event_mask = IXGBE_CPU_TO_LE16(mask);\n+\treturn ixgbe_aci_send_cmd(hw, &desc, NULL, 0);\n+}\n+\n+/**\n+ * ixgbe_configure_lse - enable/disable link status events\n+ * @hw: pointer to the HW struct\n+ * @activate: bool value deciding if lse should be enabled nor disabled\n+ * @mask: event mask to be set; a set bit means deactivation of the\n+ * corresponding event\n+ *\n+ * Set the event mask and then enable or disable link status events\n+ *\n+ * Return: the exit code of the operation.\n+ */\n+s32 ixgbe_configure_lse(struct ixgbe_hw *hw, bool activate, u16 mask)\n+{\n+\ts32 rc;\n+\n+\trc = ixgbe_aci_set_event_mask(hw, (u8)hw->bus.func, mask);\n+\tif (rc) {\n+\t\treturn rc;\n+\t}\n+\n+\t/* Enabling link status events generation by fw */\n+\trc = ixgbe_aci_get_link_info(hw, activate, NULL);\n+\tif (rc) {\n+\t\treturn rc;\n+\t}\n+\treturn IXGBE_SUCCESS;\n+}\n+\n+/**\n+ * ixgbe_aci_get_netlist_node - get a node handle\n+ * @hw: pointer to the hw struct\n+ * @cmd: get_link_topo AQ structure\n+ * @node_part_number: output node part number if node found\n+ * @node_handle: output node handle parameter if node found\n+ *\n+ * Get the netlist node and assigns it to\n+ * the provided handle using ACI command (0x06E0).\n+ *\n+ * Return: the exit code of the operation.\n+ */\n+s32 ixgbe_aci_get_netlist_node(struct ixgbe_hw *hw,\n+\t\t\t       struct ixgbe_aci_cmd_get_link_topo *cmd,\n+\t\t\t       u8 *node_part_number, u16 *node_handle)\n+{\n+\tstruct ixgbe_aci_desc desc;\n+\n+\tixgbe_fill_dflt_direct_cmd_desc(&desc, ixgbe_aci_opc_get_link_topo);\n+\tdesc.params.get_link_topo = *cmd;\n+\n+\tif (ixgbe_aci_send_cmd(hw, &desc, NULL, 0))\n+\t\treturn IXGBE_ERR_NOT_SUPPORTED;\n+\n+\tif (node_handle)\n+\t\t*node_handle =\n+\t\t\tIXGBE_LE16_TO_CPU(desc.params.get_link_topo.addr.handle);\n+\tif (node_part_number)\n+\t\t*node_part_number = desc.params.get_link_topo.node_part_num;\n+\n+\treturn IXGBE_SUCCESS;\n+}\n+\n+/**\n+ * ixgbe_aci_sff_eeprom - read/write SFF EEPROM\n+ * @hw: pointer to the HW struct\n+ * @lport: bits [7:0] = logical port, bit [8] = logical port valid\n+ * @bus_addr: I2C bus address of the eeprom (typically 0xA0, 0=topo default)\n+ * @mem_addr: I2C offset. lower 8 bits for address, 8 upper bits zero padding.\n+ * @page: QSFP page\n+ * @page_bank_ctrl: configuration of SFF/CMIS paging and banking control\n+ * @data: pointer to data buffer to be read/written to the I2C device.\n+ * @length: 1-16 for read, 1 for write.\n+ * @write: 0 read, 1 for write.\n+ *\n+ * Read/write SFF EEPROM using ACI command (0x06EE).\n+ *\n+ * Return: the exit code of the operation.\n+ */\n+s32 ixgbe_aci_sff_eeprom(struct ixgbe_hw *hw, u16 lport, u8 bus_addr,\n+\t\t\t u16 mem_addr, u8 page, u8 page_bank_ctrl, u8 *data,\n+\t\t\t u8 length, bool write)\n+{\n+\tstruct ixgbe_aci_cmd_sff_eeprom *cmd;\n+\tstruct ixgbe_aci_desc desc;\n+\ts32 status;\n+\n+\tif (!data || (mem_addr & 0xff00))\n+\t\treturn IXGBE_ERR_PARAM;\n+\n+\tixgbe_fill_dflt_direct_cmd_desc(&desc, ixgbe_aci_opc_sff_eeprom);\n+\tcmd = &desc.params.read_write_sff_param;\n+\tdesc.flags = IXGBE_CPU_TO_LE16(IXGBE_ACI_FLAG_RD);\n+\tcmd->lport_num = (u8)(lport & 0xff);\n+\tcmd->lport_num_valid = (u8)((lport >> 8) & 0x01);\n+\tcmd->i2c_bus_addr = IXGBE_CPU_TO_LE16(((bus_addr >> 1) &\n+\t\t\t\t\t IXGBE_ACI_SFF_I2CBUS_7BIT_M) |\n+\t\t\t\t\t((page_bank_ctrl <<\n+\t\t\t\t\t  IXGBE_ACI_SFF_PAGE_BANK_CTRL_S) &\n+\t\t\t\t\t IXGBE_ACI_SFF_PAGE_BANK_CTRL_M));\n+\tcmd->i2c_offset = IXGBE_CPU_TO_LE16(mem_addr & 0xff);\n+\tcmd->module_page = page;\n+\tif (write)\n+\t\tcmd->i2c_bus_addr |= IXGBE_CPU_TO_LE16(IXGBE_ACI_SFF_IS_WRITE);\n+\n+\tstatus = ixgbe_aci_send_cmd(hw, &desc, data, length);\n+\treturn status;\n+}\n+\n+/**\n+ * ixgbe_get_media_type_E610 - Gets media type\n+ * @hw: pointer to the HW struct\n+ *\n+ * In order to get the media type, the function gets PHY\n+ * capabilities and later on use them to identify the PHY type\n+ * checking phy_type_high and phy_type_low.\n+ *\n+ * Return: the type of media in form of ixgbe_media_type enum\n+ * or ixgbe_media_type_unknown in case of an error.\n+ */\n+enum ixgbe_media_type ixgbe_get_media_type_E610(struct ixgbe_hw *hw)\n+{\n+\tstruct ixgbe_aci_cmd_get_phy_caps_data pcaps;\n+\tu64 phy_mask = 0;\n+\ts32 rc;\n+\tu8 i;\n+\n+\trc = ixgbe_update_link_info(hw);\n+\tif (rc) {\n+\t\treturn ixgbe_media_type_unknown;\n+\t}\n+\n+\t/* If there is no link but PHY (dongle) is available SW should use\n+\t * Get PHY Caps admin command instead of Get Link Status, find most\n+\t * significant bit that is set in PHY types reported by the command\n+\t * and use it to discover media type.\n+\t */\n+\tif (!(hw->link.link_info.link_info & IXGBE_ACI_LINK_UP) &&\n+\t    (hw->link.link_info.link_info & IXGBE_ACI_MEDIA_AVAILABLE)) {\n+\t\t/* Get PHY Capabilities */\n+\t\trc = ixgbe_aci_get_phy_caps(hw, false,\n+\t\t\t\t\t    IXGBE_ACI_REPORT_TOPO_CAP_MEDIA,\n+\t\t\t\t\t    &pcaps);\n+\t\tif (rc) {\n+\t\t\treturn ixgbe_media_type_unknown;\n+\t\t}\n+\n+\t\t/* Check if there is some bit set in phy_type_high */\n+\t\tfor (i = 64; i > 0; i--) {\n+\t\t\tphy_mask = (u64)((u64)1 << (i - 1));\n+\t\t\tif ((pcaps.phy_type_high & phy_mask) != 0) {\n+\t\t\t\t/* If any bit is set treat it as PHY type */\n+\t\t\t\thw->link.link_info.phy_type_high = phy_mask;\n+\t\t\t\thw->link.link_info.phy_type_low = 0;\n+\t\t\t\tbreak;\n+\t\t\t}\n+\t\t\tphy_mask = 0;\n+\t\t}\n+\n+\t\t/* If nothing found in phy_type_high search in phy_type_low */\n+\t\tif (phy_mask == 0) {\n+\t\t\tfor (i = 64; i > 0; i--) {\n+\t\t\t\tphy_mask = (u64)((u64)1 << (i - 1));\n+\t\t\t\tif ((pcaps.phy_type_low & phy_mask) != 0) {\n+\t\t\t\t\t/* If any bit is set treat it as PHY type */\n+\t\t\t\t\thw->link.link_info.phy_type_high = 0;\n+\t\t\t\t\thw->link.link_info.phy_type_low = phy_mask;\n+\t\t\t\t\tbreak;\n+\t\t\t\t}\n+\t\t\t}\n+\t\t}\n+\n+\t\t/* Based on search above try to discover media type */\n+\t\thw->phy.media_type = ixgbe_get_media_type_from_phy_type(hw);\n+\t}\n+\n+\treturn hw->phy.media_type;\n+}\n+\n+/**\n+ * ixgbe_setup_link_E610 - Set up link\n+ * @hw: pointer to hardware structure\n+ * @speed: new link speed\n+ * @autoneg_wait: true when waiting for completion is needed\n+ *\n+ * Set up the link with the specified speed.\n+ *\n+ * Return: the exit code of the operation.\n+ */\n+s32 ixgbe_setup_link_E610(struct ixgbe_hw *hw, ixgbe_link_speed speed,\n+\t\t\t  bool autoneg_wait)\n+{\n+\n+\t/* Simply request FW to perform proper PHY setup */\n+\treturn hw->phy.ops.setup_link_speed(hw, speed, autoneg_wait);\n+}\n+\n+/**\n+ * ixgbe_check_link_E610 - 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+ * Determine if the link is up and the current link speed\n+ * using ACI command (0x0607).\n+ *\n+ * Return: the exit code of the operation.\n+ */\n+s32 ixgbe_check_link_E610(struct ixgbe_hw *hw, ixgbe_link_speed *speed,\n+\t\t\t  bool *link_up, bool link_up_wait_to_complete)\n+{\n+\ts32 rc;\n+\tu32 i;\n+\n+\tif (!speed || !link_up)\n+\t\treturn IXGBE_ERR_PARAM;\n+\n+\t/* Set get_link_info flag to ensure that fresh\n+\t * link information will be obtained from FW\n+\t * by sending Get Link Status admin command. */\n+\thw->link.get_link_info = true;\n+\n+\t/* Update link information in adapter context. */\n+\trc = ixgbe_get_link_status(hw, link_up);\n+\tif (rc)\n+\t\treturn rc;\n+\n+\t/* Wait for link up if it was requested. */\n+\tif (link_up_wait_to_complete && *link_up == false) {\n+\t\tfor (i = 0; i < hw->mac.max_link_up_time; i++) {\n+\t\t\tmsec_delay(100);\n+\t\t\thw->link.get_link_info = true;\n+\t\t\trc = ixgbe_get_link_status(hw, link_up);\n+\t\t\tif (rc)\n+\t\t\t\treturn rc;\n+\t\t\tif (*link_up)\n+\t\t\t\tbreak;\n+\t\t}\n+\t}\n+\n+\t/* Use link information in adapter context updated by the call\n+\t * to ixgbe_get_link_status() to determine current link speed.\n+\t * Link speed information is valid only when link up was\n+\t * reported by FW. */\n+\tif (*link_up) {\n+\t\tswitch (hw->link.link_info.link_speed) {\n+\t\tcase IXGBE_ACI_LINK_SPEED_10MB:\n+\t\t\t*speed = IXGBE_LINK_SPEED_10_FULL;\n+\t\t\tbreak;\n+\t\tcase IXGBE_ACI_LINK_SPEED_100MB:\n+\t\t\t*speed = IXGBE_LINK_SPEED_100_FULL;\n+\t\t\tbreak;\n+\t\tcase IXGBE_ACI_LINK_SPEED_1000MB:\n+\t\t\t*speed = IXGBE_LINK_SPEED_1GB_FULL;\n+\t\t\tbreak;\n+\t\tcase IXGBE_ACI_LINK_SPEED_2500MB:\n+\t\t\t*speed = IXGBE_LINK_SPEED_2_5GB_FULL;\n+\t\t\tbreak;\n+\t\tcase IXGBE_ACI_LINK_SPEED_5GB:\n+\t\t\t*speed = IXGBE_LINK_SPEED_5GB_FULL;\n+\t\t\tbreak;\n+\t\tcase IXGBE_ACI_LINK_SPEED_10GB:\n+\t\t\t*speed = IXGBE_LINK_SPEED_10GB_FULL;\n+\t\t\tbreak;\n+\t\tdefault:\n+\t\t\t*speed = IXGBE_LINK_SPEED_UNKNOWN;\n+\t\t\tbreak;\n+\t\t}\n+\t} else {\n+\t\t*speed = IXGBE_LINK_SPEED_UNKNOWN;\n+\t}\n+\n+\treturn IXGBE_SUCCESS;\n+}\n+\n+/**\n+ * ixgbe_get_link_capabilities_E610 - Determine 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+ * Determine speed and AN parameters of a link.\n+ *\n+ * Return: the exit code of the operation.\n+ */\n+s32 ixgbe_get_link_capabilities_E610(struct ixgbe_hw *hw,\n+\t\t\t\t     ixgbe_link_speed *speed,\n+\t\t\t\t     bool *autoneg)\n+{\n+\n+\tif (!speed || !autoneg)\n+\t\treturn IXGBE_ERR_PARAM;\n+\n+\t*autoneg = true;\n+\t*speed = hw->phy.speeds_supported;\n+\n+\treturn IXGBE_SUCCESS;\n+}\n+\n+/**\n+ * ixgbe_cfg_phy_fc - Configure PHY Flow Control (FC) data based on FC mode\n+ * @hw: pointer to hardware structure\n+ * @cfg: PHY configuration data to set FC mode\n+ * @req_mode: FC mode to configure\n+ *\n+ * Configures PHY Flow Control according to the provided configuration.\n+ *\n+ * Return: the exit code of the operation.\n+ */\n+s32 ixgbe_cfg_phy_fc(struct ixgbe_hw *hw,\n+\t\t     struct ixgbe_aci_cmd_set_phy_cfg_data *cfg,\n+\t\t     enum ixgbe_fc_mode req_mode)\n+{\n+\tstruct ixgbe_aci_cmd_get_phy_caps_data* pcaps = NULL;\n+\ts32 status = IXGBE_SUCCESS;\n+\tu8 pause_mask = 0x0;\n+\n+\tif (!cfg)\n+\t\treturn IXGBE_ERR_PARAM;\n+\n+\tswitch (req_mode) {\n+\tcase ixgbe_fc_auto:\n+\t{\n+\t\tpcaps = (struct ixgbe_aci_cmd_get_phy_caps_data *)\n+\t\t\tixgbe_malloc(hw, sizeof(*pcaps));\n+\t\tif (!pcaps) {\n+\t\t\tstatus = IXGBE_ERR_OUT_OF_MEM;\n+\t\t\tgoto out;\n+\t\t}\n+\n+\t\t/* Query the value of FC that both the NIC and the attached\n+\t\t * media can do. */\n+\t\tstatus = ixgbe_aci_get_phy_caps(hw, false,\n+\t\t\tIXGBE_ACI_REPORT_TOPO_CAP_MEDIA, pcaps);\n+\t\tif (status)\n+\t\t\tgoto out;\n+\n+\t\tpause_mask |= pcaps->caps & IXGBE_ACI_PHY_EN_TX_LINK_PAUSE;\n+\t\tpause_mask |= pcaps->caps & IXGBE_ACI_PHY_EN_RX_LINK_PAUSE;\n+\n+\t\tbreak;\n+\t}\n+\tcase ixgbe_fc_full:\n+\t\tpause_mask |= IXGBE_ACI_PHY_EN_TX_LINK_PAUSE;\n+\t\tpause_mask |= IXGBE_ACI_PHY_EN_RX_LINK_PAUSE;\n+\t\tbreak;\n+\tcase ixgbe_fc_rx_pause:\n+\t\tpause_mask |= IXGBE_ACI_PHY_EN_RX_LINK_PAUSE;\n+\t\tbreak;\n+\tcase ixgbe_fc_tx_pause:\n+\t\tpause_mask |= IXGBE_ACI_PHY_EN_TX_LINK_PAUSE;\n+\t\tbreak;\n+\tdefault:\n+\t\tbreak;\n+\t}\n+\n+\t/* clear the old pause settings */\n+\tcfg->caps &= ~(IXGBE_ACI_PHY_EN_TX_LINK_PAUSE |\n+\t\tIXGBE_ACI_PHY_EN_RX_LINK_PAUSE);\n+\n+\t/* set the new capabilities */\n+\tcfg->caps |= pause_mask;\n+\n+out:\n+\tif (pcaps)\n+\t\tixgbe_free(hw, pcaps);\n+\treturn status;\n+}\n+\n+/**\n+ * ixgbe_setup_fc_E610 - Set up flow control\n+ * @hw: pointer to hardware structure\n+ *\n+ * Set up flow control. This has to be done during init time.\n+ *\n+ * Return: the exit code of the operation.\n+ */\n+s32 ixgbe_setup_fc_E610(struct ixgbe_hw *hw)\n+{\n+\tstruct ixgbe_aci_cmd_get_phy_caps_data pcaps = { 0 };\n+\tstruct ixgbe_aci_cmd_set_phy_cfg_data cfg = { 0 };\n+\ts32 status;\n+\n+\t/* Get the current PHY config */\n+\tstatus = ixgbe_aci_get_phy_caps(hw, false,\n+\t\tIXGBE_ACI_REPORT_ACTIVE_CFG, &pcaps);\n+\tif (status)\n+\t\treturn status;\n+\n+\tixgbe_copy_phy_caps_to_cfg(&pcaps, &cfg);\n+\n+\t/* Configure the set PHY data */\n+\tstatus = ixgbe_cfg_phy_fc(hw, &cfg, hw->fc.requested_mode);\n+\tif (status)\n+\t\treturn status;\n+\n+\t/* If the capabilities have changed, then set the new config */\n+\tif (cfg.caps != pcaps.caps) {\n+\t\tcfg.caps |= IXGBE_ACI_PHY_ENA_AUTO_LINK_UPDT;\n+\n+\t\tstatus = ixgbe_aci_set_phy_cfg(hw, &cfg);\n+\t\tif (status)\n+\t\t\treturn status;\n+\t}\n+\n+\treturn status;\n+}\n+\n+/**\n+ * ixgbe_fc_autoneg_E610 - Configure flow control\n+ * @hw: pointer to hardware structure\n+ *\n+ * Configure Flow Control.\n+ */\n+void ixgbe_fc_autoneg_E610(struct ixgbe_hw *hw)\n+{\n+\ts32 status;\n+\n+\t/* Get current link status.\n+\t * Current FC mode will be stored in the hw context. */\n+\tstatus = ixgbe_aci_get_link_info(hw, false, NULL);\n+\tif (status) {\n+\t\tgoto out;\n+\t}\n+\n+\t/* Check if the link is up */\n+\tif (!(hw->link.link_info.link_info & IXGBE_ACI_LINK_UP)) {\n+\t\tstatus = IXGBE_ERR_FC_NOT_NEGOTIATED;\n+\t\tgoto out;\n+\t}\n+\n+\t/* Check if auto-negotiation has completed */\n+\tif (!(hw->link.link_info.an_info & IXGBE_ACI_AN_COMPLETED)) {\n+\t\tstatus = IXGBE_ERR_FC_NOT_NEGOTIATED;\n+\t\tgoto out;\n+\t}\n+\n+out:\n+\tif (status == IXGBE_SUCCESS) {\n+\t\thw->fc.fc_was_autonegged = true;\n+\t} else {\n+\t\thw->fc.fc_was_autonegged = false;\n+\t\thw->fc.current_mode = hw->fc.requested_mode;\n+\t}\n+}\n+\n+/**\n+ * ixgbe_disable_rx_E610 - Disable RX unit\n+ * @hw: pointer to hardware structure\n+ *\n+ * Disable RX DMA unit on E610 with use of ACI command (0x000C).\n+ *\n+ * Return: the exit code of the operation.\n+ */\n+void ixgbe_disable_rx_E610(struct ixgbe_hw *hw)\n+{\n+\tu32 rxctrl;\n+\n+\tDEBUGFUNC(\"ixgbe_disable_rx_E610\");\n+\n+\trxctrl = IXGBE_READ_REG(hw, IXGBE_RXCTRL);\n+\tif (rxctrl & IXGBE_RXCTRL_RXEN) {\n+\t\tu32 pfdtxgswc;\n+\t\ts32 status;\n+\n+\t\tpfdtxgswc = IXGBE_READ_REG(hw, IXGBE_PFDTXGSWC);\n+\t\tif (pfdtxgswc & IXGBE_PFDTXGSWC_VT_LBEN) {\n+\t\t\tpfdtxgswc &= ~IXGBE_PFDTXGSWC_VT_LBEN;\n+\t\t\tIXGBE_WRITE_REG(hw, IXGBE_PFDTXGSWC, pfdtxgswc);\n+\t\t\thw->mac.set_lben = true;\n+\t\t} else {\n+\t\t\thw->mac.set_lben = false;\n+\t\t}\n+\n+\t\tstatus = ixgbe_aci_disable_rxen(hw);\n+\n+\t\t/* If we fail - disable RX using register write */\n+\t\tif (status) {\n+\t\t\trxctrl = IXGBE_READ_REG(hw, IXGBE_RXCTRL);\n+\t\t\tif (rxctrl & IXGBE_RXCTRL_RXEN) {\n+\t\t\t\trxctrl &= ~IXGBE_RXCTRL_RXEN;\n+\t\t\t\tIXGBE_WRITE_REG(hw, IXGBE_RXCTRL, rxctrl);\n+\t\t\t}\n+\t\t}\n+\t}\n+}\n+\n+/**\n+ * ixgbe_init_phy_ops_E610 - PHY specific init\n+ * @hw: pointer to hardware structure\n+ *\n+ * Initialize any function pointers that were not able to be\n+ * set during init_shared_code because the PHY type was not known.\n+ *\n+ * Return: the exit code of the operation.\n+ */\n+s32 ixgbe_init_phy_ops_E610(struct ixgbe_hw *hw)\n+{\n+\tstruct ixgbe_mac_info *mac = &hw->mac;\n+\tstruct ixgbe_phy_info *phy = &hw->phy;\n+\ts32 ret_val;\n+\n+\tphy->ops.identify_sfp = ixgbe_identify_module_E610;\n+\tphy->ops.read_reg = NULL; /* PHY reg access is not required */\n+\tphy->ops.write_reg = NULL;\n+\tphy->ops.read_reg_mdi = NULL;\n+\tphy->ops.write_reg_mdi = NULL;\n+\tphy->ops.setup_link = ixgbe_setup_phy_link_E610;\n+\tphy->ops.get_firmware_version = ixgbe_get_phy_firmware_version_E610;\n+\tphy->ops.read_i2c_byte = NULL; /* disabled for E610 */\n+\tphy->ops.write_i2c_byte = NULL; /* disabled for E610 */\n+\tphy->ops.read_i2c_sff8472 = ixgbe_read_i2c_sff8472_E610;\n+\tphy->ops.read_i2c_eeprom = ixgbe_read_i2c_eeprom_E610;\n+\tphy->ops.write_i2c_eeprom = ixgbe_write_i2c_eeprom_E610;\n+\tphy->ops.i2c_bus_clear = NULL; /* do not use generic implementation  */\n+\tphy->ops.check_overtemp = ixgbe_check_overtemp_E610;\n+\tif (mac->ops.get_media_type(hw) == ixgbe_media_type_copper)\n+\t\tphy->ops.set_phy_power = ixgbe_set_phy_power_E610;\n+\telse\n+\t\tphy->ops.set_phy_power = NULL;\n+\tphy->ops.enter_lplu = ixgbe_enter_lplu_E610;\n+\tphy->ops.handle_lasi = NULL; /* no implementation for E610 */\n+\tphy->ops.read_i2c_byte_unlocked = NULL; /* disabled for E610 */\n+\tphy->ops.write_i2c_byte_unlocked = NULL; /* disabled for E610 */\n+\n+\t/* TODO: Set functions pointers based on device ID */\n+\n+\t/* Identify the PHY */\n+\tret_val = phy->ops.identify(hw);\n+\tif (ret_val != IXGBE_SUCCESS)\n+\t\treturn ret_val;\n+\n+\t/* TODO: Set functions pointers based on PHY type */\n+\n+\treturn ret_val;\n+}\n+\n+/**\n+ * ixgbe_identify_phy_E610 - Identify PHY\n+ * @hw: pointer to hardware structure\n+ * \n+ * Determine PHY type, supported speeds and PHY ID.\n+ *\n+ * Return: the exit code of the operation.\n+ */\n+s32 ixgbe_identify_phy_E610(struct ixgbe_hw *hw)\n+{\n+\tstruct ixgbe_aci_cmd_get_phy_caps_data pcaps;\n+\ts32 rc;\n+\n+\t/* Set PHY type */\n+\thw->phy.type = ixgbe_phy_fw;\n+\n+\trc = ixgbe_aci_get_phy_caps(hw, false, IXGBE_ACI_REPORT_TOPO_CAP_MEDIA,\n+\t\t\t\t    &pcaps);\n+\tif (rc)\n+\t\treturn rc;\n+\n+\tif (!(pcaps.module_compliance_enforcement &\n+\t      IXGBE_ACI_MOD_ENFORCE_STRICT_MODE)) {\n+\t\t/* Handle lenient mode */\n+\t\trc = ixgbe_aci_get_phy_caps(hw, false,\n+\t\t\t\t\t    IXGBE_ACI_REPORT_TOPO_CAP_NO_MEDIA,\n+\t\t\t\t\t    &pcaps);\n+\t\tif (rc)\n+\t\t\treturn rc;\n+\t}\n+\n+\t/* Determine supported speeds */\n+\thw->phy.speeds_supported = IXGBE_LINK_SPEED_UNKNOWN;\n+\n+\tif (pcaps.phy_type_high & IXGBE_PHY_TYPE_HIGH_10BASE_T ||\n+\t    pcaps.phy_type_high & IXGBE_PHY_TYPE_HIGH_10M_SGMII)\n+\t\thw->phy.speeds_supported |= IXGBE_LINK_SPEED_10_FULL;\n+\tif (pcaps.phy_type_low  & IXGBE_PHY_TYPE_LOW_100BASE_TX ||\n+\t    pcaps.phy_type_low  & IXGBE_PHY_TYPE_LOW_100M_SGMII ||\n+\t    pcaps.phy_type_high & IXGBE_PHY_TYPE_HIGH_100M_USXGMII)\n+\t\thw->phy.speeds_supported |= IXGBE_LINK_SPEED_100_FULL;\n+\tif (pcaps.phy_type_low  & IXGBE_PHY_TYPE_LOW_1000BASE_T  ||\n+\t    pcaps.phy_type_low  & IXGBE_PHY_TYPE_LOW_1000BASE_SX ||\n+\t    pcaps.phy_type_low  & IXGBE_PHY_TYPE_LOW_1000BASE_LX ||\n+\t    pcaps.phy_type_low  & IXGBE_PHY_TYPE_LOW_1000BASE_KX ||\n+\t    pcaps.phy_type_low  & IXGBE_PHY_TYPE_LOW_1G_SGMII    ||\n+\t    pcaps.phy_type_high & IXGBE_PHY_TYPE_HIGH_1G_USXGMII)\n+\t\thw->phy.speeds_supported |= IXGBE_LINK_SPEED_1GB_FULL;\n+\tif (pcaps.phy_type_low  & IXGBE_PHY_TYPE_LOW_2500BASE_T   ||\n+\t    pcaps.phy_type_low  & IXGBE_PHY_TYPE_LOW_2500BASE_X   ||\n+\t    pcaps.phy_type_low  & IXGBE_PHY_TYPE_LOW_2500BASE_KX  ||\n+\t    pcaps.phy_type_high & IXGBE_PHY_TYPE_HIGH_2500M_SGMII ||\n+\t    pcaps.phy_type_high & IXGBE_PHY_TYPE_HIGH_2500M_USXGMII)\n+\t\thw->phy.speeds_supported |= IXGBE_LINK_SPEED_2_5GB_FULL;\n+\tif (pcaps.phy_type_low  & IXGBE_PHY_TYPE_LOW_5GBASE_T  ||\n+\t    pcaps.phy_type_low  & IXGBE_PHY_TYPE_LOW_5GBASE_KR ||\n+\t    pcaps.phy_type_high & IXGBE_PHY_TYPE_HIGH_5G_USXGMII)\n+\t\thw->phy.speeds_supported |= IXGBE_LINK_SPEED_5GB_FULL;\n+\tif (pcaps.phy_type_low  & IXGBE_PHY_TYPE_LOW_10GBASE_T       ||\n+\t    pcaps.phy_type_low  & IXGBE_PHY_TYPE_LOW_10G_SFI_DA      ||\n+\t    pcaps.phy_type_low  & IXGBE_PHY_TYPE_LOW_10GBASE_SR      ||\n+\t    pcaps.phy_type_low  & IXGBE_PHY_TYPE_LOW_10GBASE_LR      ||\n+\t    pcaps.phy_type_low  & IXGBE_PHY_TYPE_LOW_10GBASE_KR_CR1  ||\n+\t    pcaps.phy_type_low  & IXGBE_PHY_TYPE_LOW_10G_SFI_AOC_ACC ||\n+\t    pcaps.phy_type_low  & IXGBE_PHY_TYPE_LOW_10G_SFI_C2C     ||\n+\t    pcaps.phy_type_high & IXGBE_PHY_TYPE_HIGH_10G_USXGMII)\n+\t\thw->phy.speeds_supported |= IXGBE_LINK_SPEED_10GB_FULL;\n+\n+\t/* Initialize autoneg speeds */\n+\tif (!hw->phy.autoneg_advertised)\n+\t\thw->phy.autoneg_advertised = hw->phy.speeds_supported;\n+\n+\t/* Set PHY ID */\n+\tmemcpy(&hw->phy.id, pcaps.phy_id_oui, sizeof(u32));\n+\n+\treturn IXGBE_SUCCESS;\n+}\n+\n+/**\n+ * ixgbe_identify_module_E610 - Identify SFP module type\n+ * @hw: pointer to hardware structure\n+ *\n+ * Identify the SFP module type.\n+ *\n+ * Return: the exit code of the operation.\n+ */\n+s32 ixgbe_identify_module_E610(struct ixgbe_hw *hw)\n+{\n+\tbool media_available;\n+\tu8 module_type;\n+\ts32 rc;\n+\n+\trc = ixgbe_update_link_info(hw);\n+\tif (rc)\n+\t\tgoto err;\n+\n+\tmedia_available =\n+\t\t(hw->link.link_info.link_info &\n+\t\t IXGBE_ACI_MEDIA_AVAILABLE) ? true : false;\n+\n+\tif (media_available) {\n+\t\thw->phy.sfp_type = ixgbe_sfp_type_unknown;\n+\n+\t\t/* Get module type from hw context updated by ixgbe_update_link_info() */\n+\t\tmodule_type = hw->link.link_info.module_type[IXGBE_ACI_MOD_TYPE_IDENT];\n+\n+\t\tif ((module_type & IXGBE_ACI_MOD_TYPE_BYTE1_SFP_PLUS_CU_PASSIVE) ||\n+\t\t    (module_type & IXGBE_ACI_MOD_TYPE_BYTE1_SFP_PLUS_CU_ACTIVE)) {\n+\t\t\thw->phy.sfp_type = ixgbe_sfp_type_da_cu;\n+\t\t} else if (module_type & IXGBE_ACI_MOD_TYPE_BYTE1_10G_BASE_SR) {\n+\t\t\thw->phy.sfp_type = ixgbe_sfp_type_sr;\n+\t\t} else if ((module_type & IXGBE_ACI_MOD_TYPE_BYTE1_10G_BASE_LR) ||\n+\t\t\t   (module_type & IXGBE_ACI_MOD_TYPE_BYTE1_10G_BASE_LRM)) {\n+\t\t\thw->phy.sfp_type = ixgbe_sfp_type_lr;\n+\t\t}\n+\t\trc = IXGBE_SUCCESS;\n+\t} else {\n+\t\thw->phy.sfp_type = ixgbe_sfp_type_not_present;\n+\t\trc = IXGBE_ERR_SFP_NOT_PRESENT;\n+\t}\n+err:\n+\treturn rc;\n+}\n+\n+/**\n+ * ixgbe_setup_phy_link_E610 - Sets up firmware-controlled PHYs\n+ * @hw: pointer to hardware structure\n+ *\n+ * Set the parameters for the firmware-controlled PHYs.\n+ *\n+ * Return: the exit code of the operation.\n+ */\n+s32 ixgbe_setup_phy_link_E610(struct ixgbe_hw *hw)\n+{\n+\tstruct ixgbe_aci_cmd_get_phy_caps_data pcaps;\n+\tstruct ixgbe_aci_cmd_set_phy_cfg_data pcfg;\n+\tu8 rmode = IXGBE_ACI_REPORT_ACTIVE_CFG;\n+\ts32 rc;\n+\n+\trc = ixgbe_aci_get_link_info(hw, false, NULL);\n+\tif (rc) {\n+\t\tgoto err;\n+\t}\n+\n+\t/* If media is not available get default config */\n+\tif (!(hw->link.link_info.link_info & IXGBE_ACI_MEDIA_AVAILABLE))\n+\t\trmode = IXGBE_ACI_REPORT_DFLT_CFG;\n+\n+\trc = ixgbe_aci_get_phy_caps(hw, false, rmode, &pcaps);\n+\tif (rc) {\n+\t\tgoto err;\n+\t}\n+\n+\tixgbe_copy_phy_caps_to_cfg(&pcaps, &pcfg);\n+\n+\t/* Set default PHY types for a given speed */\n+\tpcfg.phy_type_low = 0;\n+\tpcfg.phy_type_high = 0;\n+\n+\tif (hw->phy.autoneg_advertised & IXGBE_LINK_SPEED_10_FULL) {\n+\t\tpcfg.phy_type_high |= IXGBE_PHY_TYPE_HIGH_10BASE_T;\n+\t\tpcfg.phy_type_high |= IXGBE_PHY_TYPE_HIGH_10M_SGMII;\n+\t}\n+\tif (hw->phy.autoneg_advertised & IXGBE_LINK_SPEED_100_FULL) {\n+\t\tpcfg.phy_type_low  |= IXGBE_PHY_TYPE_LOW_100BASE_TX;\n+\t\tpcfg.phy_type_low  |= IXGBE_PHY_TYPE_LOW_100M_SGMII;\n+\t\tpcfg.phy_type_high |= IXGBE_PHY_TYPE_HIGH_100M_USXGMII;\n+\t}\n+\tif (hw->phy.autoneg_advertised & IXGBE_LINK_SPEED_1GB_FULL) {\n+\t\tpcfg.phy_type_low  |= IXGBE_PHY_TYPE_LOW_1000BASE_T;\n+\t\tpcfg.phy_type_low  |= IXGBE_PHY_TYPE_LOW_1000BASE_SX;\n+\t\tpcfg.phy_type_low  |= IXGBE_PHY_TYPE_LOW_1000BASE_LX;\n+\t\tpcfg.phy_type_low  |= IXGBE_PHY_TYPE_LOW_1000BASE_KX;\n+\t\tpcfg.phy_type_low  |= IXGBE_PHY_TYPE_LOW_1G_SGMII;\n+\t\tpcfg.phy_type_high |= IXGBE_PHY_TYPE_HIGH_1G_USXGMII;\n+\t}\n+\tif (hw->phy.autoneg_advertised & IXGBE_LINK_SPEED_2_5GB_FULL) {\n+\t\tpcfg.phy_type_low  |= IXGBE_PHY_TYPE_LOW_2500BASE_T;\n+\t\tpcfg.phy_type_low  |= IXGBE_PHY_TYPE_LOW_2500BASE_X;\n+\t\tpcfg.phy_type_low  |= IXGBE_PHY_TYPE_LOW_2500BASE_KX;\n+\t\tpcfg.phy_type_high |= IXGBE_PHY_TYPE_HIGH_2500M_SGMII;\n+\t\tpcfg.phy_type_high |= IXGBE_PHY_TYPE_HIGH_2500M_USXGMII;\n+\t}\n+\tif (hw->phy.autoneg_advertised & IXGBE_LINK_SPEED_5GB_FULL) {\n+\t\tpcfg.phy_type_low  |= IXGBE_PHY_TYPE_LOW_5GBASE_T;\n+\t\tpcfg.phy_type_low  |= IXGBE_PHY_TYPE_LOW_5GBASE_KR;\n+\t\tpcfg.phy_type_high |= IXGBE_PHY_TYPE_HIGH_5G_USXGMII;\n+\t}\n+\tif (hw->phy.autoneg_advertised & IXGBE_LINK_SPEED_10GB_FULL) {\n+\t\tpcfg.phy_type_low  |= IXGBE_PHY_TYPE_LOW_10GBASE_T;\n+\t\tpcfg.phy_type_low  |= IXGBE_PHY_TYPE_LOW_10G_SFI_DA;\n+\t\tpcfg.phy_type_low  |= IXGBE_PHY_TYPE_LOW_10GBASE_SR;\n+\t\tpcfg.phy_type_low  |= IXGBE_PHY_TYPE_LOW_10GBASE_LR;\n+\t\tpcfg.phy_type_low  |= IXGBE_PHY_TYPE_LOW_10GBASE_KR_CR1;\n+\t\tpcfg.phy_type_low  |= IXGBE_PHY_TYPE_LOW_10G_SFI_AOC_ACC;\n+\t\tpcfg.phy_type_low  |= IXGBE_PHY_TYPE_LOW_10G_SFI_C2C;\n+\t\tpcfg.phy_type_high |= IXGBE_PHY_TYPE_HIGH_10G_USXGMII;\n+\t}\n+\n+\t/* Mask the set values to avoid requesting unsupported link types */\n+\tpcfg.phy_type_low &= pcaps.phy_type_low;\n+\tpcfg.phy_type_high &= pcaps.phy_type_high;\n+\n+\tif (pcfg.phy_type_high != pcaps.phy_type_high ||\n+\t    pcfg.phy_type_low != pcaps.phy_type_low ||\n+\t    pcfg.caps != pcaps.caps) {\n+\t\tpcfg.caps |= IXGBE_ACI_PHY_ENA_LINK;\n+\t\tpcfg.caps |= IXGBE_ACI_PHY_ENA_AUTO_LINK_UPDT;\n+\n+\t\trc = ixgbe_aci_set_phy_cfg(hw, &pcfg);\n+\t}\n+\n+err:\n+\treturn rc;\n+}\n+\n+/**\n+ * ixgbe_get_phy_firmware_version_E610 - Gets the PHY Firmware Version\n+ * @hw: pointer to hardware structure\n+ * @firmware_version: pointer to the PHY Firmware Version\n+ * \n+ * Determines PHY FW version based on response to Get PHY Capabilities\n+ * admin command (0x0600).\n+ *\n+ * Return: the exit code of the operation.\n+ */\n+s32 ixgbe_get_phy_firmware_version_E610(struct ixgbe_hw *hw,\n+\t\t\t\t\tu16 *firmware_version)\n+{\n+\tstruct ixgbe_aci_cmd_get_phy_caps_data pcaps;\n+\ts32 status;\n+\n+\tif (!firmware_version)\n+\t\treturn IXGBE_ERR_PARAM;\n+\n+\tstatus = ixgbe_aci_get_phy_caps(hw, false,\n+\t\t\t\t\tIXGBE_ACI_REPORT_ACTIVE_CFG,\n+\t\t\t\t\t&pcaps);\n+\tif (status)\n+\t\treturn status;\n+\n+\t/* TODO: determine which bytes of the 8-byte phy_fw_ver\n+\t * field should be written to the 2-byte firmware_version\n+\t * output argument. */\n+\tmemcpy(firmware_version, pcaps.phy_fw_ver, sizeof(u16));\n+\n+\treturn IXGBE_SUCCESS;\n+}\n+\n+/**\n+ * ixgbe_read_i2c_sff8472_E610 - Reads 8 bit word over I2C interface\n+ * @hw: pointer to hardware structure\n+ * @byte_offset: byte offset at address 0xA2\n+ * @sff8472_data: value read\n+ *\n+ * Performs byte read operation from SFP module's SFF-8472 data over I2C.\n+ *\n+ * Return: the exit code of the operation.\n+ **/\n+s32 ixgbe_read_i2c_sff8472_E610(struct ixgbe_hw *hw, u8 byte_offset,\n+\t\t\t\tu8 *sff8472_data)\n+{\n+\treturn ixgbe_aci_sff_eeprom(hw, 0, IXGBE_I2C_EEPROM_DEV_ADDR2,\n+\t\t\t\t    byte_offset, 0,\n+\t\t\t\t    IXGBE_ACI_SFF_NO_PAGE_BANK_UPDATE,\n+\t\t\t\t    sff8472_data, 1, false);\n+}\n+\n+/**\n+ * ixgbe_read_i2c_eeprom_E610 - Reads 8 bit EEPROM word over I2C interface\n+ * @hw: pointer to hardware structure\n+ * @byte_offset: EEPROM byte offset to read\n+ * @eeprom_data: value read\n+ *\n+ * Performs byte read operation from SFP module's EEPROM over I2C interface.\n+ *\n+ * Return: the exit code of the operation.\n+ **/\n+s32 ixgbe_read_i2c_eeprom_E610(struct ixgbe_hw *hw, u8 byte_offset,\n+\t\t\t       u8 *eeprom_data)\n+{\n+\treturn ixgbe_aci_sff_eeprom(hw, 0, IXGBE_I2C_EEPROM_DEV_ADDR,\n+\t\t\t\t    byte_offset, 0,\n+\t\t\t\t    IXGBE_ACI_SFF_NO_PAGE_BANK_UPDATE,\n+\t\t\t\t    eeprom_data, 1, false);\n+}\n+\n+/**\n+ * ixgbe_write_i2c_eeprom_E610 - Writes 8 bit EEPROM word over I2C interface\n+ * @hw: pointer to hardware structure\n+ * @byte_offset: EEPROM byte offset to write\n+ * @eeprom_data: value to write\n+ *\n+ * Performs byte write operation to SFP module's EEPROM over I2C interface.\n+ *\n+ * Return: the exit code of the operation.\n+ **/\n+s32 ixgbe_write_i2c_eeprom_E610(struct ixgbe_hw *hw, u8 byte_offset,\n+\t\t\t\tu8 eeprom_data)\n+{\n+\treturn ixgbe_aci_sff_eeprom(hw, 0, IXGBE_I2C_EEPROM_DEV_ADDR,\n+\t\t\t\t    byte_offset, 0,\n+\t\t\t\t    IXGBE_ACI_SFF_NO_PAGE_BANK_UPDATE,\n+\t\t\t\t    &eeprom_data, 1, true);\n+}\n+\n+/**\n+ * ixgbe_check_overtemp_E610 - Check firmware-controlled PHYs for overtemp\n+ * @hw: pointer to hardware structure\n+ *\n+ * Get the link status and check if the PHY temperature alarm detected.\n+ *\n+ * Return: the exit code of the operation.\n+ */\n+s32 ixgbe_check_overtemp_E610(struct ixgbe_hw *hw)\n+{\n+\tstruct ixgbe_aci_cmd_get_link_status_data link_data = { 0 };\n+\tstruct ixgbe_aci_cmd_get_link_status *resp;\n+\tstruct ixgbe_aci_desc desc;\n+\ts32 status = IXGBE_SUCCESS;\n+\n+\tif (!hw)\n+\t\treturn IXGBE_ERR_PARAM;\n+\n+\tixgbe_fill_dflt_direct_cmd_desc(&desc, ixgbe_aci_opc_get_link_status);\n+\tresp = &desc.params.get_link_status;\n+\tresp->cmd_flags = IXGBE_CPU_TO_LE16(IXGBE_ACI_LSE_NOP);\n+\n+\tstatus = ixgbe_aci_send_cmd(hw, &desc, &link_data, sizeof(link_data));\n+\tif (status != IXGBE_SUCCESS)\n+\t\treturn status;\n+\n+\tif (link_data.ext_info & IXGBE_ACI_LINK_PHY_TEMP_ALARM) {\n+\t\tERROR_REPORT1(IXGBE_ERROR_CAUTION,\n+\t\t\t      \"PHY Temperature Alarm detected\");\n+\t\tstatus = IXGBE_ERR_OVERTEMP;\n+\t}\n+\n+\treturn status;\n+}\n+\n+/**\n+ * ixgbe_set_phy_power_E610 - Control power for copper PHY\n+ * @hw: pointer to hardware structure\n+ * @on: true for on, false for off\n+ *\n+ * Set the power on/off of the PHY\n+ * by getting its capabilities and setting the appropriate\n+ * configuration parameters.\n+ *\n+ * Return: the exit code of the operation.\n+ */\n+s32 ixgbe_set_phy_power_E610(struct ixgbe_hw *hw, bool on)\n+{\n+\tstruct ixgbe_aci_cmd_get_phy_caps_data phy_caps = { 0 };\n+\tstruct ixgbe_aci_cmd_set_phy_cfg_data phy_cfg = { 0 };\n+\ts32 status;\n+\n+\tstatus = ixgbe_aci_get_phy_caps(hw, false,\n+\t\tIXGBE_ACI_REPORT_ACTIVE_CFG, &phy_caps);\n+\tif (status != IXGBE_SUCCESS)\n+\t\treturn status;\n+\n+\tixgbe_copy_phy_caps_to_cfg(&phy_caps, &phy_cfg);\n+\n+\tif (on) {\n+\t\tphy_cfg.caps &= ~IXGBE_ACI_PHY_ENA_LOW_POWER;\n+\t} else {\n+\t\tphy_cfg.caps |= IXGBE_ACI_PHY_ENA_LOW_POWER;\n+\t}\n+\n+\t/* PHY is already in requested power mode */\n+\tif (phy_caps.caps == phy_cfg.caps)\n+\t\treturn IXGBE_SUCCESS;\n+\n+\tphy_cfg.caps |= IXGBE_ACI_PHY_ENA_LINK;\n+\tphy_cfg.caps |= IXGBE_ACI_PHY_ENA_AUTO_LINK_UPDT;\n+\n+\tstatus = ixgbe_aci_set_phy_cfg(hw, &phy_cfg);\n+\n+\treturn status;\n+}\n+\n+/**\n+ * ixgbe_enter_lplu_E610 - Transition to low power states\n+ * @hw: pointer to hardware structure\n+ *\n+ * Configures Low Power Link Up on transition to low power states\n+ * (from D0 to non-D0). Link is required to enter LPLU so avoid resetting the\n+ * X557 PHY immediately prior to entering LPLU.\n+ *\n+ * Return: the exit code of the operation.\n+ */\n+s32 ixgbe_enter_lplu_E610(struct ixgbe_hw *hw)\n+{\n+\tstruct ixgbe_aci_cmd_get_phy_caps_data phy_caps = { 0 };\n+\tstruct ixgbe_aci_cmd_set_phy_cfg_data phy_cfg = { 0 };\n+\ts32 status;\n+\n+\tstatus = ixgbe_aci_get_phy_caps(hw, false,\n+\t\tIXGBE_ACI_REPORT_ACTIVE_CFG, &phy_caps);\n+\tif (status != IXGBE_SUCCESS)\n+\t\treturn status;\n+\n+\tixgbe_copy_phy_caps_to_cfg(&phy_caps, &phy_cfg);\n+\n+\tphy_cfg.low_power_ctrl_an |= IXGBE_ACI_PHY_EN_D3COLD_LOW_POWER_AUTONEG;\n+\n+\tstatus = ixgbe_aci_set_phy_cfg(hw, &phy_cfg);\n+\n+\treturn status;\n+}\ndiff --git a/drivers/net/ixgbe/base/ixgbe_e610.h b/drivers/net/ixgbe/base/ixgbe_e610.h\nindex 5f78f970c4..7327d92239 100644\n--- a/drivers/net/ixgbe/base/ixgbe_e610.h\n+++ b/drivers/net/ixgbe/base/ixgbe_e610.h\n@@ -33,5 +33,49 @@ s32 ixgbe_aci_get_phy_caps(struct ixgbe_hw *hw, bool qual_mods, u8 report_mode,\n \t\t\t   struct ixgbe_aci_cmd_get_phy_caps_data *pcaps);\n void ixgbe_copy_phy_caps_to_cfg(struct ixgbe_aci_cmd_get_phy_caps_data *caps,\n \t\t\t\tstruct ixgbe_aci_cmd_set_phy_cfg_data *cfg);\n+s32 ixgbe_aci_set_phy_cfg(struct ixgbe_hw *hw,\n+\t\t\t  struct ixgbe_aci_cmd_set_phy_cfg_data *cfg);\n+s32 ixgbe_aci_set_link_restart_an(struct ixgbe_hw *hw, bool ena_link);\n+s32 ixgbe_update_link_info(struct ixgbe_hw *hw);\n+s32 ixgbe_get_link_status(struct ixgbe_hw *hw, bool *link_up);\n+s32 ixgbe_aci_get_link_info(struct ixgbe_hw *hw, bool ena_lse,\n+\t\t\t    struct ixgbe_link_status *link);\n+s32 ixgbe_aci_set_event_mask(struct ixgbe_hw *hw, u8 port_num, u16 mask);\n+s32 ixgbe_configure_lse(struct ixgbe_hw *hw, bool activate, u16 mask);\n+s32 ixgbe_aci_sff_eeprom(struct ixgbe_hw *hw, u16 lport, u8 bus_addr,\n+\t\t\t u16 mem_addr, u8 page, u8 page_bank_ctrl, u8 *data,\n+\t\t\t u8 length, bool write);\n+enum ixgbe_media_type ixgbe_get_media_type_E610(struct ixgbe_hw *hw);\n+s32 ixgbe_setup_link_E610(struct ixgbe_hw *hw, ixgbe_link_speed speed,\n+\t\t\t  bool autoneg_wait);\n+s32 ixgbe_check_link_E610(struct ixgbe_hw *hw, ixgbe_link_speed *speed,\n+\t\t\t  bool *link_up, bool link_up_wait_to_complete);\n+s32 ixgbe_get_link_capabilities_E610(struct ixgbe_hw *hw,\n+\t\t\t\t     ixgbe_link_speed *speed,\n+\t\t\t\t     bool *autoneg);\n+s32 ixgbe_cfg_phy_fc(struct ixgbe_hw *hw,\n+\t\t     struct ixgbe_aci_cmd_set_phy_cfg_data *cfg,\n+\t\t     enum ixgbe_fc_mode req_mode);\n+s32 ixgbe_setup_fc_E610(struct ixgbe_hw *hw);\n+void ixgbe_fc_autoneg_E610(struct ixgbe_hw *hw);\n+void ixgbe_disable_rx_E610(struct ixgbe_hw *hw);\n+s32 ixgbe_init_phy_ops_E610(struct ixgbe_hw *hw);\n+s32 ixgbe_identify_phy_E610(struct ixgbe_hw *hw);\n+s32 ixgbe_identify_module_E610(struct ixgbe_hw *hw);\n+s32 ixgbe_setup_phy_link_E610(struct ixgbe_hw *hw);\n+s32 ixgbe_get_phy_firmware_version_E610(struct ixgbe_hw *hw,\n+\t\t\t\t\tu16 *firmware_version);\n+s32 ixgbe_read_i2c_sff8472_E610(struct ixgbe_hw *hw, u8 byte_offset,\n+\t\t\t\tu8 *sff8472_data);\n+s32 ixgbe_read_i2c_eeprom_E610(struct ixgbe_hw *hw, u8 byte_offset,\n+\t\t\t       u8 *eeprom_data);\n+s32 ixgbe_write_i2c_eeprom_E610(struct ixgbe_hw *hw, u8 byte_offset,\n+\t\t\t\tu8 eeprom_data);\n+s32 ixgbe_check_overtemp_E610(struct ixgbe_hw *hw);\n+s32 ixgbe_set_phy_power_E610(struct ixgbe_hw *hw, bool on);\n+s32 ixgbe_enter_lplu_E610(struct ixgbe_hw *hw);\n+s32 ixgbe_aci_get_netlist_node(struct ixgbe_hw *hw,\n+\t\t\t       struct ixgbe_aci_cmd_get_link_topo *cmd,\n+\t\t\t       u8 *node_part_number, u16 *node_handle);\n \n #endif /* _IXGBE_E610_H_ */\n",
    "prefixes": [
        "v2",
        "24/27"
    ]
}