get:
Show a patch.

patch:
Update a patch.

put:
Update a patch.

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

{
    "id": 1033673,
    "url": "http://patchwork.ozlabs.org/api/patches/1033673/?format=api",
    "web_url": "http://patchwork.ozlabs.org/project/intel-wired-lan/patch/20190130171314.2829-1-sasha.neftin@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": "<20190130171314.2829-1-sasha.neftin@intel.com>",
    "list_archive_url": null,
    "date": "2019-01-30T17:13:14",
    "name": "[v1,1/1] igc: Add ethtool support",
    "commit_ref": null,
    "pull_url": null,
    "state": "accepted",
    "archived": false,
    "hash": "86aac2559ce6c7dd230205c774b17be333f142f9",
    "submitter": {
        "id": 69860,
        "url": "http://patchwork.ozlabs.org/api/people/69860/?format=api",
        "name": "Sasha Neftin",
        "email": "sasha.neftin@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/20190130171314.2829-1-sasha.neftin@intel.com/mbox/",
    "series": [
        {
            "id": 89123,
            "url": "http://patchwork.ozlabs.org/api/series/89123/?format=api",
            "web_url": "http://patchwork.ozlabs.org/project/intel-wired-lan/list/?series=89123",
            "date": "2019-01-30T17:13:14",
            "name": "[v1,1/1] igc: Add ethtool support",
            "version": 1,
            "mbox": "http://patchwork.ozlabs.org/series/89123/mbox/"
        }
    ],
    "comments": "http://patchwork.ozlabs.org/api/patches/1033673/comments/",
    "check": "pending",
    "checks": "http://patchwork.ozlabs.org/api/patches/1033673/checks/",
    "tags": {},
    "related": [],
    "headers": {
        "Return-Path": "<intel-wired-lan-bounces@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"
        ],
        "Authentication-Results": [
            "ozlabs.org;\n\tspf=pass (mailfrom) smtp.mailfrom=osuosl.org\n\t(client-ip=140.211.166.137; helo=fraxinus.osuosl.org;\n\tenvelope-from=intel-wired-lan-bounces@osuosl.org;\n\treceiver=<UNKNOWN>)",
            "ozlabs.org;\n\tdmarc=fail (p=none dis=none) header.from=intel.com"
        ],
        "Received": [
            "from fraxinus.osuosl.org (smtp4.osuosl.org [140.211.166.137])\n\t(using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256\n\tbits)) (No client certificate requested)\n\tby ozlabs.org (Postfix) with ESMTPS id 43qVLt6mvHz9sP0\n\tfor <incoming@patchwork.ozlabs.org>;\n\tThu, 31 Jan 2019 04:13:26 +1100 (AEDT)",
            "from localhost (localhost [127.0.0.1])\n\tby fraxinus.osuosl.org (Postfix) with ESMTP id 8E84486457;\n\tWed, 30 Jan 2019 17:13:24 +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 ybU-K6gIriAJ; Wed, 30 Jan 2019 17:13:21 +0000 (UTC)",
            "from ash.osuosl.org (ash.osuosl.org [140.211.166.34])\n\tby fraxinus.osuosl.org (Postfix) with ESMTP id 3366E8626B;\n\tWed, 30 Jan 2019 17:13:21 +0000 (UTC)",
            "from silver.osuosl.org (smtp3.osuosl.org [140.211.166.136])\n\tby ash.osuosl.org (Postfix) with ESMTP id 05C421BF39A\n\tfor <intel-wired-lan@lists.osuosl.org>;\n\tWed, 30 Jan 2019 17:13:20 +0000 (UTC)",
            "from localhost (localhost [127.0.0.1])\n\tby silver.osuosl.org (Postfix) with ESMTP id E885E30A3A\n\tfor <intel-wired-lan@lists.osuosl.org>;\n\tWed, 30 Jan 2019 17:13:19 +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 W7onSt-QGhdr for <intel-wired-lan@lists.osuosl.org>;\n\tWed, 30 Jan 2019 17:13:17 +0000 (UTC)",
            "from mga07.intel.com (mga07.intel.com [134.134.136.100])\n\tby silver.osuosl.org (Postfix) with ESMTPS id 6079822763\n\tfor <intel-wired-lan@lists.osuosl.org>;\n\tWed, 30 Jan 2019 17:13:17 +0000 (UTC)",
            "from orsmga005.jf.intel.com ([10.7.209.41])\n\tby orsmga105.jf.intel.com with ESMTP/TLS/DHE-RSA-AES256-GCM-SHA384;\n\t30 Jan 2019 09:13:16 -0800",
            "from ccdlinuxdev08.iil.intel.com ([143.185.161.150])\n\tby orsmga005.jf.intel.com with ESMTP; 30 Jan 2019 09:13: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-Amp-Result": "SKIPPED(no attachment in message)",
        "X-Amp-File-Uploaded": "False",
        "X-ExtLoop1": "1",
        "X-IronPort-AV": "E=Sophos;i=\"5.56,541,1539673200\"; d=\"scan'208\";a=\"295722784\"",
        "From": "Sasha Neftin <sasha.neftin@intel.com>",
        "To": "intel-wired-lan@lists.osuosl.org",
        "Date": "Wed, 30 Jan 2019 19:13:14 +0200",
        "Message-Id": "<20190130171314.2829-1-sasha.neftin@intel.com>",
        "X-Mailer": "git-send-email 2.11.0",
        "Subject": "[Intel-wired-lan] [PATCH v1 1/1] igc: Add ethtool support",
        "X-BeenThere": "intel-wired-lan@osuosl.org",
        "X-Mailman-Version": "2.1.29",
        "Precedence": "list",
        "List-Id": "Intel Wired Ethernet Linux Kernel Driver Development\n\t<intel-wired-lan.osuosl.org>",
        "List-Unsubscribe": "<https://lists.osuosl.org/mailman/options/intel-wired-lan>, \n\t<mailto:intel-wired-lan-request@osuosl.org?subject=unsubscribe>",
        "List-Archive": "<http://lists.osuosl.org/pipermail/intel-wired-lan/>",
        "List-Post": "<mailto:intel-wired-lan@osuosl.org>",
        "List-Help": "<mailto:intel-wired-lan-request@osuosl.org?subject=help>",
        "List-Subscribe": "<https://lists.osuosl.org/mailman/listinfo/intel-wired-lan>, \n\t<mailto:intel-wired-lan-request@osuosl.org?subject=subscribe>",
        "MIME-Version": "1.0",
        "Content-Type": "text/plain; charset=\"us-ascii\"",
        "Content-Transfer-Encoding": "7bit",
        "Errors-To": "intel-wired-lan-bounces@osuosl.org",
        "Sender": "\"Intel-wired-lan\" <intel-wired-lan-bounces@osuosl.org>"
    },
    "content": "This patch adds basic ethtool support to the device to allow\nfor configuration.\n\nSigned-off-by: Sasha Neftin <sasha.neftin@intel.com>\n---\n drivers/net/ethernet/intel/igc/Makefile      |    3 +-\n drivers/net/ethernet/intel/igc/igc.h         |   34 +-\n drivers/net/ethernet/intel/igc/igc_base.c    |    1 +\n drivers/net/ethernet/intel/igc/igc_defines.h |    4 +\n drivers/net/ethernet/intel/igc/igc_ethtool.c | 1032 ++++++++++++++++++++++++++\n drivers/net/ethernet/intel/igc/igc_hw.h      |    1 +\n drivers/net/ethernet/intel/igc/igc_main.c    |  109 ++-\n drivers/net/ethernet/intel/igc/igc_regs.h    |    3 +\n 8 files changed, 1169 insertions(+), 18 deletions(-)\n create mode 100644 drivers/net/ethernet/intel/igc/igc_ethtool.c",
    "diff": "diff --git a/drivers/net/ethernet/intel/igc/Makefile b/drivers/net/ethernet/intel/igc/Makefile\nindex 4387f6ba8e67..88c6f88baac5 100644\n--- a/drivers/net/ethernet/intel/igc/Makefile\n+++ b/drivers/net/ethernet/intel/igc/Makefile\n@@ -7,4 +7,5 @@\n \n obj-$(CONFIG_IGC) += igc.o\n \n-igc-objs := igc_main.o igc_mac.o igc_i225.o igc_base.o igc_nvm.o igc_phy.o\n+igc-objs := igc_main.o igc_mac.o igc_i225.o igc_base.o igc_nvm.o igc_phy.o \\\n+igc_ethtool.o\ndiff --git a/drivers/net/ethernet/intel/igc/igc.h b/drivers/net/ethernet/intel/igc/igc.h\nindex b1039dd3dd13..80faccc34cda 100644\n--- a/drivers/net/ethernet/intel/igc/igc.h\n+++ b/drivers/net/ethernet/intel/igc/igc.h\n@@ -13,19 +13,43 @@\n \n #include \"igc_hw.h\"\n \n-/* main */\n+/* forward declaration */\n+void igc_set_ethtool_ops(struct net_device *);\n+\n+struct igc_adapter;\n+struct igc_ring;\n+\n+void igc_up(struct igc_adapter *adapter);\n+void igc_down(struct igc_adapter *adapter);\n+int igc_setup_tx_resources(struct igc_ring *ring);\n+int igc_setup_rx_resources(struct igc_ring *ring);\n+void igc_free_tx_resources(struct igc_ring *ring);\n+void igc_free_rx_resources(struct igc_ring *ring);\n+unsigned int igc_get_max_rss_queues(struct igc_adapter *adapter);\n+void igc_set_flag_queue_pairs(struct igc_adapter *adapter,\n+\t\t\t      const u32 max_rss_queues);\n+int igc_reinit_queues(struct igc_adapter *adapter);\n+bool igc_has_link(struct igc_adapter *adapter);\n+void igc_reset(struct igc_adapter *adapter);\n+int igc_set_spd_dplx(struct igc_adapter *adapter, u32 spd, u8 dplx);\n+\n extern char igc_driver_name[];\n extern char igc_driver_version[];\n \n+#define IGC_REGS_LEN\t\t\t740\n+#define IGC_RETA_SIZE\t\t\t128\n+\n /* Interrupt defines */\n #define IGC_START_ITR\t\t\t648 /* ~6000 ints/sec */\n #define IGC_FLAG_HAS_MSI\t\tBIT(0)\n-#define IGC_FLAG_QUEUE_PAIRS\t\tBIT(4)\n+#define IGC_FLAG_QUEUE_PAIRS\t\tBIT(3)\n+#define IGC_FLAG_DMAC\t\t\tBIT(4)\n #define IGC_FLAG_NEED_LINK_UPDATE\tBIT(9)\n #define IGC_FLAG_MEDIA_RESET\t\tBIT(10)\n #define IGC_FLAG_MAS_ENABLE\t\tBIT(12)\n #define IGC_FLAG_HAS_MSIX\t\tBIT(13)\n #define IGC_FLAG_VLAN_PROMISC\t\tBIT(15)\n+#define IGC_FLAG_RX_LEGACY\t\tBIT(16)\n \n #define IGC_START_ITR\t\t\t648 /* ~6000 ints/sec */\n #define IGC_4K_ITR\t\t\t980\n@@ -60,6 +84,7 @@ extern char igc_driver_version[];\n #define IGC_RXBUFFER_2048\t\t2048\n #define IGC_RXBUFFER_3072\t\t3072\n \n+#define AUTO_ALL_MODES\t\t0\n #define IGC_RX_HDR_LEN\t\t\tIGC_RXBUFFER_256\n \n /* RX and TX descriptor control thresholds.\n@@ -340,6 +365,8 @@ struct igc_adapter {\n \n \tstruct igc_mac_addr *mac_table;\n \n+\tu8 rss_indir_tbl[IGC_RETA_SIZE];\n+\n \tunsigned long link_check_timeout;\n \tstruct igc_info ei;\n };\n@@ -418,6 +445,9 @@ static inline s32 igc_read_phy_reg(struct igc_hw *hw, u32 offset, u16 *data)\n \treturn 0;\n }\n \n+/* forward declaration */\n+void igc_reinit_locked(struct igc_adapter *);\n+\n #define igc_rx_pg_size(_ring) (PAGE_SIZE << igc_rx_pg_order(_ring))\n \n #define IGC_TXD_DCMD\t(IGC_ADVTXD_DCMD_EOP | IGC_ADVTXD_DCMD_RS)\ndiff --git a/drivers/net/ethernet/intel/igc/igc_base.c b/drivers/net/ethernet/intel/igc/igc_base.c\nindex fe9a9666c70f..51a8b8769c67 100644\n--- a/drivers/net/ethernet/intel/igc/igc_base.c\n+++ b/drivers/net/ethernet/intel/igc/igc_base.c\n@@ -131,6 +131,7 @@ static s32 igc_init_nvm_params_base(struct igc_hw *hw)\n \tif (size > 15)\n \t\tsize = 15;\n \n+\tnvm->type = igc_nvm_eeprom_spi;\n \tnvm->word_size = BIT(size);\n \tnvm->opcode_bits = 8;\n \tnvm->delay_usec = 1;\ndiff --git a/drivers/net/ethernet/intel/igc/igc_defines.h b/drivers/net/ethernet/intel/igc/igc_defines.h\nindex 8740754ea1fd..7d1bdcd1225a 100644\n--- a/drivers/net/ethernet/intel/igc/igc_defines.h\n+++ b/drivers/net/ethernet/intel/igc/igc_defines.h\n@@ -4,6 +4,10 @@\n #ifndef _IGC_DEFINES_H_\n #define _IGC_DEFINES_H_\n \n+/* Number of Transmit and Receive Descriptors must be a multiple of 8 */\n+#define REQ_TX_DESCRIPTOR_MULTIPLE  8\n+#define REQ_RX_DESCRIPTOR_MULTIPLE  8\n+\n #define IGC_CTRL_EXT_DRV_LOAD\t0x10000000 /* Drv loaded bit for FW */\n \n /* PCI Bus Info */\ndiff --git a/drivers/net/ethernet/intel/igc/igc_ethtool.c b/drivers/net/ethernet/intel/igc/igc_ethtool.c\nnew file mode 100644\nindex 000000000000..eff37a6c0afa\n--- /dev/null\n+++ b/drivers/net/ethernet/intel/igc/igc_ethtool.c\n@@ -0,0 +1,1032 @@\n+// SPDX-License-Identifier: GPL-2.0\n+/* Copyright (c)  2018 Intel Corporation */\n+\n+/* ethtool support for igc */\n+#include <linux/pm_runtime.h>\n+\n+#include \"igc.h\"\n+\n+static const char igc_priv_flags_strings[][ETH_GSTRING_LEN] = {\n+#define IGC_PRIV_FLAGS_LEGACY_RX\tBIT(0)\n+\t\"legacy-rx\",\n+};\n+\n+#define IGC_PRIV_FLAGS_STR_LEN ARRAY_SIZE(igc_priv_flags_strings)\n+\n+static void igc_get_drvinfo(struct net_device *netdev,\n+\t\t\t    struct ethtool_drvinfo *drvinfo)\n+{\n+\tstruct igc_adapter *adapter = netdev_priv(netdev);\n+\n+\tstrlcpy(drvinfo->driver,  igc_driver_name, sizeof(drvinfo->driver));\n+\tstrlcpy(drvinfo->version, igc_driver_version, sizeof(drvinfo->version));\n+\n+\t/* add fw_version here */\n+\tstrlcpy(drvinfo->bus_info, pci_name(adapter->pdev),\n+\t\tsizeof(drvinfo->bus_info));\n+\n+\tdrvinfo->n_priv_flags = IGC_PRIV_FLAGS_STR_LEN;\n+}\n+\n+static int igc_get_regs_len(struct net_device *netdev)\n+{\n+\treturn IGC_REGS_LEN * sizeof(u32);\n+}\n+\n+static void igc_get_regs(struct net_device *netdev,\n+\t\t\t struct ethtool_regs *regs, void *p)\n+{\n+\tstruct igc_adapter *adapter = netdev_priv(netdev);\n+\tstruct igc_hw *hw = &adapter->hw;\n+\tu32 *regs_buff = p;\n+\tu8 i;\n+\n+\tmemset(p, 0, IGC_REGS_LEN * sizeof(u32));\n+\n+\tregs->version = (1u << 24) | (hw->revision_id << 16) | hw->device_id;\n+\n+\t/* General Registers */\n+\tregs_buff[0] = rd32(IGC_CTRL);\n+\tregs_buff[1] = rd32(IGC_STATUS);\n+\tregs_buff[2] = rd32(IGC_CTRL_EXT);\n+\tregs_buff[3] = rd32(IGC_MDIC);\n+\tregs_buff[4] = rd32(IGC_CONNSW);\n+\n+\t/* NVM Register */\n+\tregs_buff[5] = rd32(IGC_EECD);\n+\n+\t/* Interrupt */\n+\t/* Reading EICS for EICR because they read the\n+\t * same but EICS does not clear on read\n+\t */\n+\tregs_buff[6] = rd32(IGC_EICS);\n+\tregs_buff[7] = rd32(IGC_EICS);\n+\tregs_buff[8] = rd32(IGC_EIMS);\n+\tregs_buff[9] = rd32(IGC_EIMC);\n+\tregs_buff[10] = rd32(IGC_EIAC);\n+\tregs_buff[11] = rd32(IGC_EIAM);\n+\t/* Reading ICS for ICR because they read the\n+\t * same but ICS does not clear on read\n+\t */\n+\tregs_buff[12] = rd32(IGC_ICS);\n+\tregs_buff[13] = rd32(IGC_ICS);\n+\tregs_buff[14] = rd32(IGC_IMS);\n+\tregs_buff[15] = rd32(IGC_IMC);\n+\tregs_buff[16] = rd32(IGC_IAC);\n+\tregs_buff[17] = rd32(IGC_IAM);\n+\n+\t/* Flow Control */\n+\tregs_buff[18] = rd32(IGC_FCAL);\n+\tregs_buff[19] = rd32(IGC_FCAH);\n+\tregs_buff[20] = rd32(IGC_FCTTV);\n+\tregs_buff[21] = rd32(IGC_FCRTL);\n+\tregs_buff[22] = rd32(IGC_FCRTH);\n+\tregs_buff[23] = rd32(IGC_FCRTV);\n+\n+\t/* Receive */\n+\tregs_buff[24] = rd32(IGC_RCTL);\n+\tregs_buff[25] = rd32(IGC_RXCSUM);\n+\tregs_buff[26] = rd32(IGC_RLPML);\n+\tregs_buff[27] = rd32(IGC_RFCTL);\n+\n+\t/* Transmit */\n+\tregs_buff[28] = rd32(IGC_TCTL);\n+\tregs_buff[29] = rd32(IGC_TIPG);\n+\n+\t/* Wake Up */\n+\n+\t/* MAC */\n+\n+\t/* Statistics */\n+\tregs_buff[30] = adapter->stats.crcerrs;\n+\tregs_buff[31] = adapter->stats.algnerrc;\n+\tregs_buff[32] = adapter->stats.symerrs;\n+\tregs_buff[33] = adapter->stats.rxerrc;\n+\tregs_buff[34] = adapter->stats.mpc;\n+\tregs_buff[35] = adapter->stats.scc;\n+\tregs_buff[36] = adapter->stats.ecol;\n+\tregs_buff[37] = adapter->stats.mcc;\n+\tregs_buff[38] = adapter->stats.latecol;\n+\tregs_buff[39] = adapter->stats.colc;\n+\tregs_buff[40] = adapter->stats.dc;\n+\tregs_buff[41] = adapter->stats.tncrs;\n+\tregs_buff[42] = adapter->stats.sec;\n+\tregs_buff[43] = adapter->stats.htdpmc;\n+\tregs_buff[44] = adapter->stats.rlec;\n+\tregs_buff[45] = adapter->stats.xonrxc;\n+\tregs_buff[46] = adapter->stats.xontxc;\n+\tregs_buff[47] = adapter->stats.xoffrxc;\n+\tregs_buff[48] = adapter->stats.xofftxc;\n+\tregs_buff[49] = adapter->stats.fcruc;\n+\tregs_buff[50] = adapter->stats.prc64;\n+\tregs_buff[51] = adapter->stats.prc127;\n+\tregs_buff[52] = adapter->stats.prc255;\n+\tregs_buff[53] = adapter->stats.prc511;\n+\tregs_buff[54] = adapter->stats.prc1023;\n+\tregs_buff[55] = adapter->stats.prc1522;\n+\tregs_buff[56] = adapter->stats.gprc;\n+\tregs_buff[57] = adapter->stats.bprc;\n+\tregs_buff[58] = adapter->stats.mprc;\n+\tregs_buff[59] = adapter->stats.gptc;\n+\tregs_buff[60] = adapter->stats.gorc;\n+\tregs_buff[61] = adapter->stats.gotc;\n+\tregs_buff[62] = adapter->stats.rnbc;\n+\tregs_buff[63] = adapter->stats.ruc;\n+\tregs_buff[64] = adapter->stats.rfc;\n+\tregs_buff[65] = adapter->stats.roc;\n+\tregs_buff[66] = adapter->stats.rjc;\n+\tregs_buff[67] = adapter->stats.mgprc;\n+\tregs_buff[68] = adapter->stats.mgpdc;\n+\tregs_buff[69] = adapter->stats.mgptc;\n+\tregs_buff[70] = adapter->stats.tor;\n+\tregs_buff[71] = adapter->stats.tot;\n+\tregs_buff[72] = adapter->stats.tpr;\n+\tregs_buff[73] = adapter->stats.tpt;\n+\tregs_buff[74] = adapter->stats.ptc64;\n+\tregs_buff[75] = adapter->stats.ptc127;\n+\tregs_buff[76] = adapter->stats.ptc255;\n+\tregs_buff[77] = adapter->stats.ptc511;\n+\tregs_buff[78] = adapter->stats.ptc1023;\n+\tregs_buff[79] = adapter->stats.ptc1522;\n+\tregs_buff[80] = adapter->stats.mptc;\n+\tregs_buff[81] = adapter->stats.bptc;\n+\tregs_buff[82] = adapter->stats.tsctc;\n+\tregs_buff[83] = adapter->stats.iac;\n+\tregs_buff[84] = adapter->stats.rpthc;\n+\tregs_buff[85] = adapter->stats.hgptc;\n+\tregs_buff[86] = adapter->stats.hgorc;\n+\tregs_buff[87] = adapter->stats.hgotc;\n+\tregs_buff[88] = adapter->stats.lenerrs;\n+\tregs_buff[89] = adapter->stats.scvpc;\n+\tregs_buff[90] = adapter->stats.hrmpc;\n+\n+\tfor (i = 0; i < 4; i++)\n+\t\tregs_buff[91 + i] = rd32(IGC_SRRCTL(i));\n+\tfor (i = 0; i < 4; i++)\n+\t\tregs_buff[95 + i] = rd32(IGC_PSRTYPE(i));\n+\tfor (i = 0; i < 4; i++)\n+\t\tregs_buff[99 + i] = rd32(IGC_RDBAL(i));\n+\tfor (i = 0; i < 4; i++)\n+\t\tregs_buff[103 + i] = rd32(IGC_RDBAH(i));\n+\tfor (i = 0; i < 4; i++)\n+\t\tregs_buff[107 + i] = rd32(IGC_RDLEN(i));\n+\tfor (i = 0; i < 4; i++)\n+\t\tregs_buff[111 + i] = rd32(IGC_RDH(i));\n+\tfor (i = 0; i < 4; i++)\n+\t\tregs_buff[115 + i] = rd32(IGC_RDT(i));\n+\tfor (i = 0; i < 4; i++)\n+\t\tregs_buff[119 + i] = rd32(IGC_RXDCTL(i));\n+\n+\tfor (i = 0; i < 10; i++)\n+\t\tregs_buff[123 + i] = rd32(IGC_EITR(i));\n+\tfor (i = 0; i < 16; i++)\n+\t\tregs_buff[139 + i] = rd32(IGC_RAL(i));\n+\tfor (i = 0; i < 16; i++)\n+\t\tregs_buff[145 + i] = rd32(IGC_RAH(i));\n+\n+\tfor (i = 0; i < 4; i++)\n+\t\tregs_buff[149 + i] = rd32(IGC_TDBAL(i));\n+\tfor (i = 0; i < 4; i++)\n+\t\tregs_buff[152 + i] = rd32(IGC_TDBAH(i));\n+\tfor (i = 0; i < 4; i++)\n+\t\tregs_buff[156 + i] = rd32(IGC_TDLEN(i));\n+\tfor (i = 0; i < 4; i++)\n+\t\tregs_buff[160 + i] = rd32(IGC_TDH(i));\n+\tfor (i = 0; i < 4; i++)\n+\t\tregs_buff[164 + i] = rd32(IGC_TDT(i));\n+\tfor (i = 0; i < 4; i++)\n+\t\tregs_buff[168 + i] = rd32(IGC_TXDCTL(i));\n+}\n+\n+static u32 igc_get_msglevel(struct net_device *netdev)\n+{\n+\tstruct igc_adapter *adapter = netdev_priv(netdev);\n+\n+\treturn adapter->msg_enable;\n+}\n+\n+static void igc_set_msglevel(struct net_device *netdev, u32 data)\n+{\n+\tstruct igc_adapter *adapter = netdev_priv(netdev);\n+\n+\tadapter->msg_enable = data;\n+}\n+\n+static int igc_nway_reset(struct net_device *netdev)\n+{\n+\tstruct igc_adapter *adapter = netdev_priv(netdev);\n+\n+\tif (netif_running(netdev))\n+\t\tigc_reinit_locked(adapter);\n+\treturn 0;\n+}\n+\n+static u32 igc_get_link(struct net_device *netdev)\n+{\n+\tstruct igc_adapter *adapter = netdev_priv(netdev);\n+\tstruct igc_mac_info *mac = &adapter->hw.mac;\n+\n+\t/* If the link is not reported up to netdev, interrupts are disabled,\n+\t * and so the physical link state may have changed since we last\n+\t * looked. Set get_link_status to make sure that the true link\n+\t * state is interrogated, rather than pulling a cached and possibly\n+\t * stale link state from the driver.\n+\t */\n+\tif (!netif_carrier_ok(netdev))\n+\t\tmac->get_link_status = 1;\n+\n+\treturn igc_has_link(adapter);\n+}\n+\n+static int igc_get_eeprom_len(struct net_device *netdev)\n+{\n+\tstruct igc_adapter *adapter = netdev_priv(netdev);\n+\n+\treturn adapter->hw.nvm.word_size * 2;\n+}\n+\n+static int igc_get_eeprom(struct net_device *netdev,\n+\t\t\t  struct ethtool_eeprom *eeprom, u8 *bytes)\n+{\n+\tstruct igc_adapter *adapter = netdev_priv(netdev);\n+\tstruct igc_hw *hw = &adapter->hw;\n+\tint first_word, last_word;\n+\tu16 *eeprom_buff;\n+\tint ret_val = 0;\n+\tu16 i;\n+\n+\tif (eeprom->len == 0)\n+\t\treturn -EINVAL;\n+\n+\teeprom->magic = hw->vendor_id | (hw->device_id << 16);\n+\n+\tfirst_word = eeprom->offset >> 1;\n+\tlast_word = (eeprom->offset + eeprom->len - 1) >> 1;\n+\n+\teeprom_buff = kmalloc_array(last_word - first_word + 1, sizeof(u16),\n+\t\t\t\t    GFP_KERNEL);\n+\tif (!eeprom_buff)\n+\t\treturn -ENOMEM;\n+\n+\tif (hw->nvm.type == igc_nvm_eeprom_spi) {\n+\t\tret_val = hw->nvm.ops.read(hw, first_word,\n+\t\t\t\t\t   last_word - first_word + 1,\n+\t\t\t\t\t   eeprom_buff);\n+\t} else {\n+\t\tfor (i = 0; i < last_word - first_word + 1; i++) {\n+\t\t\tret_val = hw->nvm.ops.read(hw, first_word + i, 1,\n+\t\t\t\t\t\t   &eeprom_buff[i]);\n+\t\t\tif (ret_val)\n+\t\t\t\tbreak;\n+\t\t}\n+\t}\n+\n+\t/* Device's eeprom is always little-endian, word addressable */\n+\tfor (i = 0; i < last_word - first_word + 1; i++)\n+\t\tle16_to_cpus(&eeprom_buff[i]);\n+\n+\tmemcpy(bytes, (u8 *)eeprom_buff + (eeprom->offset & 1),\n+\t       eeprom->len);\n+\tkfree(eeprom_buff);\n+\n+\treturn ret_val;\n+}\n+\n+static int igc_set_eeprom(struct net_device *netdev,\n+\t\t\t  struct ethtool_eeprom *eeprom, u8 *bytes)\n+{\n+\tstruct igc_adapter *adapter = netdev_priv(netdev);\n+\tstruct igc_hw *hw = &adapter->hw;\n+\tint max_len, first_word, last_word, ret_val = 0;\n+\tu16 *eeprom_buff;\n+\tvoid *ptr;\n+\tu16 i;\n+\n+\tif (eeprom->len == 0)\n+\t\treturn -EOPNOTSUPP;\n+\n+\tif (hw->mac.type >= igc_i225 &&\n+\t    !igc_get_flash_presence_i225(hw)) {\n+\t\treturn -EOPNOTSUPP;\n+\t}\n+\n+\tif (eeprom->magic != (hw->vendor_id | (hw->device_id << 16)))\n+\t\treturn -EFAULT;\n+\n+\tmax_len = hw->nvm.word_size * 2;\n+\n+\tfirst_word = eeprom->offset >> 1;\n+\tlast_word = (eeprom->offset + eeprom->len - 1) >> 1;\n+\teeprom_buff = kmalloc(max_len, GFP_KERNEL);\n+\tif (!eeprom_buff)\n+\t\treturn -ENOMEM;\n+\n+\tptr = (void *)eeprom_buff;\n+\n+\tif (eeprom->offset & 1) {\n+\t\t/* need read/modify/write of first changed EEPROM word\n+\t\t * only the second byte of the word is being modified\n+\t\t */\n+\t\tret_val = hw->nvm.ops.read(hw, first_word, 1,\n+\t\t\t\t\t    &eeprom_buff[0]);\n+\t\tptr++;\n+\t}\n+\tif (((eeprom->offset + eeprom->len) & 1) && ret_val == 0) {\n+\t\t/* need read/modify/write of last changed EEPROM word\n+\t\t * only the first byte of the word is being modified\n+\t\t */\n+\t\tret_val = hw->nvm.ops.read(hw, last_word, 1,\n+\t\t\t\t   &eeprom_buff[last_word - first_word]);\n+\t}\n+\n+\t/* Device's eeprom is always little-endian, word addressable */\n+\tfor (i = 0; i < last_word - first_word + 1; i++)\n+\t\tle16_to_cpus(&eeprom_buff[i]);\n+\n+\tmemcpy(ptr, bytes, eeprom->len);\n+\n+\tfor (i = 0; i < last_word - first_word + 1; i++)\n+\t\teeprom_buff[i] = cpu_to_le16(eeprom_buff[i]);\n+\n+\tret_val = hw->nvm.ops.write(hw, first_word,\n+\t\t\t\t    last_word - first_word + 1, eeprom_buff);\n+\n+\t/* Update the checksum if nvm write succeeded */\n+\tif (ret_val == 0)\n+\t\thw->nvm.ops.update(hw);\n+\n+\t/* check if need: igc_set_fw_version(adapter); */\n+\tkfree(eeprom_buff);\n+\treturn ret_val;\n+}\n+\n+static void igc_get_ringparam(struct net_device *netdev,\n+\t\t\t      struct ethtool_ringparam *ring)\n+{\n+\tstruct igc_adapter *adapter = netdev_priv(netdev);\n+\n+\tring->rx_max_pending = IGC_MAX_RXD;\n+\tring->tx_max_pending = IGC_MAX_TXD;\n+\tring->rx_pending = adapter->rx_ring_count;\n+\tring->tx_pending = adapter->tx_ring_count;\n+}\n+\n+static int igc_set_ringparam(struct net_device *netdev,\n+\t\t\t     struct ethtool_ringparam *ring)\n+{\n+\tstruct igc_adapter *adapter = netdev_priv(netdev);\n+\tstruct igc_ring *temp_ring;\n+\tu16 new_rx_count, new_tx_count;\n+\tint i, err = 0;\n+\n+\tif (ring->rx_mini_pending || ring->rx_jumbo_pending)\n+\t\treturn -EINVAL;\n+\n+\tnew_rx_count = min_t(u32, ring->rx_pending, IGC_MAX_RXD);\n+\tnew_rx_count = max_t(u16, new_rx_count, IGC_MIN_RXD);\n+\tnew_rx_count = ALIGN(new_rx_count, REQ_RX_DESCRIPTOR_MULTIPLE);\n+\n+\tnew_tx_count = min_t(u32, ring->tx_pending, IGC_MAX_TXD);\n+\tnew_tx_count = max_t(u16, new_tx_count, IGC_MIN_TXD);\n+\tnew_tx_count = ALIGN(new_tx_count, REQ_TX_DESCRIPTOR_MULTIPLE);\n+\n+\tif (new_tx_count == adapter->tx_ring_count &&\n+\t    new_rx_count == adapter->rx_ring_count) {\n+\t\t/* nothing to do */\n+\t\treturn 0;\n+\t}\n+\n+\twhile (test_and_set_bit(__IGC_RESETTING, &adapter->state))\n+\t\tusleep_range(1000, 2000);\n+\n+\tif (!netif_running(adapter->netdev)) {\n+\t\tfor (i = 0; i < adapter->num_tx_queues; i++)\n+\t\t\tadapter->tx_ring[i]->count = new_tx_count;\n+\t\tfor (i = 0; i < adapter->num_rx_queues; i++)\n+\t\t\tadapter->rx_ring[i]->count = new_rx_count;\n+\t\tadapter->tx_ring_count = new_tx_count;\n+\t\tadapter->rx_ring_count = new_rx_count;\n+\t\tgoto clear_reset;\n+\t}\n+\n+\tif (adapter->num_tx_queues > adapter->num_rx_queues)\n+\t\ttemp_ring = vmalloc(array_size(sizeof(struct igc_ring),\n+\t\t\t\t\t       adapter->num_tx_queues));\n+\telse\n+\t\ttemp_ring = vmalloc(array_size(sizeof(struct igc_ring),\n+\t\t\t\t\t       adapter->num_rx_queues));\n+\n+\tif (!temp_ring) {\n+\t\terr = -ENOMEM;\n+\t\tgoto clear_reset;\n+\t}\n+\n+\tigc_down(adapter);\n+\n+\t/* We can't just free everything and then setup again,\n+\t * because the ISRs in MSI-X mode get passed pointers\n+\t * to the Tx and Rx ring structs.\n+\t */\n+\tif (new_tx_count != adapter->tx_ring_count) {\n+\t\tfor (i = 0; i < adapter->num_tx_queues; i++) {\n+\t\t\tmemcpy(&temp_ring[i], adapter->tx_ring[i],\n+\t\t\t       sizeof(struct igc_ring));\n+\n+\t\t\ttemp_ring[i].count = new_tx_count;\n+\t\t\terr = igc_setup_tx_resources(&temp_ring[i]);\n+\t\t\tif (err) {\n+\t\t\t\twhile (i) {\n+\t\t\t\t\ti--;\n+\t\t\t\t\tigc_free_tx_resources(&temp_ring[i]);\n+\t\t\t\t}\n+\t\t\t\tgoto err_setup;\n+\t\t\t}\n+\t\t}\n+\n+\t\tfor (i = 0; i < adapter->num_tx_queues; i++) {\n+\t\t\tigc_free_tx_resources(adapter->tx_ring[i]);\n+\n+\t\t\tmemcpy(adapter->tx_ring[i], &temp_ring[i],\n+\t\t\t       sizeof(struct igc_ring));\n+\t\t}\n+\n+\t\tadapter->tx_ring_count = new_tx_count;\n+\t}\n+\n+\tif (new_rx_count != adapter->rx_ring_count) {\n+\t\tfor (i = 0; i < adapter->num_rx_queues; i++) {\n+\t\t\tmemcpy(&temp_ring[i], adapter->rx_ring[i],\n+\t\t\t       sizeof(struct igc_ring));\n+\n+\t\t\ttemp_ring[i].count = new_rx_count;\n+\t\t\terr = igc_setup_rx_resources(&temp_ring[i]);\n+\t\t\tif (err) {\n+\t\t\t\twhile (i) {\n+\t\t\t\t\ti--;\n+\t\t\t\t\tigc_free_rx_resources(&temp_ring[i]);\n+\t\t\t\t}\n+\t\t\t\tgoto err_setup;\n+\t\t\t}\n+\t\t}\n+\n+\t\tfor (i = 0; i < adapter->num_rx_queues; i++) {\n+\t\t\tigc_free_rx_resources(adapter->rx_ring[i]);\n+\n+\t\t\tmemcpy(adapter->rx_ring[i], &temp_ring[i],\n+\t\t\t       sizeof(struct igc_ring));\n+\t\t}\n+\n+\t\tadapter->rx_ring_count = new_rx_count;\n+\t}\n+err_setup:\n+\tigc_up(adapter);\n+\tvfree(temp_ring);\n+clear_reset:\n+\tclear_bit(__IGC_RESETTING, &adapter->state);\n+\treturn err;\n+}\n+\n+static void igc_get_pauseparam(struct net_device *netdev,\n+\t\t\t       struct ethtool_pauseparam *pause)\n+{\n+\tstruct igc_adapter *adapter = netdev_priv(netdev);\n+\tstruct igc_hw *hw = &adapter->hw;\n+\n+\tpause->autoneg =\n+\t\t(adapter->fc_autoneg ? AUTONEG_ENABLE : AUTONEG_DISABLE);\n+\n+\tif (hw->fc.current_mode == igc_fc_rx_pause) {\n+\t\tpause->rx_pause = 1;\n+\t} else if (hw->fc.current_mode == igc_fc_tx_pause) {\n+\t\tpause->tx_pause = 1;\n+\t} else if (hw->fc.current_mode == igc_fc_full) {\n+\t\tpause->rx_pause = 1;\n+\t\tpause->tx_pause = 1;\n+\t}\n+}\n+\n+static int igc_set_pauseparam(struct net_device *netdev,\n+\t\t\t      struct ethtool_pauseparam *pause)\n+{\n+\tstruct igc_adapter *adapter = netdev_priv(netdev);\n+\tstruct igc_hw *hw = &adapter->hw;\n+\tint retval = 0;\n+\n+\tadapter->fc_autoneg = pause->autoneg;\n+\n+\twhile (test_and_set_bit(__IGC_RESETTING, &adapter->state))\n+\t\tusleep_range(1000, 2000);\n+\n+\tif (adapter->fc_autoneg == AUTONEG_ENABLE) {\n+\t\thw->fc.requested_mode = igc_fc_default;\n+\t\tif (netif_running(adapter->netdev)) {\n+\t\t\tigc_down(adapter);\n+\t\t\tigc_up(adapter);\n+\t\t} else {\n+\t\t\tigc_reset(adapter);\n+\t\t}\n+\t} else {\n+\t\tif (pause->rx_pause && pause->tx_pause)\n+\t\t\thw->fc.requested_mode = igc_fc_full;\n+\t\telse if (pause->rx_pause && !pause->tx_pause)\n+\t\t\thw->fc.requested_mode = igc_fc_rx_pause;\n+\t\telse if (!pause->rx_pause && pause->tx_pause)\n+\t\t\thw->fc.requested_mode = igc_fc_tx_pause;\n+\t\telse if (!pause->rx_pause && !pause->tx_pause)\n+\t\t\thw->fc.requested_mode = igc_fc_none;\n+\n+\t\thw->fc.current_mode = hw->fc.requested_mode;\n+\n+\t\tretval = ((hw->phy.media_type == igc_media_type_copper) ?\n+\t\t\t  igc_force_mac_fc(hw) : igc_setup_link(hw));\n+\t}\n+\n+\tclear_bit(__IGC_RESETTING, &adapter->state);\n+\treturn retval;\n+}\n+\n+static int igc_get_coalesce(struct net_device *netdev,\n+\t\t\t    struct ethtool_coalesce *ec)\n+{\n+\tstruct igc_adapter *adapter = netdev_priv(netdev);\n+\n+\tif (adapter->rx_itr_setting <= 3)\n+\t\tec->rx_coalesce_usecs = adapter->rx_itr_setting;\n+\telse\n+\t\tec->rx_coalesce_usecs = adapter->rx_itr_setting >> 2;\n+\n+\tif (!(adapter->flags & IGC_FLAG_QUEUE_PAIRS)) {\n+\t\tif (adapter->tx_itr_setting <= 3)\n+\t\t\tec->tx_coalesce_usecs = adapter->tx_itr_setting;\n+\t\telse\n+\t\t\tec->tx_coalesce_usecs = adapter->tx_itr_setting >> 2;\n+\t}\n+\n+\treturn 0;\n+}\n+\n+static int igc_set_coalesce(struct net_device *netdev,\n+\t\t\t    struct ethtool_coalesce *ec)\n+{\n+\tstruct igc_adapter *adapter = netdev_priv(netdev);\n+\tint i;\n+\n+\tif (ec->rx_max_coalesced_frames ||\n+\t    ec->rx_coalesce_usecs_irq ||\n+\t    ec->rx_max_coalesced_frames_irq ||\n+\t    ec->tx_max_coalesced_frames ||\n+\t    ec->tx_coalesce_usecs_irq ||\n+\t    ec->stats_block_coalesce_usecs ||\n+\t    ec->use_adaptive_rx_coalesce ||\n+\t    ec->use_adaptive_tx_coalesce ||\n+\t    ec->pkt_rate_low ||\n+\t    ec->rx_coalesce_usecs_low ||\n+\t    ec->rx_max_coalesced_frames_low ||\n+\t    ec->tx_coalesce_usecs_low ||\n+\t    ec->tx_max_coalesced_frames_low ||\n+\t    ec->pkt_rate_high ||\n+\t    ec->rx_coalesce_usecs_high ||\n+\t    ec->rx_max_coalesced_frames_high ||\n+\t    ec->tx_coalesce_usecs_high ||\n+\t    ec->tx_max_coalesced_frames_high ||\n+\t    ec->rate_sample_interval)\n+\t\treturn -ENOTSUPP;\n+\n+\tif (ec->rx_coalesce_usecs > IGC_MAX_ITR_USECS ||\n+\t    (ec->rx_coalesce_usecs > 3 &&\n+\t     ec->rx_coalesce_usecs < IGC_MIN_ITR_USECS) ||\n+\t    ec->rx_coalesce_usecs == 2)\n+\t\treturn -EINVAL;\n+\n+\tif (ec->tx_coalesce_usecs > IGC_MAX_ITR_USECS ||\n+\t    (ec->tx_coalesce_usecs > 3 &&\n+\t     ec->tx_coalesce_usecs < IGC_MIN_ITR_USECS) ||\n+\t    ec->tx_coalesce_usecs == 2)\n+\t\treturn -EINVAL;\n+\n+\tif ((adapter->flags & IGC_FLAG_QUEUE_PAIRS) && ec->tx_coalesce_usecs)\n+\t\treturn -EINVAL;\n+\n+\t/* If ITR is disabled, disable DMAC */\n+\tif (ec->rx_coalesce_usecs == 0) {\n+\t\tif (adapter->flags & IGC_FLAG_DMAC)\n+\t\t\tadapter->flags &= ~IGC_FLAG_DMAC;\n+\t}\n+\n+\t/* convert to rate of irq's per second */\n+\tif (ec->rx_coalesce_usecs && ec->rx_coalesce_usecs <= 3)\n+\t\tadapter->rx_itr_setting = ec->rx_coalesce_usecs;\n+\telse\n+\t\tadapter->rx_itr_setting = ec->rx_coalesce_usecs << 2;\n+\n+\t/* convert to rate of irq's per second */\n+\tif (adapter->flags & IGC_FLAG_QUEUE_PAIRS)\n+\t\tadapter->tx_itr_setting = adapter->rx_itr_setting;\n+\telse if (ec->tx_coalesce_usecs && ec->tx_coalesce_usecs <= 3)\n+\t\tadapter->tx_itr_setting = ec->tx_coalesce_usecs;\n+\telse\n+\t\tadapter->tx_itr_setting = ec->tx_coalesce_usecs << 2;\n+\n+\tfor (i = 0; i < adapter->num_q_vectors; i++) {\n+\t\tstruct igc_q_vector *q_vector = adapter->q_vector[i];\n+\n+\t\tq_vector->tx.work_limit = adapter->tx_work_limit;\n+\t\tif (q_vector->rx.ring)\n+\t\t\tq_vector->itr_val = adapter->rx_itr_setting;\n+\t\telse\n+\t\t\tq_vector->itr_val = adapter->tx_itr_setting;\n+\t\tif (q_vector->itr_val && q_vector->itr_val <= 3)\n+\t\t\tq_vector->itr_val = IGC_START_ITR;\n+\t\tq_vector->set_itr = 1;\n+\t}\n+\n+\treturn 0;\n+}\n+\n+void igc_write_rss_indir_tbl(struct igc_adapter *adapter)\n+{\n+\tstruct igc_hw *hw = &adapter->hw;\n+\tu32 reg = IGC_RETA(0);\n+\tu32 shift = 0;\n+\tint i = 0;\n+\n+\twhile (i < IGC_RETA_SIZE) {\n+\t\tu32 val = 0;\n+\t\tint j;\n+\n+\t\tfor (j = 3; j >= 0; j--) {\n+\t\t\tval <<= 8;\n+\t\t\tval |= adapter->rss_indir_tbl[i + j];\n+\t\t}\n+\n+\t\twr32(reg, val << shift);\n+\t\treg += 4;\n+\t\ti += 4;\n+\t}\n+}\n+\n+static u32 igc_get_rxfh_indir_size(struct net_device *netdev)\n+{\n+\treturn IGC_RETA_SIZE;\n+}\n+\n+static int igc_get_rxfh(struct net_device *netdev, u32 *indir, u8 *key,\n+\t\t\tu8 *hfunc)\n+{\n+\tstruct igc_adapter *adapter = netdev_priv(netdev);\n+\tint i;\n+\n+\tif (hfunc)\n+\t\t*hfunc = ETH_RSS_HASH_TOP;\n+\tif (!indir)\n+\t\treturn 0;\n+\tfor (i = 0; i < IGC_RETA_SIZE; i++)\n+\t\tindir[i] = adapter->rss_indir_tbl[i];\n+\n+\treturn 0;\n+}\n+\n+static int igc_set_rxfh(struct net_device *netdev, const u32 *indir,\n+\t\t\tconst u8 *key, const u8 hfunc)\n+{\n+\tstruct igc_adapter *adapter = netdev_priv(netdev);\n+\tu32 num_queues;\n+\tint i;\n+\n+\t/* We do not allow change in unsupported parameters */\n+\tif (key ||\n+\t    (hfunc != ETH_RSS_HASH_NO_CHANGE && hfunc != ETH_RSS_HASH_TOP))\n+\t\treturn -EOPNOTSUPP;\n+\tif (!indir)\n+\t\treturn 0;\n+\n+\tnum_queues = adapter->rss_queues;\n+\n+\t/* Verify user input. */\n+\tfor (i = 0; i < IGC_RETA_SIZE; i++)\n+\t\tif (indir[i] >= num_queues)\n+\t\t\treturn -EINVAL;\n+\n+\tfor (i = 0; i < IGC_RETA_SIZE; i++)\n+\t\tadapter->rss_indir_tbl[i] = indir[i];\n+\n+\tigc_write_rss_indir_tbl(adapter);\n+\n+\treturn 0;\n+}\n+\n+static unsigned int igc_max_channels(struct igc_adapter *adapter)\n+{\n+\treturn igc_get_max_rss_queues(adapter);\n+}\n+\n+static void igc_get_channels(struct net_device *netdev,\n+\t\t\t     struct ethtool_channels *ch)\n+{\n+\tstruct igc_adapter *adapter = netdev_priv(netdev);\n+\n+\t/* Report maximum channels */\n+\tch->max_combined = igc_max_channels(adapter);\n+\n+\t/* Report info for other vector */\n+\tif (adapter->flags & IGC_FLAG_HAS_MSIX) {\n+\t\tch->max_other = NON_Q_VECTORS;\n+\t\tch->other_count = NON_Q_VECTORS;\n+\t}\n+\n+\tch->combined_count = adapter->rss_queues;\n+}\n+\n+static int igc_set_channels(struct net_device *netdev,\n+\t\t\t    struct ethtool_channels *ch)\n+{\n+\tstruct igc_adapter *adapter = netdev_priv(netdev);\n+\tunsigned int count = ch->combined_count;\n+\tunsigned int max_combined = 0;\n+\n+\t/* Verify they are not requesting separate vectors */\n+\tif (!count || ch->rx_count || ch->tx_count)\n+\t\treturn -EINVAL;\n+\n+\t/* Verify other_count is valid and has not been changed */\n+\tif (ch->other_count != NON_Q_VECTORS)\n+\t\treturn -EINVAL;\n+\n+\t/* Verify the number of channels doesn't exceed hw limits */\n+\tmax_combined = igc_max_channels(adapter);\n+\tif (count > max_combined)\n+\t\treturn -EINVAL;\n+\n+\tif (count != adapter->rss_queues) {\n+\t\tadapter->rss_queues = count;\n+\t\tigc_set_flag_queue_pairs(adapter, max_combined);\n+\n+\t\t/* Hardware has to reinitialize queues and interrupts to\n+\t\t * match the new configuration.\n+\t\t */\n+\t\treturn igc_reinit_queues(adapter);\n+\t}\n+\n+\treturn 0;\n+}\n+\n+static u32 igc_get_priv_flags(struct net_device *netdev)\n+{\n+\tstruct igc_adapter *adapter = netdev_priv(netdev);\n+\tu32 priv_flags = 0;\n+\n+\tif (adapter->flags & IGC_FLAG_RX_LEGACY)\n+\t\tpriv_flags |= IGC_PRIV_FLAGS_LEGACY_RX;\n+\n+\treturn priv_flags;\n+}\n+\n+static int igc_set_priv_flags(struct net_device *netdev, u32 priv_flags)\n+{\n+\tstruct igc_adapter *adapter = netdev_priv(netdev);\n+\tunsigned int flags = adapter->flags;\n+\n+\tflags &= ~IGC_FLAG_RX_LEGACY;\n+\tif (priv_flags & IGC_PRIV_FLAGS_LEGACY_RX)\n+\t\tflags |= IGC_FLAG_RX_LEGACY;\n+\n+\tif (flags != adapter->flags) {\n+\t\tadapter->flags = flags;\n+\n+\t\t/* reset interface to repopulate queues */\n+\t\tif (netif_running(netdev))\n+\t\t\tigc_reinit_locked(adapter);\n+\t}\n+\n+\treturn 0;\n+}\n+\n+static int igc_ethtool_begin(struct net_device *netdev)\n+{\n+\tstruct igc_adapter *adapter = netdev_priv(netdev);\n+\n+\tpm_runtime_get_sync(&adapter->pdev->dev);\n+\treturn 0;\n+}\n+\n+static void igc_ethtool_complete(struct net_device *netdev)\n+{\n+\tstruct igc_adapter *adapter = netdev_priv(netdev);\n+\n+\tpm_runtime_put(&adapter->pdev->dev);\n+}\n+\n+static int igc_get_link_ksettings(struct net_device *netdev,\n+\t\t\t\t  struct ethtool_link_ksettings *cmd)\n+{\n+\tstruct igc_adapter *adapter = netdev_priv(netdev);\n+\tstruct igc_hw *hw = &adapter->hw;\n+\tu32 status;\n+\tu32 speed;\n+\n+\tethtool_link_ksettings_zero_link_mode(cmd, supported);\n+\tethtool_link_ksettings_zero_link_mode(cmd, advertising);\n+\n+\t/* supported link modes */\n+\tethtool_link_ksettings_add_link_mode(cmd, supported, 10baseT_Half);\n+\tethtool_link_ksettings_add_link_mode(cmd, supported, 10baseT_Full);\n+\tethtool_link_ksettings_add_link_mode(cmd, supported, 100baseT_Half);\n+\tethtool_link_ksettings_add_link_mode(cmd, supported, 100baseT_Full);\n+\tethtool_link_ksettings_add_link_mode(cmd, supported, 1000baseT_Full);\n+\tethtool_link_ksettings_add_link_mode(cmd, supported, 2500baseT_Full);\n+\n+\t/* twisted pair */\n+\tcmd->base.port = PORT_TP;\n+\tcmd->base.phy_address = hw->phy.addr;\n+\n+\t/* advertising link modes */\n+\tethtool_link_ksettings_add_link_mode(cmd, advertising, 10baseT_Half);\n+\tethtool_link_ksettings_add_link_mode(cmd, advertising, 10baseT_Full);\n+\tethtool_link_ksettings_add_link_mode(cmd, advertising, 100baseT_Half);\n+\tethtool_link_ksettings_add_link_mode(cmd, advertising, 100baseT_Full);\n+\tethtool_link_ksettings_add_link_mode(cmd, advertising, 1000baseT_Full);\n+\tethtool_link_ksettings_add_link_mode(cmd, advertising, 2500baseT_Full);\n+\n+\t/* set autoneg settings */\n+\tif (hw->mac.autoneg == 1) {\n+\t\tethtool_link_ksettings_add_link_mode(cmd, supported, Autoneg);\n+\t\tethtool_link_ksettings_add_link_mode(cmd, advertising,\n+\t\t\t\t\t\t     Autoneg);\n+\t}\n+\n+\tswitch (hw->fc.requested_mode) {\n+\tcase igc_fc_full:\n+\t\tethtool_link_ksettings_add_link_mode(cmd, advertising, Pause);\n+\t\tbreak;\n+\tcase igc_fc_rx_pause:\n+\t\tethtool_link_ksettings_add_link_mode(cmd, advertising, Pause);\n+\t\tethtool_link_ksettings_add_link_mode(cmd, advertising,\n+\t\t\t\t\t\t     Asym_Pause);\n+\t\tbreak;\n+\tcase igc_fc_tx_pause:\n+\t\tethtool_link_ksettings_add_link_mode(cmd, advertising,\n+\t\t\t\t\t\t     Asym_Pause);\n+\t\tbreak;\n+\tdefault:\n+\t\tethtool_link_ksettings_add_link_mode(cmd, advertising, Pause);\n+\t\tethtool_link_ksettings_add_link_mode(cmd, advertising,\n+\t\t\t\t\t\t     Asym_Pause);\n+\t}\n+\n+\tstatus = rd32(IGC_STATUS);\n+\n+\tif (status & IGC_STATUS_LU) {\n+\t\tif (status & IGC_STATUS_SPEED_1000) {\n+\t\t\t/* For I225, STATUS will indicate 1G speed in both\n+\t\t\t * 1 Gbps and 2.5 Gbps link modes.\n+\t\t\t * An additional bit is used\n+\t\t\t * to differentiate between 1 Gbps and 2.5 Gbps.\n+\t\t\t */\n+\t\t\tif (hw->mac.type == igc_i225 &&\n+\t\t\t    (status & IGC_STATUS_SPEED_2500)) {\n+\t\t\t\tspeed = SPEED_2500;\n+\t\t\t\thw_dbg(\"2500 Mbs, \");\n+\t\t\t} else {\n+\t\t\t\tspeed = SPEED_1000;\n+\t\t\t\thw_dbg(\"1000 Mbs, \");\n+\t\t\t}\n+\t\t} else if (status & IGC_STATUS_SPEED_100) {\n+\t\t\tspeed = SPEED_100;\n+\t\t\thw_dbg(\"100 Mbs, \");\n+\t\t} else {\n+\t\t\tspeed = SPEED_10;\n+\t\t\thw_dbg(\"10 Mbs, \");\n+\t\t}\n+\t\tif ((status & IGC_STATUS_FD) ||\n+\t\t    hw->phy.media_type != igc_media_type_copper)\n+\t\t\tcmd->base.duplex = DUPLEX_FULL;\n+\t\telse\n+\t\t\tcmd->base.duplex = DUPLEX_HALF;\n+\t} else {\n+\t\tspeed = SPEED_UNKNOWN;\n+\t\tcmd->base.duplex = DUPLEX_UNKNOWN;\n+\t}\n+\tcmd->base.speed = speed;\n+\tif (hw->mac.autoneg)\n+\t\tcmd->base.autoneg = AUTONEG_ENABLE;\n+\telse\n+\t\tcmd->base.autoneg = AUTONEG_DISABLE;\n+\n+\t/* MDI-X => 2; MDI =>1; Invalid =>0 */\n+\tif (hw->phy.media_type == igc_media_type_copper)\n+\t\tcmd->base.eth_tp_mdix = hw->phy.is_mdix ? ETH_TP_MDI_X :\n+\t\t\t\t\t\t      ETH_TP_MDI;\n+\telse\n+\t\tcmd->base.eth_tp_mdix = ETH_TP_MDI_INVALID;\n+\n+\tif (hw->phy.mdix == AUTO_ALL_MODES)\n+\t\tcmd->base.eth_tp_mdix_ctrl = ETH_TP_MDI_AUTO;\n+\telse\n+\t\tcmd->base.eth_tp_mdix_ctrl = hw->phy.mdix;\n+\n+\treturn 0;\n+}\n+\n+static int igc_set_link_ksettings(struct net_device *netdev,\n+\t\t\t\t  const struct ethtool_link_ksettings *cmd)\n+{\n+\tstruct igc_adapter *adapter = netdev_priv(netdev);\n+\tstruct igc_hw *hw = &adapter->hw;\n+\tu32 advertising;\n+\n+\t/* When adapter in resetting mode, autoneg/speed/duplex\n+\t * cannot be changed\n+\t */\n+\tif (igc_check_reset_block(hw)) {\n+\t\tdev_err(&adapter->pdev->dev,\n+\t\t\t\"Cannot change link characteristics when reset is active.\\n\");\n+\t\treturn -EINVAL;\n+\t}\n+\n+\t/* MDI setting is only allowed when autoneg enabled because\n+\t * some hardware doesn't allow MDI setting when speed or\n+\t * duplex is forced.\n+\t */\n+\tif (cmd->base.eth_tp_mdix_ctrl) {\n+\t\tif (cmd->base.eth_tp_mdix_ctrl != ETH_TP_MDI_AUTO &&\n+\t\t    cmd->base.autoneg != AUTONEG_ENABLE) {\n+\t\t\tdev_err(&adapter->pdev->dev, \"forcing MDI/MDI-X state is not supported when link speed and/or duplex are forced\\n\");\n+\t\t\treturn -EINVAL;\n+\t\t}\n+\t}\n+\n+\twhile (test_and_set_bit(__IGC_RESETTING, &adapter->state))\n+\t\tusleep_range(1000, 2000);\n+\n+\tethtool_convert_link_mode_to_legacy_u32(&advertising,\n+\t\t\t\t\t\tcmd->link_modes.advertising);\n+\n+\tif (cmd->base.autoneg == AUTONEG_ENABLE) {\n+\t\thw->mac.autoneg = 1;\n+\t\thw->phy.autoneg_advertised = advertising;\n+\t\tif (adapter->fc_autoneg)\n+\t\t\thw->fc.requested_mode = igc_fc_default;\n+\t} else {\n+\t\t/* calling this overrides forced MDI setting */\n+\t\tdev_info(&adapter->pdev->dev,\n+\t\t\t \"Force mode currently not supported\\n\");\n+\t}\n+\n+\t/* MDI-X => 2; MDI => 1; Auto => 3 */\n+\tif (cmd->base.eth_tp_mdix_ctrl) {\n+\t\t/* fix up the value for auto (3 => 0) as zero is mapped\n+\t\t * internally to auto\n+\t\t */\n+\t\tif (cmd->base.eth_tp_mdix_ctrl == ETH_TP_MDI_AUTO)\n+\t\t\thw->phy.mdix = AUTO_ALL_MODES;\n+\t\telse\n+\t\t\thw->phy.mdix = cmd->base.eth_tp_mdix_ctrl;\n+\t}\n+\n+\t/* reset the link */\n+\tif (netif_running(adapter->netdev)) {\n+\t\tigc_down(adapter);\n+\t\tigc_up(adapter);\n+\t} else {\n+\t\tigc_reset(adapter);\n+\t}\n+\n+\tclear_bit(__IGC_RESETTING, &adapter->state);\n+\n+\treturn 0;\n+}\n+\n+static const struct ethtool_ops igc_ethtool_ops = {\n+\t.get_drvinfo\t\t= igc_get_drvinfo,\n+\t.get_regs_len\t\t= igc_get_regs_len,\n+\t.get_regs\t\t= igc_get_regs,\n+\t.get_msglevel\t\t= igc_get_msglevel,\n+\t.set_msglevel\t\t= igc_set_msglevel,\n+\t.nway_reset\t\t= igc_nway_reset,\n+\t.get_link\t\t= igc_get_link,\n+\t.get_eeprom_len\t\t= igc_get_eeprom_len,\n+\t.get_eeprom\t\t= igc_get_eeprom,\n+\t.set_eeprom\t\t= igc_set_eeprom,\n+\t.get_ringparam\t\t= igc_get_ringparam,\n+\t.set_ringparam\t\t= igc_set_ringparam,\n+\t.get_pauseparam\t\t= igc_get_pauseparam,\n+\t.set_pauseparam\t\t= igc_set_pauseparam,\n+\t.get_coalesce\t\t= igc_get_coalesce,\n+\t.set_coalesce\t\t= igc_set_coalesce,\n+\t.get_rxfh_indir_size\t= igc_get_rxfh_indir_size,\n+\t.get_rxfh\t\t= igc_get_rxfh,\n+\t.set_rxfh\t\t= igc_set_rxfh,\n+\t.get_channels\t\t= igc_get_channels,\n+\t.set_channels\t\t= igc_set_channels,\n+\t.get_priv_flags\t\t= igc_get_priv_flags,\n+\t.set_priv_flags\t\t= igc_set_priv_flags,\n+\t.begin\t\t\t= igc_ethtool_begin,\n+\t.complete\t\t= igc_ethtool_complete,\n+\t.get_link_ksettings\t= igc_get_link_ksettings,\n+\t.set_link_ksettings\t= igc_set_link_ksettings,\n+};\n+\n+void igc_set_ethtool_ops(struct net_device *netdev)\n+{\n+\tnetdev->ethtool_ops = &igc_ethtool_ops;\n+}\ndiff --git a/drivers/net/ethernet/intel/igc/igc_hw.h b/drivers/net/ethernet/intel/igc/igc_hw.h\nindex c50414f48f0d..7c88b7bd4799 100644\n--- a/drivers/net/ethernet/intel/igc/igc_hw.h\n+++ b/drivers/net/ethernet/intel/igc/igc_hw.h\n@@ -55,6 +55,7 @@ enum igc_media_type {\n \n enum igc_nvm_type {\n \tigc_nvm_unknown = 0,\n+\tigc_nvm_eeprom_spi,\n \tigc_nvm_flash_hw,\n \tigc_nvm_invm,\n };\ndiff --git a/drivers/net/ethernet/intel/igc/igc_main.c b/drivers/net/ethernet/intel/igc/igc_main.c\nindex f20183037fb2..11c75433fe22 100644\n--- a/drivers/net/ethernet/intel/igc/igc_main.c\n+++ b/drivers/net/ethernet/intel/igc/igc_main.c\n@@ -12,6 +12,8 @@\n #define DRV_VERSION\t\"0.0.1-k\"\n #define DRV_SUMMARY\t\"Intel(R) 2.5G Ethernet Linux Driver\"\n \n+#define DEFAULT_MSG_ENABLE (NETIF_MSG_DRV | NETIF_MSG_PROBE | NETIF_MSG_LINK)\n+\n static int debug = -1;\n \n MODULE_AUTHOR(\"Intel Corporation, <linux.nics@intel.com>\");\n@@ -66,7 +68,7 @@ enum latency_range {\n \tlatency_invalid = 255\n };\n \n-static void igc_reset(struct igc_adapter *adapter)\n+void igc_reset(struct igc_adapter *adapter)\n {\n \tstruct pci_dev *pdev = adapter->pdev;\n \tstruct igc_hw *hw = &adapter->hw;\n@@ -150,7 +152,7 @@ static void igc_get_hw_control(struct igc_adapter *adapter)\n  *\n  * Free all transmit software resources\n  */\n-static void igc_free_tx_resources(struct igc_ring *tx_ring)\n+void igc_free_tx_resources(struct igc_ring *tx_ring)\n {\n \tigc_clean_tx_ring(tx_ring);\n \n@@ -261,7 +263,7 @@ static void igc_clean_all_tx_rings(struct igc_adapter *adapter)\n  *\n  * Return 0 on success, negative on failure\n  */\n-static int igc_setup_tx_resources(struct igc_ring *tx_ring)\n+int igc_setup_tx_resources(struct igc_ring *tx_ring)\n {\n \tstruct device *dev = tx_ring->dev;\n \tint size = 0;\n@@ -381,7 +383,7 @@ static void igc_clean_all_rx_rings(struct igc_adapter *adapter)\n  *\n  * Free all receive software resources\n  */\n-static void igc_free_rx_resources(struct igc_ring *rx_ring)\n+void igc_free_rx_resources(struct igc_ring *rx_ring)\n {\n \tigc_clean_rx_ring(rx_ring);\n \n@@ -418,7 +420,7 @@ static void igc_free_all_rx_resources(struct igc_adapter *adapter)\n  *\n  * Returns 0 on success, negative on failure\n  */\n-static int igc_setup_rx_resources(struct igc_ring *rx_ring)\n+int igc_setup_rx_resources(struct igc_ring *rx_ring)\n {\n \tstruct device *dev = rx_ring->dev;\n \tint size, desc_len;\n@@ -1703,7 +1705,7 @@ static bool igc_clean_tx_irq(struct igc_q_vector *q_vector, int napi_budget)\n  * igc_up - Open the interface and prepare it to handle traffic\n  * @adapter: board private structure\n  */\n-static void igc_up(struct igc_adapter *adapter)\n+void igc_up(struct igc_adapter *adapter)\n {\n \tstruct igc_hw *hw = &adapter->hw;\n \tint i = 0;\n@@ -1748,7 +1750,7 @@ static void igc_nfc_filter_exit(struct igc_adapter *adapter)\n  * igc_down - Close the interface\n  * @adapter: board private structure\n  */\n-static void igc_down(struct igc_adapter *adapter)\n+void igc_down(struct igc_adapter *adapter)\n {\n \tstruct net_device *netdev = adapter->netdev;\n \tstruct igc_hw *hw = &adapter->hw;\n@@ -1810,7 +1812,7 @@ static void igc_down(struct igc_adapter *adapter)\n \tigc_clean_all_rx_rings(adapter);\n }\n \n-static void igc_reinit_locked(struct igc_adapter *adapter)\n+void igc_reinit_locked(struct igc_adapter *adapter)\n {\n \tWARN_ON(in_interrupt());\n \twhile (test_and_set_bit(__IGC_RESETTING, &adapter->state))\n@@ -1922,7 +1924,7 @@ static void igc_configure(struct igc_adapter *adapter)\n \n /**\n  * igc_rar_set_index - Sync RAL[index] and RAH[index] registers with MAC table\n- * @adapter: Pointer to adapter structure\n+ * @adapter: address of board private structure\n  * @index: Index of the RAR entry which need to be synced with MAC table\n  */\n static void igc_rar_set_index(struct igc_adapter *adapter, u32 index)\n@@ -2298,7 +2300,7 @@ static void igc_update_phy_info(struct timer_list *t)\n  * igc_has_link - check shared code for link and determine up/down\n  * @adapter: pointer to driver private info\n  */\n-static bool igc_has_link(struct igc_adapter *adapter)\n+bool igc_has_link(struct igc_adapter *adapter)\n {\n \tstruct igc_hw *hw = &adapter->hw;\n \tbool link_active = false;\n@@ -3501,6 +3503,57 @@ u32 igc_rd32(struct igc_hw *hw, u32 reg)\n \treturn value;\n }\n \n+int igc_set_spd_dplx(struct igc_adapter *adapter, u32 spd, u8 dplx)\n+{\n+\tstruct pci_dev *pdev = adapter->pdev;\n+\tstruct igc_mac_info *mac = &adapter->hw.mac;\n+\n+\tmac->autoneg = 0;\n+\n+\t/* Make sure dplx is at most 1 bit and lsb of speed is not set\n+\t * for the switch() below to work\n+\t */\n+\tif ((spd & 1) || (dplx & ~1))\n+\t\tgoto err_inval;\n+\n+\tswitch (spd + dplx) {\n+\tcase SPEED_10 + DUPLEX_HALF:\n+\t\tmac->forced_speed_duplex = ADVERTISE_10_HALF;\n+\t\tbreak;\n+\tcase SPEED_10 + DUPLEX_FULL:\n+\t\tmac->forced_speed_duplex = ADVERTISE_10_FULL;\n+\t\tbreak;\n+\tcase SPEED_100 + DUPLEX_HALF:\n+\t\tmac->forced_speed_duplex = ADVERTISE_100_HALF;\n+\t\tbreak;\n+\tcase SPEED_100 + DUPLEX_FULL:\n+\t\tmac->forced_speed_duplex = ADVERTISE_100_FULL;\n+\t\tbreak;\n+\tcase SPEED_1000 + DUPLEX_FULL:\n+\t\tmac->autoneg = 1;\n+\t\tadapter->hw.phy.autoneg_advertised = ADVERTISE_1000_FULL;\n+\t\tbreak;\n+\tcase SPEED_1000 + DUPLEX_HALF: /* not supported */\n+\t\tgoto err_inval;\n+\tcase SPEED_2500 + DUPLEX_FULL:\n+\t\tmac->autoneg = 1;\n+\t\tadapter->hw.phy.autoneg_advertised = ADVERTISE_2500_FULL;\n+\t\tbreak;\n+\tcase SPEED_2500 + DUPLEX_HALF: /* not supported */\n+\tdefault:\n+\t\tgoto err_inval;\n+\t}\n+\n+\t/* clear MDI, MDI(-X) override is only allowed when autoneg enabled */\n+\tadapter->hw.phy.mdix = AUTO_ALL_MODES;\n+\n+\treturn 0;\n+\n+err_inval:\n+\tdev_err(&pdev->dev, \"Unsupported Speed/Duplex configuration\\n\");\n+\treturn -EINVAL;\n+}\n+\n /**\n  * igc_probe - Device Initialization Routine\n  * @pdev: PCI device information struct\n@@ -3568,7 +3621,7 @@ static int igc_probe(struct pci_dev *pdev,\n \thw = &adapter->hw;\n \thw->back = adapter;\n \tadapter->port_num = hw->bus.func;\n-\tadapter->msg_enable = GENMASK(debug - 1, 0);\n+\tadapter->msg_enable = netif_msg_init(debug, DEFAULT_MSG_ENABLE);\n \n \terr = pci_save_state(pdev);\n \tif (err)\n@@ -3584,7 +3637,7 @@ static int igc_probe(struct pci_dev *pdev,\n \thw->hw_addr = adapter->io_addr;\n \n \tnetdev->netdev_ops = &igc_netdev_ops;\n-\n+\tigc_set_ethtool_ops(netdev);\n \tnetdev->watchdog_timeo = 5 * HZ;\n \n \tnetdev->mem_start = pci_resource_start(pdev, 0);\n@@ -3744,8 +3797,8 @@ static struct pci_driver igc_driver = {\n \t.remove   = igc_remove,\n };\n \n-static void igc_set_flag_queue_pairs(struct igc_adapter *adapter,\n-\t\t\t\t     const u32 max_rss_queues)\n+void igc_set_flag_queue_pairs(struct igc_adapter *adapter,\n+\t\t\t      const u32 max_rss_queues)\n {\n \t/* Determine if we need to pair queues. */\n \t/* If rss_queues > half of max_rss_queues, pair the queues in\n@@ -3757,7 +3810,7 @@ static void igc_set_flag_queue_pairs(struct igc_adapter *adapter,\n \t\tadapter->flags &= ~IGC_FLAG_QUEUE_PAIRS;\n }\n \n-static unsigned int igc_get_max_rss_queues(struct igc_adapter *adapter)\n+unsigned int igc_get_max_rss_queues(struct igc_adapter *adapter)\n {\n \tunsigned int max_rss_queues;\n \n@@ -3837,6 +3890,32 @@ static int igc_sw_init(struct igc_adapter *adapter)\n }\n \n /**\n+ * igc_reinit_queues - return error\n+ * @adapter: pointer to adapter structure\n+ */\n+int igc_reinit_queues(struct igc_adapter *adapter)\n+{\n+\tstruct net_device *netdev = adapter->netdev;\n+\tstruct pci_dev *pdev = adapter->pdev;\n+\tint err = 0;\n+\n+\tif (netif_running(netdev))\n+\t\tigc_close(netdev);\n+\n+\tigc_reset_interrupt_capability(adapter);\n+\n+\tif (igc_init_interrupt_scheme(adapter, true)) {\n+\t\tdev_err(&pdev->dev, \"Unable to allocate memory for queues\\n\");\n+\t\treturn -ENOMEM;\n+\t}\n+\n+\tif (netif_running(netdev))\n+\t\terr = igc_open(netdev);\n+\n+\treturn err;\n+}\n+\n+/**\n  * igc_get_hw_dev - return device\n  * @hw: pointer to hardware structure\n  *\ndiff --git a/drivers/net/ethernet/intel/igc/igc_regs.h b/drivers/net/ethernet/intel/igc/igc_regs.h\nindex f8c835283377..5afe7a8d3faf 100644\n--- a/drivers/net/ethernet/intel/igc/igc_regs.h\n+++ b/drivers/net/ethernet/intel/igc/igc_regs.h\n@@ -80,6 +80,9 @@\n /* MSI-X Table Register Descriptions */\n #define IGC_PBACL\t\t0x05B68  /* MSIx PBA Clear - R/W 1 to clear */\n \n+/* Redirection Table - RW Array */\n+#define IGC_RETA(_i)\t\t(0x05C00 + ((_i) * 4))\n+\n /* Receive Register Descriptions */\n #define IGC_RCTL\t\t0x00100  /* Rx Control - RW */\n #define IGC_SRRCTL(_n)\t\t(0x0C00C + ((_n) * 0x40))\n",
    "prefixes": [
        "v1",
        "1/1"
    ]
}