Patch Detail
get:
Show a patch.
patch:
Update a patch.
put:
Update a patch.
GET /api/patches/697456/?format=api
{ "id": 697456, "url": "http://patchwork.ozlabs.org/api/patches/697456/?format=api", "web_url": "http://patchwork.ozlabs.org/project/intel-wired-lan/patch/147977209408.28902.2664072497234838810.stgit@mdrustad-wks.jf.intel.com/", "project": { "id": 46, "url": "http://patchwork.ozlabs.org/api/projects/46/?format=api", "name": "Intel Wired Ethernet development", "link_name": "intel-wired-lan", "list_id": "intel-wired-lan.osuosl.org", "list_email": "intel-wired-lan@osuosl.org", "web_url": "", "scm_url": "", "webscm_url": "", "list_archive_url": "", "list_archive_url_format": "", "commit_url_format": "" }, "msgid": "<147977209408.28902.2664072497234838810.stgit@mdrustad-wks.jf.intel.com>", "list_archive_url": null, "date": "2016-11-21T23:48:14", "name": "[4/4] ixgbe: Implement support for firmware-controlled PHYs", "commit_ref": null, "pull_url": null, "state": "superseded", "archived": false, "hash": "f29c025bc4378e26dcf4003bdc68e7a52fb57e23", "submitter": { "id": 13252, "url": "http://patchwork.ozlabs.org/api/people/13252/?format=api", "name": "Rustad, Mark D", "email": "mark.d.rustad@intel.com" }, "delegate": { "id": 68, "url": "http://patchwork.ozlabs.org/api/users/68/?format=api", "username": "jtkirshe", "first_name": "Jeff", "last_name": "Kirsher", "email": "jeffrey.t.kirsher@intel.com" }, "mbox": "http://patchwork.ozlabs.org/project/intel-wired-lan/patch/147977209408.28902.2664072497234838810.stgit@mdrustad-wks.jf.intel.com/mbox/", "series": [], "comments": "http://patchwork.ozlabs.org/api/patches/697456/comments/", "check": "pending", "checks": "http://patchwork.ozlabs.org/api/patches/697456/checks/", "tags": {}, "related": [], "headers": { "Return-Path": "<intel-wired-lan-bounces@lists.osuosl.org>", "X-Original-To": [ "incoming@patchwork.ozlabs.org", "intel-wired-lan@lists.osuosl.org" ], "Delivered-To": [ "patchwork-incoming@bilbo.ozlabs.org", "intel-wired-lan@lists.osuosl.org" ], "Received": [ "from silver.osuosl.org (smtp3.osuosl.org [140.211.166.136])\n\t(using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits))\n\t(No client certificate requested)\n\tby ozlabs.org (Postfix) with ESMTPS id 3tN50W4N4Qz9svs\n\tfor <incoming@patchwork.ozlabs.org>;\n\tTue, 22 Nov 2016 10:48:59 +1100 (AEDT)", "from localhost (localhost [127.0.0.1])\n\tby silver.osuosl.org (Postfix) with ESMTP id 31B36245DF;\n\tMon, 21 Nov 2016 23:48:58 +0000 (UTC)", "from silver.osuosl.org ([127.0.0.1])\n\tby localhost (.osuosl.org [127.0.0.1]) (amavisd-new, port 10024)\n\twith ESMTP id 0bL1CKD8dhZn; Mon, 21 Nov 2016 23:48:30 +0000 (UTC)", "from ash.osuosl.org (ash.osuosl.org [140.211.166.34])\n\tby silver.osuosl.org (Postfix) with ESMTP id 7A50424576;\n\tMon, 21 Nov 2016 23:48:18 +0000 (UTC)", "from fraxinus.osuosl.org (smtp4.osuosl.org [140.211.166.137])\n\tby ash.osuosl.org (Postfix) with ESMTP id E7D2B1C073B\n\tfor <intel-wired-lan@lists.osuosl.org>;\n\tMon, 21 Nov 2016 23:48:16 +0000 (UTC)", "from localhost (localhost [127.0.0.1])\n\tby fraxinus.osuosl.org (Postfix) with ESMTP id B084A87010\n\tfor <intel-wired-lan@lists.osuosl.org>;\n\tMon, 21 Nov 2016 23:48:16 +0000 (UTC)", "from fraxinus.osuosl.org ([127.0.0.1])\n\tby localhost (.osuosl.org [127.0.0.1]) (amavisd-new, port 10024)\n\twith ESMTP id uLbfQpYm7_xV for <intel-wired-lan@lists.osuosl.org>;\n\tMon, 21 Nov 2016 23:48:14 +0000 (UTC)", "from mga05.intel.com (mga05.intel.com [192.55.52.43])\n\tby fraxinus.osuosl.org (Postfix) with ESMTPS id CF91C86F66\n\tfor <intel-wired-lan@lists.osuosl.org>;\n\tMon, 21 Nov 2016 23:48:14 +0000 (UTC)", "from orsmga004.jf.intel.com ([10.7.209.38])\n\tby fmsmga105.fm.intel.com with ESMTP; 21 Nov 2016 15:48:14 -0800", "from mdrustad-wks.jf.intel.com ([134.134.3.111])\n\tby orsmga004.jf.intel.com with ESMTP; 21 Nov 2016 15:48:14 -0800" ], "X-Virus-Scanned": [ "amavisd-new at osuosl.org", "amavisd-new at osuosl.org" ], "X-Greylist": "domain auto-whitelisted by SQLgrey-1.7.6", "X-ExtLoop1": "1", "X-IronPort-AV": "E=Sophos;i=\"5.31,677,1473145200\"; d=\"scan'208\";a=\"33258418\"", "From": "Mark D Rustad <mark.d.rustad@intel.com>", "To": "intel-wired-lan@lists.osuosl.org", "Date": "Mon, 21 Nov 2016 15:48:14 -0800", "Message-ID": "<147977209408.28902.2664072497234838810.stgit@mdrustad-wks.jf.intel.com>", "In-Reply-To": "<147977200790.28902.977631990204721234.stgit@mdrustad-wks.jf.intel.com>", "References": "<147977200790.28902.977631990204721234.stgit@mdrustad-wks.jf.intel.com>", "User-Agent": "StGit/unknown-version", "MIME-Version": "1.0", "Subject": "[Intel-wired-lan] [PATCH 4/4] ixgbe: Implement support for\n\tfirmware-controlled PHYs", "X-BeenThere": "intel-wired-lan@lists.osuosl.org", "X-Mailman-Version": "2.1.18-1", "Precedence": "list", "List-Id": "Intel Wired Ethernet Linux Kernel Driver Development\n\t<intel-wired-lan.lists.osuosl.org>", "List-Unsubscribe": "<http://lists.osuosl.org/mailman/options/intel-wired-lan>, \n\t<mailto:intel-wired-lan-request@lists.osuosl.org?subject=unsubscribe>", "List-Archive": "<http://lists.osuosl.org/pipermail/intel-wired-lan/>", "List-Post": "<mailto:intel-wired-lan@lists.osuosl.org>", "List-Help": "<mailto:intel-wired-lan-request@lists.osuosl.org?subject=help>", "List-Subscribe": "<http://lists.osuosl.org/mailman/listinfo/intel-wired-lan>, \n\t<mailto:intel-wired-lan-request@lists.osuosl.org?subject=subscribe>", "Content-Type": "text/plain; charset=\"us-ascii\"", "Content-Transfer-Encoding": "7bit", "Errors-To": "intel-wired-lan-bounces@lists.osuosl.org", "Sender": "\"Intel-wired-lan\" <intel-wired-lan-bounces@lists.osuosl.org>" }, "content": "Implement support for devices that have firmware-controlled PHYs.\n\nSigned-off-by: Mark Rustad <mark.d.rustad@intel.com>\n---\n drivers/net/ethernet/intel/ixgbe/ixgbe.h | 4 \n drivers/net/ethernet/intel/ixgbe/ixgbe_ethtool.c | 138 ++++++++\n drivers/net/ethernet/intel/ixgbe/ixgbe_main.c | 42 ++\n drivers/net/ethernet/intel/ixgbe/ixgbe_phy.c | 3 \n drivers/net/ethernet/intel/ixgbe/ixgbe_type.h | 6 \n drivers/net/ethernet/intel/ixgbe/ixgbe_x550.c | 387 ++++++++++++++++++++++\n 6 files changed, 577 insertions(+), 3 deletions(-)", "diff": "diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe.h b/drivers/net/ethernet/intel/ixgbe/ixgbe.h\nindex ef81c3d8c295..53fb427b1c29 100644\n--- a/drivers/net/ethernet/intel/ixgbe/ixgbe.h\n+++ b/drivers/net/ethernet/intel/ixgbe/ixgbe.h\n@@ -661,6 +661,8 @@ struct ixgbe_adapter {\n #define IXGBE_FLAG2_PHY_INTERRUPT\t\tBIT(11)\n #define IXGBE_FLAG2_UDP_TUN_REREG_NEEDED\tBIT(12)\n #define IXGBE_FLAG2_VLAN_PROMISC\t\tBIT(13)\n+#define IXGBE_FLAG2_EEE_CAPABLE\t\t\tBIT(14)\n+#define IXGBE_FLAG2_EEE_ENABLED\t\t\tBIT(15)\n \n \t/* Tx fast path data */\n \tint num_tx_queues;\n@@ -862,6 +864,7 @@ enum ixgbe_boards {\n \tboard_X550,\n \tboard_X550EM_x,\n \tboard_x550em_a,\n+\tboard_x550em_a_fw,\n };\n \n extern const struct ixgbe_info ixgbe_82598_info;\n@@ -870,6 +873,7 @@ extern const struct ixgbe_info ixgbe_X540_info;\n extern const struct ixgbe_info ixgbe_X550_info;\n extern const struct ixgbe_info ixgbe_X550EM_x_info;\n extern const struct ixgbe_info ixgbe_x550em_a_info;\n+extern const struct ixgbe_info ixgbe_x550em_a_fw_info;\n #ifdef CONFIG_IXGBE_DCB\n extern const struct dcbnl_rtnl_ops dcbnl_ops;\n #endif\ndiff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_ethtool.c b/drivers/net/ethernet/intel/ixgbe/ixgbe_ethtool.c\nindex fd192bf29b26..005d28d1f3fe 100644\n--- a/drivers/net/ethernet/intel/ixgbe/ixgbe_ethtool.c\n+++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_ethtool.c\n@@ -3173,6 +3173,9 @@ static int ixgbe_get_module_info(struct net_device *dev,\n \tu8 sff8472_rev, addr_mode;\n \tbool page_swap = false;\n \n+\tif (hw->phy.type == ixgbe_phy_fw)\n+\t\treturn -ENXIO;\n+\n \t/* Check whether we support SFF-8472 or not */\n \tstatus = hw->phy.ops.read_i2c_eeprom(hw,\n \t\t\t\t\t IXGBE_SFF_SFF_8472_COMP,\n@@ -3218,6 +3221,9 @@ static int ixgbe_get_module_eeprom(struct net_device *dev,\n \tif (ee->len == 0)\n \t\treturn -EINVAL;\n \n+\tif (hw->phy.type == ixgbe_phy_fw)\n+\t\treturn -ENXIO;\n+\n \tfor (i = ee->offset; i < ee->offset + ee->len; i++) {\n \t\t/* I2C reads can take long time */\n \t\tif (test_bit(__IXGBE_IN_SFP_INIT, &adapter->state))\n@@ -3237,6 +3243,136 @@ static int ixgbe_get_module_eeprom(struct net_device *dev,\n \treturn 0;\n }\n \n+static const struct {\n+\tixgbe_link_speed mac_speed;\n+\tu32 supported;\n+} ixgbe_ls_map[] = {\n+\t{ IXGBE_LINK_SPEED_10_FULL, SUPPORTED_10baseT_Full },\n+\t{ IXGBE_LINK_SPEED_100_FULL, SUPPORTED_100baseT_Full },\n+\t{ IXGBE_LINK_SPEED_1GB_FULL, SUPPORTED_1000baseT_Full },\n+\t{ IXGBE_LINK_SPEED_2_5GB_FULL, SUPPORTED_2500baseX_Full },\n+\t{ IXGBE_LINK_SPEED_10GB_FULL, SUPPORTED_10000baseT_Full },\n+};\n+\n+static const struct {\n+\tu32 lp_advertised;\n+\tu32 mac_speed;\n+} ixgbe_lp_map[] = {\n+\t{ FW_PHY_ACT_UD_2_100M_TX_EEE, SUPPORTED_100baseT_Full },\n+\t{ FW_PHY_ACT_UD_2_1G_T_EEE, SUPPORTED_1000baseT_Full },\n+\t{ FW_PHY_ACT_UD_2_10G_T_EEE, SUPPORTED_10000baseT_Full },\n+\t{ FW_PHY_ACT_UD_2_1G_KX_EEE, SUPPORTED_1000baseKX_Full },\n+\t{ FW_PHY_ACT_UD_2_10G_KX4_EEE, SUPPORTED_10000baseKX4_Full },\n+\t{ FW_PHY_ACT_UD_2_10G_KR_EEE, SUPPORTED_10000baseKR_Full},\n+};\n+\n+static int\n+ixgbe_get_eee_fw(struct ixgbe_adapter *adapter, struct ethtool_eee *edata)\n+{\n+\tu32 info[FW_PHY_ACT_DATA_COUNT] = { 0 };\n+\tstruct ixgbe_hw *hw = &adapter->hw;\n+\ts32 rc;\n+\tu16 i;\n+\n+\trc = ixgbe_fw_phy_activity(hw, FW_PHY_ACT_UD_2, &info);\n+\tif (rc)\n+\t\treturn rc;\n+\n+\tedata->lp_advertised = 0;\n+\tfor (i = 0; i < ARRAY_SIZE(ixgbe_lp_map); ++i) {\n+\t\tif (info[0] & ixgbe_lp_map[i].lp_advertised)\n+\t\t\tedata->lp_advertised |= ixgbe_lp_map[i].mac_speed;\n+\t}\n+\n+\tedata->supported = 0;\n+\tfor (i = 0; i < ARRAY_SIZE(ixgbe_ls_map); ++i) {\n+\t\tif (hw->phy.eee_speeds_supported & ixgbe_ls_map[i].mac_speed)\n+\t\t\tedata->supported |= ixgbe_ls_map[i].supported;\n+\t}\n+\n+\tedata->advertised = 0;\n+\tfor (i = 0; i < ARRAY_SIZE(ixgbe_ls_map); ++i) {\n+\t\tif (hw->phy.eee_speeds_advertised & ixgbe_ls_map[i].mac_speed)\n+\t\t\tedata->advertised |= ixgbe_ls_map[i].supported;\n+\t}\n+\n+\tedata->eee_enabled = !!edata->advertised;\n+\tedata->tx_lpi_enabled = edata->eee_enabled;\n+\tif (edata->advertised & edata->lp_advertised)\n+\t\tedata->eee_active = true;\n+\n+\treturn 0;\n+}\n+\n+static int ixgbe_get_eee(struct net_device *netdev, struct ethtool_eee *edata)\n+{\n+\tstruct ixgbe_adapter *adapter = netdev_priv(netdev);\n+\tstruct ixgbe_hw *hw = &adapter->hw;\n+\n+\tif (!(adapter->flags2 & IXGBE_FLAG2_EEE_CAPABLE))\n+\t\treturn -EOPNOTSUPP;\n+\n+\tif (hw->phy.eee_speeds_supported && hw->phy.type == ixgbe_phy_fw)\n+\t\treturn ixgbe_get_eee_fw(adapter, edata);\n+\n+\treturn -EOPNOTSUPP;\n+}\n+\n+static int ixgbe_set_eee(struct net_device *netdev, struct ethtool_eee *edata)\n+{\n+\tstruct ixgbe_adapter *adapter = netdev_priv(netdev);\n+\tstruct ixgbe_hw *hw = &adapter->hw;\n+\tstruct ethtool_eee eee_data;\n+\ts32 ret_val;\n+\n+\tif (!(adapter->flags2 & IXGBE_FLAG2_EEE_CAPABLE))\n+\t\treturn -EOPNOTSUPP;\n+\n+\tmemset(&eee_data, 0, sizeof(struct ethtool_eee));\n+\n+\tret_val = ixgbe_get_eee(netdev, &eee_data);\n+\tif (ret_val)\n+\t\treturn ret_val;\n+\n+\tif (eee_data.eee_enabled && !edata->eee_enabled) {\n+\t\tif (eee_data.tx_lpi_enabled != edata->tx_lpi_enabled) {\n+\t\t\te_err(drv, \"Setting EEE tx-lpi is not supported\\n\");\n+\t\t\treturn -EINVAL;\n+\t\t}\n+\n+\t\tif (eee_data.tx_lpi_timer != edata->tx_lpi_timer) {\n+\t\t\te_err(drv,\n+\t\t\t \"Setting EEE Tx LPI timer is not supported\\n\");\n+\t\t\treturn -EINVAL;\n+\t\t}\n+\n+\t\tif (eee_data.advertised != edata->advertised) {\n+\t\t\te_err(drv,\n+\t\t\t \"Setting EEE advertised speeds is not supported\\n\");\n+\t\t\treturn -EINVAL;\n+\t\t}\n+\t}\n+\n+\tif (eee_data.eee_enabled != edata->eee_enabled) {\n+\t\tif (edata->eee_enabled) {\n+\t\t\tadapter->flags2 |= IXGBE_FLAG2_EEE_ENABLED;\n+\t\t\thw->phy.eee_speeds_advertised =\n+\t\t\t\t\t\t hw->phy.eee_speeds_supported;\n+\t\t} else {\n+\t\t\tadapter->flags2 &= ~IXGBE_FLAG2_EEE_ENABLED;\n+\t\t\thw->phy.eee_speeds_advertised = 0;\n+\t\t}\n+\n+\t\t/* reset link */\n+\t\tif (netif_running(netdev))\n+\t\t\tixgbe_reinit_locked(adapter);\n+\t\telse\n+\t\t\tixgbe_reset(adapter);\n+\t}\n+\n+\treturn 0;\n+}\n+\n static const struct ethtool_ops ixgbe_ethtool_ops = {\n \t.get_settings = ixgbe_get_settings,\n \t.set_settings = ixgbe_set_settings,\n@@ -3269,6 +3405,8 @@ static const struct ethtool_ops ixgbe_ethtool_ops = {\n \t.get_rxfh_key_size\t= ixgbe_get_rxfh_key_size,\n \t.get_rxfh\t\t= ixgbe_get_rxfh,\n \t.set_rxfh\t\t= ixgbe_set_rxfh,\n+\t.get_eee\t\t= ixgbe_get_eee,\n+\t.set_eee\t\t= ixgbe_set_eee,\n \t.get_channels\t\t= ixgbe_get_channels,\n \t.set_channels\t\t= ixgbe_set_channels,\n \t.get_ts_info\t\t= ixgbe_get_ts_info,\ndiff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c b/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c\nindex 0b1fa5d557ba..b12bcb18f41c 100644\n--- a/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c\n+++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c\n@@ -86,6 +86,7 @@ static const struct ixgbe_info *ixgbe_info_tbl[] = {\n \t[board_X550]\t\t= &ixgbe_X550_info,\n \t[board_X550EM_x]\t= &ixgbe_X550EM_x_info,\n \t[board_x550em_a]\t= &ixgbe_x550em_a_info,\n+\t[board_x550em_a_fw]\t= &ixgbe_x550em_a_fw_info,\n };\n \n /* ixgbe_pci_tbl - PCI Device ID Table\n@@ -140,6 +141,8 @@ static const struct pci_device_id ixgbe_pci_tbl[] = {\n \t{PCI_VDEVICE(INTEL, IXGBE_DEV_ID_X550EM_A_SGMII_L), board_x550em_a },\n \t{PCI_VDEVICE(INTEL, IXGBE_DEV_ID_X550EM_A_10G_T), board_x550em_a},\n \t{PCI_VDEVICE(INTEL, IXGBE_DEV_ID_X550EM_A_SFP), board_x550em_a },\n+\t{PCI_VDEVICE(INTEL, IXGBE_DEV_ID_X550EM_A_1G_T), board_x550em_a_fw },\n+\t{PCI_VDEVICE(INTEL, IXGBE_DEV_ID_X550EM_A_1G_T_L), board_x550em_a_fw },\n \t/* required last entry */\n \t{0, }\n };\n@@ -180,6 +183,7 @@ MODULE_VERSION(DRV_VERSION);\n static struct workqueue_struct *ixgbe_wq;\n \n static bool ixgbe_check_cfg_remove(struct ixgbe_hw *hw, struct pci_dev *pdev);\n+static void ixgbe_watchdog_link_is_down(struct ixgbe_adapter *);\n \n static int ixgbe_read_pci_cfg_word_parent(struct ixgbe_adapter *adapter,\n \t\t\t\t\t u32 reg, u16 *value)\n@@ -5294,6 +5298,8 @@ void ixgbe_reinit_locked(struct ixgbe_adapter *adapter)\n \n \twhile (test_and_set_bit(__IXGBE_RESETTING, &adapter->state))\n \t\tusleep_range(1000, 2000);\n+\tif (adapter->hw.phy.type == ixgbe_phy_fw)\n+\t\tixgbe_watchdog_link_is_down(adapter);\n \tixgbe_down(adapter);\n \t/*\n \t * If SR-IOV enabled then wait a bit before bringing the adapter\n@@ -5554,6 +5560,31 @@ void ixgbe_down(struct ixgbe_adapter *adapter)\n }\n \n /**\n+ * ixgbe_eee_capable - helper function to determine EEE support on X550\n+ * @adapter: board private structure\n+ */\n+static void ixgbe_set_eee_capable(struct ixgbe_adapter *adapter)\n+{\n+\tstruct ixgbe_hw *hw = &adapter->hw;\n+\n+\tswitch (hw->device_id) {\n+\tcase IXGBE_DEV_ID_X550EM_A_1G_T:\n+\tcase IXGBE_DEV_ID_X550EM_A_1G_T_L:\n+\t\tif (!hw->phy.eee_speeds_supported)\n+\t\t\tbreak;\n+\t\tadapter->flags2 |= IXGBE_FLAG2_EEE_CAPABLE;\n+\t\tif (!hw->phy.eee_speeds_advertised)\n+\t\t\tbreak;\n+\t\tadapter->flags2 |= IXGBE_FLAG2_EEE_ENABLED;\n+\t\tbreak;\n+\tdefault:\n+\t\tadapter->flags2 &= ~IXGBE_FLAG2_EEE_CAPABLE;\n+\t\tadapter->flags2 &= ~IXGBE_FLAG2_EEE_ENABLED;\n+\t\tbreak;\n+\t}\n+}\n+\n+/**\n * ixgbe_tx_timeout - Respond to a Tx Hang\n * @netdev: network interface device structure\n **/\n@@ -5717,6 +5748,14 @@ static int ixgbe_sw_init(struct ixgbe_adapter *adapter,\n \t\tbreak;\n \tcase ixgbe_mac_x550em_a:\n \t\tadapter->flags |= IXGBE_FLAG_GENEVE_OFFLOAD_CAPABLE;\n+\t\tswitch (hw->device_id) {\n+\t\tcase IXGBE_DEV_ID_X550EM_A_1G_T:\n+\t\tcase IXGBE_DEV_ID_X550EM_A_1G_T_L:\n+\t\t\tadapter->flags2 |= IXGBE_FLAG2_TEMP_SENSOR_CAPABLE;\n+\t\t\tbreak;\n+\t\tdefault:\n+\t\t\tbreak;\n+\t\t}\n \t/* fall through */\n \tcase ixgbe_mac_X550EM_x:\n #ifdef CONFIG_IXGBE_DCB\n@@ -5730,6 +5769,8 @@ static int ixgbe_sw_init(struct ixgbe_adapter *adapter,\n #endif /* IXGBE_FCOE */\n \t/* Fall Through */\n \tcase ixgbe_mac_X550:\n+\t\tif (hw->mac.type == ixgbe_mac_X550)\n+\t\t\tadapter->flags2 |= IXGBE_FLAG2_TEMP_SENSOR_CAPABLE;\n #ifdef CONFIG_IXGBE_DCA\n \t\tadapter->flags &= ~IXGBE_FLAG_DCA_CAPABLE;\n #endif\n@@ -9591,6 +9632,7 @@ static int ixgbe_probe(struct pci_dev *pdev, const struct pci_device_id *ent)\n \thw->phy.reset_if_overtemp = true;\n \terr = hw->mac.ops.reset_hw(hw);\n \thw->phy.reset_if_overtemp = false;\n+\tixgbe_set_eee_capable(adapter);\n \tif (err == IXGBE_ERR_SFP_NOT_PRESENT) {\n \t\terr = 0;\n \t} else if (err == IXGBE_ERR_SFP_NOT_SUPPORTED) {\ndiff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_phy.c b/drivers/net/ethernet/intel/ixgbe/ixgbe_phy.c\nindex 989a3b19d209..92dc4699b8c7 100644\n--- a/drivers/net/ethernet/intel/ixgbe/ixgbe_phy.c\n+++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_phy.c\n@@ -784,6 +784,9 @@ s32 ixgbe_setup_phy_link_speed_generic(struct ixgbe_hw *hw,\n \tif (speed & IXGBE_LINK_SPEED_100_FULL)\n \t\thw->phy.autoneg_advertised |= IXGBE_LINK_SPEED_100_FULL;\n \n+\tif (speed & IXGBE_LINK_SPEED_10_FULL)\n+\t\thw->phy.autoneg_advertised |= IXGBE_LINK_SPEED_10_FULL;\n+\n \t/* Setup link based on the new speed settings */\n \tif (hw->phy.ops.setup_link)\n \t\thw->phy.ops.setup_link(hw);\ndiff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_type.h b/drivers/net/ethernet/intel/ixgbe/ixgbe_type.h\nindex acdbd81df3a4..7a15b413044b 100644\n--- a/drivers/net/ethernet/intel/ixgbe/ixgbe_type.h\n+++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_type.h\n@@ -92,6 +92,8 @@\n #define IXGBE_DEV_ID_X550EM_A_SGMII_L\t0x15C7\n #define IXGBE_DEV_ID_X550EM_A_10G_T\t0x15C8\n #define IXGBE_DEV_ID_X550EM_A_SFP\t0x15CE\n+#define IXGBE_DEV_ID_X550EM_A_1G_T\t0x15E4\n+#define IXGBE_DEV_ID_X550EM_A_1G_T_L\t0x15E5\n \n /* VF Device IDs */\n #define IXGBE_DEV_ID_82599_VF\t\t0x10ED\n@@ -2926,6 +2928,7 @@ typedef u32 ixgbe_autoneg_advertised;\n /* Link speed */\n typedef u32 ixgbe_link_speed;\n #define IXGBE_LINK_SPEED_UNKNOWN\t0\n+#define IXGBE_LINK_SPEED_10_FULL\t0x0002\n #define IXGBE_LINK_SPEED_100_FULL\t0x0008\n #define IXGBE_LINK_SPEED_1GB_FULL\t0x0020\n #define IXGBE_LINK_SPEED_2_5GB_FULL\t0x0400\n@@ -3141,6 +3144,7 @@ enum ixgbe_phy_type {\n \tixgbe_phy_qsfp_unknown,\n \tixgbe_phy_sfp_unsupported,\n \tixgbe_phy_sgmii,\n+\tixgbe_phy_fw,\n \tixgbe_phy_generic\n };\n \n@@ -3555,6 +3559,8 @@ struct ixgbe_phy_info {\n \tbool reset_disable;\n \tixgbe_autoneg_advertised autoneg_advertised;\n \tixgbe_link_speed\t\tspeeds_supported;\n+\tixgbe_link_speed\t\teee_speeds_supported;\n+\tixgbe_link_speed\t\teee_speeds_advertised;\n \tenum ixgbe_smart_speed smart_speed;\n \tbool smart_speed_active;\n \tbool multispeed_fiber;\ndiff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_x550.c b/drivers/net/ethernet/intel/ixgbe/ixgbe_x550.c\nindex 9284b8f0178d..0adedbba7a90 100644\n--- a/drivers/net/ethernet/intel/ixgbe/ixgbe_x550.c\n+++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_x550.c\n@@ -63,6 +63,18 @@ static s32 ixgbe_get_invariants_X550_a(struct ixgbe_hw *hw)\n \treturn 0;\n }\n \n+static s32 ixgbe_get_invariants_X550_a_fw(struct ixgbe_hw *hw)\n+{\n+\tstruct ixgbe_phy_info *phy = &hw->phy;\n+\n+\t/* Start with X540 invariants, since so similar */\n+\tixgbe_get_invariants_X540(hw);\n+\n+\tphy->ops.set_phy_power = NULL;\n+\n+\treturn 0;\n+}\n+\n /** ixgbe_setup_mux_ctl - Setup ESDP register for I2C mux control\n * @hw: pointer to hardware structure\n **/\n@@ -447,6 +459,159 @@ s32 ixgbe_fw_phy_activity(struct ixgbe_hw *hw, u16 activity,\n \treturn IXGBE_ERR_HOST_INTERFACE_COMMAND;\n }\n \n+static const struct {\n+\tu16 fw_speed;\n+\tixgbe_link_speed phy_speed;\n+} ixgbe_fw_map[] = {\n+\t{ FW_PHY_ACT_LINK_SPEED_10, IXGBE_LINK_SPEED_10_FULL },\n+\t{ FW_PHY_ACT_LINK_SPEED_100, IXGBE_LINK_SPEED_100_FULL },\n+\t{ FW_PHY_ACT_LINK_SPEED_1G, IXGBE_LINK_SPEED_1GB_FULL },\n+\t{ FW_PHY_ACT_LINK_SPEED_2_5G, IXGBE_LINK_SPEED_2_5GB_FULL },\n+\t{ FW_PHY_ACT_LINK_SPEED_5G, IXGBE_LINK_SPEED_5GB_FULL },\n+\t{ FW_PHY_ACT_LINK_SPEED_10G, IXGBE_LINK_SPEED_10GB_FULL },\n+};\n+\n+/**\n+ * ixgbe_get_phy_id_fw - Get the phy ID via firmware command\n+ * @hw: pointer to hardware structure\n+ *\n+ * Returns error code\n+ */\n+static s32 ixgbe_get_phy_id_fw(struct ixgbe_hw *hw)\n+{\n+\tu32 info[FW_PHY_ACT_DATA_COUNT] = { 0 };\n+\tu16 phy_speeds;\n+\tu16 phy_id_lo;\n+\ts32 rc;\n+\tu16 i;\n+\n+\tif (hw->phy.id)\n+\t\treturn 0;\n+\n+\trc = ixgbe_fw_phy_activity(hw, FW_PHY_ACT_GET_PHY_INFO, &info);\n+\tif (rc)\n+\t\treturn rc;\n+\n+\thw->phy.speeds_supported = 0;\n+\tphy_speeds = info[0] & FW_PHY_INFO_SPEED_MASK;\n+\tfor (i = 0; i < ARRAY_SIZE(ixgbe_fw_map); ++i) {\n+\t\tif (phy_speeds & ixgbe_fw_map[i].fw_speed)\n+\t\t\thw->phy.speeds_supported |= ixgbe_fw_map[i].phy_speed;\n+\t}\n+\n+\thw->phy.id = info[0] & FW_PHY_INFO_ID_HI_MASK;\n+\tphy_id_lo = info[1] & FW_PHY_INFO_ID_LO_MASK;\n+\thw->phy.id |= phy_id_lo & IXGBE_PHY_REVISION_MASK;\n+\thw->phy.revision = phy_id_lo & ~IXGBE_PHY_REVISION_MASK;\n+\tif (!hw->phy.id || hw->phy.id == IXGBE_PHY_REVISION_MASK)\n+\t\treturn IXGBE_ERR_PHY_ADDR_INVALID;\n+\n+\thw->phy.autoneg_advertised = hw->phy.speeds_supported;\n+\thw->phy.eee_speeds_supported = IXGBE_LINK_SPEED_100_FULL |\n+\t\t\t\t IXGBE_LINK_SPEED_1GB_FULL;\n+\thw->phy.eee_speeds_advertised = hw->phy.eee_speeds_supported;\n+\treturn 0;\n+}\n+\n+/**\n+ * ixgbe_identify_phy_fw - Get PHY type based on firmware command\n+ * @hw: pointer to hardware structure\n+ *\n+ * Returns error code\n+ */\n+static s32 ixgbe_identify_phy_fw(struct ixgbe_hw *hw)\n+{\n+\tif (hw->bus.lan_id)\n+\t\thw->phy.phy_semaphore_mask = IXGBE_GSSR_PHY1_SM;\n+\telse\n+\t\thw->phy.phy_semaphore_mask = IXGBE_GSSR_PHY0_SM;\n+\n+\thw->phy.type = ixgbe_phy_fw;\n+\thw->phy.ops.read_reg = NULL;\n+\thw->phy.ops.write_reg = NULL;\n+\treturn ixgbe_get_phy_id_fw(hw);\n+}\n+\n+/**\n+ * ixgbe_shutdown_fw_phy - Shutdown a firmware-controlled PHY\n+ * @hw: pointer to hardware structure\n+ *\n+ * Returns error code\n+ */\n+static s32 ixgbe_shutdown_fw_phy(struct ixgbe_hw *hw)\n+{\n+\tu32 setup[FW_PHY_ACT_DATA_COUNT] = { 0 };\n+\n+\tsetup[0] = FW_PHY_ACT_FORCE_LINK_DOWN_OFF;\n+\treturn ixgbe_fw_phy_activity(hw, FW_PHY_ACT_FORCE_LINK_DOWN, &setup);\n+}\n+\n+/**\n+ * ixgbe_setup_fw_link - Setup firmware-controlled PHYs\n+ * @hw: pointer to hardware structure\n+ */\n+static s32 ixgbe_setup_fw_link(struct ixgbe_hw *hw)\n+{\n+\tu32 setup[FW_PHY_ACT_DATA_COUNT] = { 0 };\n+\ts32 rc;\n+\tu16 i;\n+\n+\tif (hw->phy.reset_disable || ixgbe_check_reset_blocked(hw))\n+\t\treturn 0;\n+\n+\tif (hw->fc.strict_ieee && hw->fc.requested_mode == ixgbe_fc_rx_pause) {\n+\t\thw_err(hw, \"rx_pause not valid in strict IEEE mode\\n\");\n+\t\treturn IXGBE_ERR_INVALID_LINK_SETTINGS;\n+\t}\n+\n+\tswitch (hw->fc.requested_mode) {\n+\tcase ixgbe_fc_full:\n+\t\tsetup[0] |= FW_PHY_ACT_SETUP_LINK_PAUSE_RXTX <<\n+\t\t\t FW_PHY_ACT_SETUP_LINK_PAUSE_SHIFT;\n+\t\tbreak;\n+\tcase ixgbe_fc_rx_pause:\n+\t\tsetup[0] |= FW_PHY_ACT_SETUP_LINK_PAUSE_RX <<\n+\t\t\t FW_PHY_ACT_SETUP_LINK_PAUSE_SHIFT;\n+\t\tbreak;\n+\tcase ixgbe_fc_tx_pause:\n+\t\tsetup[0] |= FW_PHY_ACT_SETUP_LINK_PAUSE_TX <<\n+\t\t\t FW_PHY_ACT_SETUP_LINK_PAUSE_SHIFT;\n+\t\tbreak;\n+\tdefault:\n+\t\tbreak;\n+\t}\n+\n+\tfor (i = 0; i < ARRAY_SIZE(ixgbe_fw_map); ++i) {\n+\t\tif (hw->phy.autoneg_advertised & ixgbe_fw_map[i].phy_speed)\n+\t\t\tsetup[0] |= ixgbe_fw_map[i].fw_speed;\n+\t}\n+\tsetup[0] |= FW_PHY_ACT_SETUP_LINK_HP | FW_PHY_ACT_SETUP_LINK_AN;\n+\n+\tif (hw->phy.eee_speeds_advertised)\n+\t\tsetup[0] |= FW_PHY_ACT_SETUP_LINK_EEE;\n+\n+\trc = ixgbe_fw_phy_activity(hw, FW_PHY_ACT_SETUP_LINK, &setup);\n+\tif (rc)\n+\t\treturn rc;\n+\tif (setup[0] == FW_PHY_ACT_SETUP_LINK_RSP_DOWN)\n+\t\treturn IXGBE_ERR_OVERTEMP;\n+\treturn 0;\n+}\n+\n+/**\n+ * ixgbe_fc_autoneg_fw - Set up flow control for FW-controlled PHYs\n+ * @hw: pointer to hardware structure\n+ *\n+ * Called at init time to set up flow control.\n+ */\n+static s32 ixgbe_fc_autoneg_fw(struct ixgbe_hw *hw)\n+{\n+\tif (hw->fc.requested_mode == ixgbe_fc_default)\n+\t\thw->fc.requested_mode = ixgbe_fc_full;\n+\n+\treturn ixgbe_setup_fw_link(hw);\n+}\n+\n /** ixgbe_init_eeprom_params_X550 - Initialize EEPROM params\n * @hw: pointer to hardware structure\n *\n@@ -1794,6 +1959,125 @@ ixgbe_setup_sgmii(struct ixgbe_hw *hw, __always_unused ixgbe_link_speed speed,\n \treturn rc;\n }\n \n+/**\n+ * ixgbe_setup_sgmii_fw - Set up link for sgmii with firmware-controlled PHYs\n+ * @hw: pointer to hardware structure\n+ */\n+static s32 ixgbe_setup_sgmii_fw(struct ixgbe_hw *hw, ixgbe_link_speed speed,\n+\t\t\t\tbool autoneg_wait)\n+{\n+\tstruct ixgbe_mac_info *mac = &hw->mac;\n+\tu32 lval, sval, flx_val;\n+\ts32 rc;\n+\n+\trc = mac->ops.read_iosf_sb_reg(hw,\n+\t\t\t\t IXGBE_KRM_LINK_CTRL_1(hw->bus.lan_id),\n+\t\t\t\t IXGBE_SB_IOSF_TARGET_KR_PHY, &lval);\n+\tif (rc)\n+\t\treturn rc;\n+\n+\tlval &= ~IXGBE_KRM_LINK_CTRL_1_TETH_AN_ENABLE;\n+\tlval &= ~IXGBE_KRM_LINK_CTRL_1_TETH_FORCE_SPEED_MASK;\n+\tlval |= IXGBE_KRM_LINK_CTRL_1_TETH_AN_SGMII_EN;\n+\tlval |= IXGBE_KRM_LINK_CTRL_1_TETH_AN_CLAUSE_37_EN;\n+\tlval &= ~IXGBE_KRM_LINK_CTRL_1_TETH_FORCE_SPEED_1G;\n+\trc = mac->ops.write_iosf_sb_reg(hw,\n+\t\t\t\t\tIXGBE_KRM_LINK_CTRL_1(hw->bus.lan_id),\n+\t\t\t\t\tIXGBE_SB_IOSF_TARGET_KR_PHY, lval);\n+\tif (rc)\n+\t\treturn rc;\n+\n+\trc = mac->ops.read_iosf_sb_reg(hw,\n+\t\t\t\t IXGBE_KRM_SGMII_CTRL(hw->bus.lan_id),\n+\t\t\t\t IXGBE_SB_IOSF_TARGET_KR_PHY, &sval);\n+\tif (rc)\n+\t\treturn rc;\n+\n+\tsval &= ~IXGBE_KRM_SGMII_CTRL_MAC_TAR_FORCE_10_D;\n+\tsval &= ~IXGBE_KRM_SGMII_CTRL_MAC_TAR_FORCE_100_D;\n+\trc = mac->ops.write_iosf_sb_reg(hw,\n+\t\t\t\t\tIXGBE_KRM_SGMII_CTRL(hw->bus.lan_id),\n+\t\t\t\t\tIXGBE_SB_IOSF_TARGET_KR_PHY, sval);\n+\tif (rc)\n+\t\treturn rc;\n+\n+\trc = mac->ops.write_iosf_sb_reg(hw,\n+\t\t\t\t\tIXGBE_KRM_LINK_CTRL_1(hw->bus.lan_id),\n+\t\t\t\t\tIXGBE_SB_IOSF_TARGET_KR_PHY, lval);\n+\tif (rc)\n+\t\treturn rc;\n+\n+\trc = mac->ops.read_iosf_sb_reg(hw,\n+\t\t\t\t IXGBE_KRM_PMD_FLX_MASK_ST20(hw->bus.lan_id),\n+\t\t\t\t IXGBE_SB_IOSF_TARGET_KR_PHY, &flx_val);\n+\tif (rc)\n+\t\treturn rc;\n+\n+\tflx_val &= ~IXGBE_KRM_PMD_FLX_MASK_ST20_SPEED_MASK;\n+\tflx_val |= IXGBE_KRM_PMD_FLX_MASK_ST20_SPEED_AN;\n+\tflx_val &= ~IXGBE_KRM_PMD_FLX_MASK_ST20_AN_EN;\n+\tflx_val |= IXGBE_KRM_PMD_FLX_MASK_ST20_SGMII_EN;\n+\tflx_val |= IXGBE_KRM_PMD_FLX_MASK_ST20_AN37_EN;\n+\n+\trc = mac->ops.write_iosf_sb_reg(hw,\n+\t\t\t\t IXGBE_KRM_PMD_FLX_MASK_ST20(hw->bus.lan_id),\n+\t\t\t\t IXGBE_SB_IOSF_TARGET_KR_PHY, flx_val);\n+\tif (rc)\n+\t\treturn rc;\n+\n+\tixgbe_restart_an_internal_phy_x550em(hw);\n+\n+\treturn hw->phy.ops.setup_link_speed(hw, speed, autoneg_wait);\n+}\n+\n+/**\n+ * ixgbe_fc_autoneg_sgmii_x550em_a - Enable flow control IEEE clause 37\n+ * @hw: pointer to hardware structure\n+ *\n+ * Enable flow control according to IEEE clause 37.\n+ */\n+static void ixgbe_fc_autoneg_sgmii_x550em_a(struct ixgbe_hw *hw)\n+{\n+\ts32 status = IXGBE_ERR_FC_NOT_NEGOTIATED;\n+\tu32 info[FW_PHY_ACT_DATA_COUNT] = { 0 };\n+\tixgbe_link_speed speed;\n+\tbool link_up;\n+\n+\t/* AN should have completed when the cable was plugged in.\n+\t * Look for reasons to bail out. Bail out if:\n+\t * - FC autoneg is disabled, or if\n+\t * - link is not up.\n+\t */\n+\tif (hw->fc.disable_fc_autoneg)\n+\t\tgoto out;\n+\n+\thw->mac.ops.check_link(hw, &speed, &link_up, false);\n+\tif (!link_up)\n+\t\tgoto out;\n+\n+\t/* Check if auto-negotiation has completed */\n+\tstatus = ixgbe_fw_phy_activity(hw, FW_PHY_ACT_GET_LINK_INFO, &info);\n+\tif (status || !(info[0] & FW_PHY_ACT_GET_LINK_INFO_AN_COMPLETE)) {\n+\t\tstatus = IXGBE_ERR_FC_NOT_NEGOTIATED;\n+\t\tgoto out;\n+\t}\n+\n+\t/* Negotiate the flow control */\n+\tstatus = ixgbe_negotiate_fc(hw, info[0], info[0],\n+\t\t\t\t FW_PHY_ACT_GET_LINK_INFO_FC_RX,\n+\t\t\t\t FW_PHY_ACT_GET_LINK_INFO_FC_TX,\n+\t\t\t\t FW_PHY_ACT_GET_LINK_INFO_LP_FC_RX,\n+\t\t\t\t FW_PHY_ACT_GET_LINK_INFO_LP_FC_TX);\n+\n+out:\n+\tif (!status) {\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 /** ixgbe_init_mac_link_ops_X550em_a - Init mac link function pointers\n * @hw: pointer to hardware structure\n **/\n@@ -1806,6 +2090,17 @@ static void ixgbe_init_mac_link_ops_X550em_a(struct ixgbe_hw *hw)\n \t\tmac->ops.setup_fc = NULL;\n \t\tmac->ops.fc_autoneg = ixgbe_fc_autoneg_fiber_x550em_a;\n \t\tbreak;\n+\tcase ixgbe_media_type_copper:\n+\t\tif (hw->device_id != IXGBE_DEV_ID_X550EM_A_1G_T &&\n+\t\t hw->device_id != IXGBE_DEV_ID_X550EM_A_1G_T_L) {\n+\t\t\tmac->ops.setup_link = ixgbe_setup_mac_link_t_X550em;\n+\t\t\tbreak;\n+\t\t}\n+\t\tmac->ops.fc_autoneg = ixgbe_fc_autoneg_sgmii_x550em_a;\n+\t\tmac->ops.setup_fc = ixgbe_fc_autoneg_fw;\n+\t\tmac->ops.setup_link = ixgbe_setup_sgmii_fw;\n+\t\tmac->ops.check_link = ixgbe_check_mac_link_generic;\n+\t\tbreak;\n \tcase ixgbe_media_type_backplane:\n \t\tmac->ops.fc_autoneg = ixgbe_fc_autoneg_backplane_x550em_a;\n \t\tmac->ops.setup_fc = ixgbe_setup_fc_backplane_x550em_a;\n@@ -1853,7 +2148,7 @@ static void ixgbe_init_mac_link_ops_X550em(struct ixgbe_hw *hw)\n \t\tmac->ops.setup_link = ixgbe_setup_mac_link_t_X550em;\n \t\tmac->ops.setup_fc = ixgbe_setup_fc_generic;\n \t\tmac->ops.check_link = ixgbe_check_link_t_X550em;\n-\t\treturn;\n+\t\tbreak;\n \tcase ixgbe_media_type_backplane:\n \t\tif (hw->device_id == IXGBE_DEV_ID_X550EM_A_SGMII ||\n \t\t hw->device_id == IXGBE_DEV_ID_X550EM_A_SGMII_L)\n@@ -1896,6 +2191,12 @@ static s32 ixgbe_get_link_capabilities_X550em(struct ixgbe_hw *hw,\n \t\t\t\t\t ixgbe_link_speed *speed,\n \t\t\t\t\t bool *autoneg)\n {\n+\tif (hw->phy.type == ixgbe_phy_fw) {\n+\t\t*autoneg = true;\n+\t\t*speed = hw->phy.speeds_supported;\n+\t\treturn 0;\n+\t}\n+\n \t/* SFP */\n \tif (hw->phy.media_type == ixgbe_media_type_fiber) {\n \t\t/* CS4227 SFP must not enable auto-negotiation */\n@@ -2697,6 +2998,50 @@ static s32 ixgbe_enter_lplu_t_x550em(struct ixgbe_hw *hw)\n }\n \n /**\n+ * ixgbe_reset_phy_fw - Reset firmware-controlled PHYs\n+ * @hw: pointer to hardware structure\n+ */\n+static s32 ixgbe_reset_phy_fw(struct ixgbe_hw *hw)\n+{\n+\tu32 store[FW_PHY_ACT_DATA_COUNT] = { 0 };\n+\ts32 rc;\n+\n+\tif (hw->phy.reset_disable || ixgbe_check_reset_blocked(hw))\n+\t\treturn 0;\n+\n+\trc = ixgbe_fw_phy_activity(hw, FW_PHY_ACT_PHY_SW_RESET, &store);\n+\tif (rc)\n+\t\treturn rc;\n+\tmemset(store, 0, sizeof(store));\n+\n+\trc = ixgbe_fw_phy_activity(hw, FW_PHY_ACT_INIT_PHY, &store);\n+\tif (rc)\n+\t\treturn rc;\n+\n+\treturn ixgbe_setup_fw_link(hw);\n+}\n+\n+/**\n+ * ixgbe_check_overtemp_fw - Check firmware-controlled PHYs for overtemp\n+ * @hw: pointer to hardware structure\n+ */\n+static s32 ixgbe_check_overtemp_fw(struct ixgbe_hw *hw)\n+{\n+\tu32 store[FW_PHY_ACT_DATA_COUNT] = { 0 };\n+\ts32 rc;\n+\n+\trc = ixgbe_fw_phy_activity(hw, FW_PHY_ACT_GET_LINK_INFO, &store);\n+\tif (rc)\n+\t\treturn rc;\n+\n+\tif (store[0] & FW_PHY_ACT_GET_LINK_INFO_TEMP) {\n+\t\tixgbe_shutdown_fw_phy(hw);\n+\t\treturn IXGBE_ERR_OVERTEMP;\n+\t}\n+\treturn 0;\n+}\n+\n+/**\n * ixgbe_read_mng_if_sel_x550em - Read NW_MNG_IF_SEL register\n * @hw: pointer to hardware structure\n *\n@@ -2782,6 +3127,10 @@ static s32 ixgbe_init_phy_ops_X550em(struct ixgbe_hw *hw)\n \t\tphy->ops.handle_lasi = ixgbe_handle_lasi_ext_t_x550em;\n \t\tphy->ops.reset = ixgbe_reset_phy_t_X550em;\n \t\tbreak;\n+\tcase ixgbe_phy_fw:\n+\t\tphy->ops.setup_link = ixgbe_setup_fw_link;\n+\t\tphy->ops.reset = ixgbe_reset_phy_fw;\n+\t\tbreak;\n \tdefault:\n \t\tbreak;\n \t}\n@@ -2819,6 +3168,8 @@ static enum ixgbe_media_type ixgbe_get_media_type_X550em(struct ixgbe_hw *hw)\n \tcase IXGBE_DEV_ID_X550EM_X_1G_T:\n \tcase IXGBE_DEV_ID_X550EM_X_10G_T:\n \tcase IXGBE_DEV_ID_X550EM_A_10G_T:\n+\tcase IXGBE_DEV_ID_X550EM_A_1G_T:\n+\tcase IXGBE_DEV_ID_X550EM_A_1G_T_L:\n \t\tmedia_type = ixgbe_media_type_copper;\n \t\tbreak;\n \tdefault:\n@@ -2886,6 +3237,13 @@ static void ixgbe_set_mdio_speed(struct ixgbe_hw *hw)\n \t\thlreg0 &= ~IXGBE_HLREG0_MDCSPD;\n \t\tIXGBE_WRITE_REG(hw, IXGBE_HLREG0, hlreg0);\n \t\tbreak;\n+\tcase IXGBE_DEV_ID_X550EM_A_1G_T:\n+\tcase IXGBE_DEV_ID_X550EM_A_1G_T_L:\n+\t\t/* Select fast MDIO clock speed for these devices */\n+\t\thlreg0 = IXGBE_READ_REG(hw, IXGBE_HLREG0);\n+\t\thlreg0 |= IXGBE_HLREG0_MDCSPD;\n+\t\tIXGBE_WRITE_REG(hw, IXGBE_HLREG0, hlreg0);\n+\t\tbreak;\n \tdefault:\n \t\tbreak;\n \t}\n@@ -3426,11 +3784,11 @@ static const struct ixgbe_eeprom_operations eeprom_ops_X550EM_x = {\n \t.read_i2c_eeprom\t= &ixgbe_read_i2c_eeprom_generic, \\\n \t.write_i2c_eeprom\t= &ixgbe_write_i2c_eeprom_generic, \\\n \t.setup_link\t\t= &ixgbe_setup_phy_link_generic, \\\n-\t.set_phy_power\t\t= NULL, \\\n-\t.check_overtemp\t\t= &ixgbe_tn_check_overtemp,\n+\t.set_phy_power\t\t= NULL,\n \n static const struct ixgbe_phy_operations phy_ops_X550 = {\n \tX550_COMMON_PHY\n+\t.check_overtemp\t\t= &ixgbe_tn_check_overtemp,\n \t.init\t\t\t= NULL,\n \t.identify\t\t= &ixgbe_identify_phy_generic,\n \t.read_reg\t\t= &ixgbe_read_phy_reg_generic,\n@@ -3439,6 +3797,7 @@ static const struct ixgbe_phy_operations phy_ops_X550 = {\n \n static const struct ixgbe_phy_operations phy_ops_X550EM_x = {\n \tX550_COMMON_PHY\n+\t.check_overtemp\t\t= &ixgbe_tn_check_overtemp,\n \t.init\t\t\t= &ixgbe_init_phy_ops_X550em,\n \t.identify\t\t= &ixgbe_identify_phy_x550em,\n \t.read_reg\t\t= &ixgbe_read_phy_reg_generic,\n@@ -3447,6 +3806,7 @@ static const struct ixgbe_phy_operations phy_ops_X550EM_x = {\n \n static const struct ixgbe_phy_operations phy_ops_x550em_a = {\n \tX550_COMMON_PHY\n+\t.check_overtemp\t\t= &ixgbe_tn_check_overtemp,\n \t.init\t\t\t= &ixgbe_init_phy_ops_X550em,\n \t.identify\t\t= &ixgbe_identify_phy_x550em,\n \t.read_reg\t\t= &ixgbe_read_phy_reg_x550a,\n@@ -3455,6 +3815,17 @@ static const struct ixgbe_phy_operations phy_ops_x550em_a = {\n \t.write_reg_mdi\t\t= &ixgbe_write_phy_reg_mdi,\n };\n \n+static const struct ixgbe_phy_operations phy_ops_x550em_a_fw = {\n+\tX550_COMMON_PHY\n+\t.check_overtemp\t\t= ixgbe_check_overtemp_fw,\n+\t.init\t\t\t= ixgbe_init_phy_ops_X550em,\n+\t.identify\t\t= ixgbe_identify_phy_fw,\n+\t.read_reg\t\t= NULL,\n+\t.write_reg\t\t= NULL,\n+\t.read_reg_mdi\t\t= NULL,\n+\t.write_reg_mdi\t\t= NULL,\n+};\n+\n static const struct ixgbe_link_operations link_ops_x550em_x = {\n \t.read_link\t\t= &ixgbe_read_i2c_combined_generic,\n \t.read_link_unlocked\t= &ixgbe_read_i2c_combined_generic_unlocked,\n@@ -3504,3 +3875,13 @@ const struct ixgbe_info ixgbe_x550em_a_info = {\n \t.mbx_ops\t\t= &mbx_ops_generic,\n \t.mvals\t\t\t= ixgbe_mvals_x550em_a,\n };\n+\n+const struct ixgbe_info ixgbe_x550em_a_fw_info = {\n+\t.mac\t\t\t= ixgbe_mac_x550em_a,\n+\t.get_invariants\t\t= ixgbe_get_invariants_X550_a_fw,\n+\t.mac_ops\t\t= &mac_ops_x550em_a,\n+\t.eeprom_ops\t\t= &eeprom_ops_X550EM_x,\n+\t.phy_ops\t\t= &phy_ops_x550em_a_fw,\n+\t.mbx_ops\t\t= &mbx_ops_generic,\n+\t.mvals\t\t\t= ixgbe_mvals_x550em_a,\n+};\n", "prefixes": [ "4/4" ] }