Patch Detail
get:
Show a patch.
patch:
Update a patch.
put:
Update a patch.
GET /api/patches/1043818/?format=api
{ "id": 1043818, "url": "http://patchwork.ozlabs.org/api/patches/1043818/?format=api", "web_url": "http://patchwork.ozlabs.org/project/intel-wired-lan/patch/20190218083731.16211-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": "<20190218083731.16211-1-sasha.neftin@intel.com>", "list_archive_url": null, "date": "2019-02-18T08:37:31", "name": "[v1,1/1] igc: Add support for statistics", "commit_ref": null, "pull_url": null, "state": "accepted", "archived": false, "hash": "97b0afd587dbda51a7dfc28ddaf03e88c00bb120", "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/20190218083731.16211-1-sasha.neftin@intel.com/mbox/", "series": [ { "id": 92588, "url": "http://patchwork.ozlabs.org/api/series/92588/?format=api", "web_url": "http://patchwork.ozlabs.org/project/intel-wired-lan/list/?series=92588", "date": "2019-02-18T08:37:31", "name": "[v1,1/1] igc: Add support for statistics", "version": 1, "mbox": "http://patchwork.ozlabs.org/series/92588/mbox/" } ], "comments": "http://patchwork.ozlabs.org/api/patches/1043818/comments/", "check": "pending", "checks": "http://patchwork.ozlabs.org/api/patches/1043818/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.136; helo=silver.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 silver.osuosl.org (smtp3.osuosl.org [140.211.166.136])\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 442y1309ddz9s3l\n\tfor <incoming@patchwork.ozlabs.org>;\n\tMon, 18 Feb 2019 19:37:42 +1100 (AEDT)", "from localhost (localhost [127.0.0.1])\n\tby silver.osuosl.org (Postfix) with ESMTP id D7B8E2226B;\n\tMon, 18 Feb 2019 08:37:40 +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 AqAWRcKvZx6V; Mon, 18 Feb 2019 08:37:36 +0000 (UTC)", "from ash.osuosl.org (ash.osuosl.org [140.211.166.34])\n\tby silver.osuosl.org (Postfix) with ESMTP id 5E262220C2;\n\tMon, 18 Feb 2019 08:37:36 +0000 (UTC)", "from fraxinus.osuosl.org (smtp4.osuosl.org [140.211.166.137])\n\tby ash.osuosl.org (Postfix) with ESMTP id 71EB01BF3C1\n\tfor <intel-wired-lan@lists.osuosl.org>;\n\tMon, 18 Feb 2019 08:37:35 +0000 (UTC)", "from localhost (localhost [127.0.0.1])\n\tby fraxinus.osuosl.org (Postfix) with ESMTP id 69E6585091\n\tfor <intel-wired-lan@lists.osuosl.org>;\n\tMon, 18 Feb 2019 08:37:35 +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 hM3SVdbweJmR for <intel-wired-lan@lists.osuosl.org>;\n\tMon, 18 Feb 2019 08:37:34 +0000 (UTC)", "from mga17.intel.com (mga17.intel.com [192.55.52.151])\n\tby fraxinus.osuosl.org (Postfix) with ESMTPS id 13E9585085\n\tfor <intel-wired-lan@lists.osuosl.org>;\n\tMon, 18 Feb 2019 08:37:34 +0000 (UTC)", "from orsmga006.jf.intel.com ([10.7.209.51])\n\tby fmsmga107.fm.intel.com with ESMTP/TLS/DHE-RSA-AES256-GCM-SHA384;\n\t18 Feb 2019 00:37:33 -0800", "from ccdlinuxdev08.iil.intel.com ([143.185.161.150])\n\tby orsmga006.jf.intel.com with ESMTP; 18 Feb 2019 00:37:31 -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.58,384,1544515200\"; d=\"scan'208\";a=\"117035379\"", "From": "Sasha Neftin <sasha.neftin@intel.com>", "To": "intel-wired-lan@lists.osuosl.org", "Date": "Mon, 18 Feb 2019 10:37:31 +0200", "Message-Id": "<20190218083731.16211-1-sasha.neftin@intel.com>", "X-Mailer": "git-send-email 2.11.0", "Subject": "[Intel-wired-lan] [PATCH v1 1/1] igc: Add support for statistics", "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": "Add support for statistics and show basic counters.\n\nSigned-off-by: Sasha Neftin <sasha.neftin@intel.com>\n---\n drivers/net/ethernet/intel/igc/igc.h | 4 +\n drivers/net/ethernet/intel/igc/igc_ethtool.c | 233 +++++++++++++++++++++++++++\n drivers/net/ethernet/intel/igc/igc_main.c | 167 ++++++++++++++++++-\n 3 files changed, 403 insertions(+), 1 deletion(-)", "diff": "diff --git a/drivers/net/ethernet/intel/igc/igc.h b/drivers/net/ethernet/intel/igc/igc.h\nindex 7eee12972d86..0f5534ce27b0 100644\n--- a/drivers/net/ethernet/intel/igc/igc.h\n+++ b/drivers/net/ethernet/intel/igc/igc.h\n@@ -37,6 +37,7 @@ int igc_add_mac_steering_filter(struct igc_adapter *adapter,\n \t\t\t\tconst u8 *addr, u8 queue, u8 flags);\n int igc_del_mac_steering_filter(struct igc_adapter *adapter,\n \t\t\t\tconst u8 *addr, u8 queue, u8 flags);\n+void igc_update_stats(struct igc_adapter *adapter);\n \n extern char igc_driver_name[];\n extern char igc_driver_version[];\n@@ -403,6 +404,9 @@ struct igc_adapter {\n \tu16 tx_ring_count;\n \tu16 rx_ring_count;\n \n+\tu32 tx_hwtstamp_timeouts;\n+\tu32 tx_hwtstamp_skipped;\n+\tu32 rx_hwtstamp_cleared;\n \tu32 *shadow_vfta;\n \n \tu32 rss_queues;\ndiff --git a/drivers/net/ethernet/intel/igc/igc_ethtool.c b/drivers/net/ethernet/intel/igc/igc_ethtool.c\nindex 25d14fc82bf8..aaa1f97d5920 100644\n--- a/drivers/net/ethernet/intel/igc/igc_ethtool.c\n+++ b/drivers/net/ethernet/intel/igc/igc_ethtool.c\n@@ -7,6 +7,115 @@\n \n #include \"igc.h\"\n \n+/* forward declaration */\n+struct igc_stats {\n+\tchar stat_string[ETH_GSTRING_LEN];\n+\tint sizeof_stat;\n+\tint stat_offset;\n+};\n+\n+#define IGC_STAT(_name, _stat) { \\\n+\t.stat_string = _name, \\\n+\t.sizeof_stat = FIELD_SIZEOF(struct igc_adapter, _stat), \\\n+\t.stat_offset = offsetof(struct igc_adapter, _stat) \\\n+}\n+\n+static const struct igc_stats igc_gstrings_stats[] = {\n+\tIGC_STAT(\"rx_packets\", stats.gprc),\n+\tIGC_STAT(\"tx_packets\", stats.gptc),\n+\tIGC_STAT(\"rx_bytes\", stats.gorc),\n+\tIGC_STAT(\"tx_bytes\", stats.gotc),\n+\tIGC_STAT(\"rx_broadcast\", stats.bprc),\n+\tIGC_STAT(\"tx_broadcast\", stats.bptc),\n+\tIGC_STAT(\"rx_multicast\", stats.mprc),\n+\tIGC_STAT(\"tx_multicast\", stats.mptc),\n+\tIGC_STAT(\"multicast\", stats.mprc),\n+\tIGC_STAT(\"collisions\", stats.colc),\n+\tIGC_STAT(\"rx_crc_errors\", stats.crcerrs),\n+\tIGC_STAT(\"rx_no_buffer_count\", stats.rnbc),\n+\tIGC_STAT(\"rx_missed_errors\", stats.mpc),\n+\tIGC_STAT(\"tx_aborted_errors\", stats.ecol),\n+\tIGC_STAT(\"tx_carrier_errors\", stats.tncrs),\n+\tIGC_STAT(\"tx_window_errors\", stats.latecol),\n+\tIGC_STAT(\"tx_abort_late_coll\", stats.latecol),\n+\tIGC_STAT(\"tx_deferred_ok\", stats.dc),\n+\tIGC_STAT(\"tx_single_coll_ok\", stats.scc),\n+\tIGC_STAT(\"tx_multi_coll_ok\", stats.mcc),\n+\tIGC_STAT(\"tx_timeout_count\", tx_timeout_count),\n+\tIGC_STAT(\"rx_long_length_errors\", stats.roc),\n+\tIGC_STAT(\"rx_short_length_errors\", stats.ruc),\n+\tIGC_STAT(\"rx_align_errors\", stats.algnerrc),\n+\tIGC_STAT(\"tx_tcp_seg_good\", stats.tsctc),\n+\tIGC_STAT(\"tx_tcp_seg_failed\", stats.tsctfc),\n+\tIGC_STAT(\"rx_flow_control_xon\", stats.xonrxc),\n+\tIGC_STAT(\"rx_flow_control_xoff\", stats.xoffrxc),\n+\tIGC_STAT(\"tx_flow_control_xon\", stats.xontxc),\n+\tIGC_STAT(\"tx_flow_control_xoff\", stats.xofftxc),\n+\tIGC_STAT(\"rx_long_byte_count\", stats.gorc),\n+\tIGC_STAT(\"tx_dma_out_of_sync\", stats.doosync),\n+\tIGC_STAT(\"tx_smbus\", stats.mgptc),\n+\tIGC_STAT(\"rx_smbus\", stats.mgprc),\n+\tIGC_STAT(\"dropped_smbus\", stats.mgpdc),\n+\tIGC_STAT(\"os2bmc_rx_by_bmc\", stats.o2bgptc),\n+\tIGC_STAT(\"os2bmc_tx_by_bmc\", stats.b2ospc),\n+\tIGC_STAT(\"os2bmc_tx_by_host\", stats.o2bspc),\n+\tIGC_STAT(\"os2bmc_rx_by_host\", stats.b2ogprc),\n+\tIGC_STAT(\"tx_hwtstamp_timeouts\", tx_hwtstamp_timeouts),\n+\tIGC_STAT(\"tx_hwtstamp_skipped\", tx_hwtstamp_skipped),\n+\tIGC_STAT(\"rx_hwtstamp_cleared\", rx_hwtstamp_cleared),\n+};\n+\n+#define IGC_NETDEV_STAT(_net_stat) { \\\n+\t.stat_string = __stringify(_net_stat), \\\n+\t.sizeof_stat = FIELD_SIZEOF(struct rtnl_link_stats64, _net_stat), \\\n+\t.stat_offset = offsetof(struct rtnl_link_stats64, _net_stat) \\\n+}\n+\n+static const struct igc_stats igc_gstrings_net_stats[] = {\n+\tIGC_NETDEV_STAT(rx_errors),\n+\tIGC_NETDEV_STAT(tx_errors),\n+\tIGC_NETDEV_STAT(tx_dropped),\n+\tIGC_NETDEV_STAT(rx_length_errors),\n+\tIGC_NETDEV_STAT(rx_over_errors),\n+\tIGC_NETDEV_STAT(rx_frame_errors),\n+\tIGC_NETDEV_STAT(rx_fifo_errors),\n+\tIGC_NETDEV_STAT(tx_fifo_errors),\n+\tIGC_NETDEV_STAT(tx_heartbeat_errors)\n+};\n+\n+enum igc_diagnostics_results {\n+\tTEST_REG = 0,\n+\tTEST_EEP,\n+\tTEST_IRQ,\n+\tTEST_LOOP,\n+\tTEST_LINK\n+};\n+\n+static const char igc_gstrings_test[][ETH_GSTRING_LEN] = {\n+\t[TEST_REG] = \"Register test (offline)\",\n+\t[TEST_EEP] = \"Eeprom test (offline)\",\n+\t[TEST_IRQ] = \"Interrupt test (offline)\",\n+\t[TEST_LOOP] = \"Loopback test (offline)\",\n+\t[TEST_LINK] = \"Link test (on/offline)\"\n+};\n+\n+#define IGC_TEST_LEN (sizeof(igc_gstrings_test) / ETH_GSTRING_LEN)\n+\n+#define IGC_GLOBAL_STATS_LEN\t\\\n+\t(sizeof(igc_gstrings_stats) / sizeof(struct igc_stats))\n+#define IGC_NETDEV_STATS_LEN\t\\\n+\t(sizeof(igc_gstrings_net_stats) / sizeof(struct igc_stats))\n+#define IGC_RX_QUEUE_STATS_LEN \\\n+\t(sizeof(struct igc_rx_queue_stats) / sizeof(u64))\n+#define IGC_TX_QUEUE_STATS_LEN 3 /* packets, bytes, restart_queue */\n+#define IGC_QUEUE_STATS_LEN \\\n+\t((((struct igc_adapter *)netdev_priv(netdev))->num_rx_queues * \\\n+\t IGC_RX_QUEUE_STATS_LEN) + \\\n+\t (((struct igc_adapter *)netdev_priv(netdev))->num_tx_queues * \\\n+\t IGC_TX_QUEUE_STATS_LEN))\n+#define IGC_STATS_LEN \\\n+\t(IGC_GLOBAL_STATS_LEN + IGC_NETDEV_STATS_LEN + IGC_QUEUE_STATS_LEN)\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@@ -546,6 +655,127 @@ static int igc_set_pauseparam(struct net_device *netdev,\n \treturn retval;\n }\n \n+static void igc_get_strings(struct net_device *netdev, u32 stringset, u8 *data)\n+{\n+\tstruct igc_adapter *adapter = netdev_priv(netdev);\n+\tu8 *p = data;\n+\tint i;\n+\n+\tswitch (stringset) {\n+\tcase ETH_SS_TEST:\n+\t\tmemcpy(data, *igc_gstrings_test,\n+\t\t IGC_TEST_LEN * ETH_GSTRING_LEN);\n+\t\tbreak;\n+\tcase ETH_SS_STATS:\n+\t\tfor (i = 0; i < IGC_GLOBAL_STATS_LEN; i++) {\n+\t\t\tmemcpy(p, igc_gstrings_stats[i].stat_string,\n+\t\t\t ETH_GSTRING_LEN);\n+\t\t\tp += ETH_GSTRING_LEN;\n+\t\t}\n+\t\tfor (i = 0; i < IGC_NETDEV_STATS_LEN; i++) {\n+\t\t\tmemcpy(p, igc_gstrings_net_stats[i].stat_string,\n+\t\t\t ETH_GSTRING_LEN);\n+\t\t\tp += ETH_GSTRING_LEN;\n+\t\t}\n+\t\tfor (i = 0; i < adapter->num_tx_queues; i++) {\n+\t\t\tsprintf(p, \"tx_queue_%u_packets\", i);\n+\t\t\tp += ETH_GSTRING_LEN;\n+\t\t\tsprintf(p, \"tx_queue_%u_bytes\", i);\n+\t\t\tp += ETH_GSTRING_LEN;\n+\t\t\tsprintf(p, \"tx_queue_%u_restart\", i);\n+\t\t\tp += ETH_GSTRING_LEN;\n+\t\t}\n+\t\tfor (i = 0; i < adapter->num_rx_queues; i++) {\n+\t\t\tsprintf(p, \"rx_queue_%u_packets\", i);\n+\t\t\tp += ETH_GSTRING_LEN;\n+\t\t\tsprintf(p, \"rx_queue_%u_bytes\", i);\n+\t\t\tp += ETH_GSTRING_LEN;\n+\t\t\tsprintf(p, \"rx_queue_%u_drops\", i);\n+\t\t\tp += ETH_GSTRING_LEN;\n+\t\t\tsprintf(p, \"rx_queue_%u_csum_err\", i);\n+\t\t\tp += ETH_GSTRING_LEN;\n+\t\t\tsprintf(p, \"rx_queue_%u_alloc_failed\", i);\n+\t\t\tp += ETH_GSTRING_LEN;\n+\t\t}\n+\t\t/* BUG_ON(p - data != IGC_STATS_LEN * ETH_GSTRING_LEN); */\n+\t\tbreak;\n+\tcase ETH_SS_PRIV_FLAGS:\n+\t\tmemcpy(data, igc_priv_flags_strings,\n+\t\t IGC_PRIV_FLAGS_STR_LEN * ETH_GSTRING_LEN);\n+\t\tbreak;\n+\t}\n+}\n+\n+static int igc_get_sset_count(struct net_device *netdev, int sset)\n+{\n+\tswitch (sset) {\n+\tcase ETH_SS_STATS:\n+\t\treturn IGC_STATS_LEN;\n+\tcase ETH_SS_TEST:\n+\t\treturn IGC_TEST_LEN;\n+\tcase ETH_SS_PRIV_FLAGS:\n+\t\treturn IGC_PRIV_FLAGS_STR_LEN;\n+\tdefault:\n+\t\treturn -ENOTSUPP;\n+\t}\n+}\n+\n+static void igc_get_ethtool_stats(struct net_device *netdev,\n+\t\t\t\t struct ethtool_stats *stats, u64 *data)\n+{\n+\tstruct igc_adapter *adapter = netdev_priv(netdev);\n+\tstruct rtnl_link_stats64 *net_stats = &adapter->stats64;\n+\tunsigned int start;\n+\tstruct igc_ring *ring;\n+\tint i, j;\n+\tchar *p;\n+\n+\tspin_lock(&adapter->stats64_lock);\n+\tigc_update_stats(adapter);\n+\n+\tfor (i = 0; i < IGC_GLOBAL_STATS_LEN; i++) {\n+\t\tp = (char *)adapter + igc_gstrings_stats[i].stat_offset;\n+\t\tdata[i] = (igc_gstrings_stats[i].sizeof_stat ==\n+\t\t\tsizeof(u64)) ? *(u64 *)p : *(u32 *)p;\n+\t}\n+\tfor (j = 0; j < IGC_NETDEV_STATS_LEN; j++, i++) {\n+\t\tp = (char *)net_stats + igc_gstrings_net_stats[j].stat_offset;\n+\t\tdata[i] = (igc_gstrings_net_stats[j].sizeof_stat ==\n+\t\t\tsizeof(u64)) ? *(u64 *)p : *(u32 *)p;\n+\t}\n+\tfor (j = 0; j < adapter->num_tx_queues; j++) {\n+\t\tu64\trestart2;\n+\n+\t\tring = adapter->tx_ring[j];\n+\t\tdo {\n+\t\t\tstart = u64_stats_fetch_begin_irq(&ring->tx_syncp);\n+\t\t\tdata[i] = ring->tx_stats.packets;\n+\t\t\tdata[i + 1] = ring->tx_stats.bytes;\n+\t\t\tdata[i + 2] = ring->tx_stats.restart_queue;\n+\t\t} while (u64_stats_fetch_retry_irq(&ring->tx_syncp, start));\n+\t\tdo {\n+\t\t\tstart = u64_stats_fetch_begin_irq(&ring->tx_syncp2);\n+\t\t\trestart2 = ring->tx_stats.restart_queue2;\n+\t\t} while (u64_stats_fetch_retry_irq(&ring->tx_syncp2, start));\n+\t\tdata[i + 2] += restart2;\n+\n+\t\ti += IGC_TX_QUEUE_STATS_LEN;\n+\t}\n+\tfor (j = 0; j < adapter->num_rx_queues; j++) {\n+\t\tring = adapter->rx_ring[j];\n+\t\tdo {\n+\t\t\tstart = u64_stats_fetch_begin_irq(&ring->rx_syncp);\n+\t\t\tdata[i] = ring->rx_stats.packets;\n+\t\t\tdata[i + 1] = ring->rx_stats.bytes;\n+\t\t\tdata[i + 2] = ring->rx_stats.drops;\n+\t\t\tdata[i + 3] = ring->rx_stats.csum_err;\n+\t\t\tdata[i + 4] = ring->rx_stats.alloc_failed;\n+\t\t} while (u64_stats_fetch_retry_irq(&ring->rx_syncp, start));\n+\t\ti += IGC_RX_QUEUE_STATS_LEN;\n+\t}\n+\tspin_unlock(&adapter->stats64_lock);\n+}\n+\n static int igc_get_coalesce(struct net_device *netdev,\n \t\t\t struct ethtool_coalesce *ec)\n {\n@@ -1611,6 +1841,9 @@ static const struct ethtool_ops igc_ethtool_ops = {\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_strings\t\t= igc_get_strings,\n+\t.get_sset_count\t\t= igc_get_sset_count,\n+\t.get_ethtool_stats\t= igc_get_ethtool_stats,\n \t.get_coalesce\t\t= igc_get_coalesce,\n \t.set_coalesce\t\t= igc_set_coalesce,\n \t.get_rxnfc\t\t= igc_get_rxnfc,\ndiff --git a/drivers/net/ethernet/intel/igc/igc_main.c b/drivers/net/ethernet/intel/igc/igc_main.c\nindex 4c8c4f9a7aa2..36b86229d839 100644\n--- a/drivers/net/ethernet/intel/igc/igc_main.c\n+++ b/drivers/net/ethernet/intel/igc/igc_main.c\n@@ -1787,8 +1787,173 @@ void igc_up(struct igc_adapter *adapter)\n * igc_update_stats - Update the board statistics counters\n * @adapter: board private structure\n */\n-static void igc_update_stats(struct igc_adapter *adapter)\n+void igc_update_stats(struct igc_adapter *adapter)\n {\n+\tstruct rtnl_link_stats64 *net_stats = &adapter->stats64;\n+\tstruct pci_dev *pdev = adapter->pdev;\n+\tstruct igc_hw *hw = &adapter->hw;\n+\tu64 _bytes, _packets;\n+\tu64 bytes, packets;\n+\tunsigned int start;\n+\tu32 mpc;\n+\tint i;\n+\n+\t/* Prevent stats update while adapter is being reset, or if the pci\n+\t * connection is down.\n+\t */\n+\tif (adapter->link_speed == 0)\n+\t\treturn;\n+\tif (pci_channel_offline(pdev))\n+\t\treturn;\n+\n+\tpackets = 0;\n+\tbytes = 0;\n+\n+\trcu_read_lock();\n+\tfor (i = 0; i < adapter->num_rx_queues; i++) {\n+\t\tstruct igc_ring *ring = adapter->rx_ring[i];\n+\t\tu32 rqdpc = rd32(IGC_RQDPC(i));\n+\n+\t\tif (hw->mac.type >= igc_i225)\n+\t\t\twr32(IGC_RQDPC(i), 0);\n+\n+\t\tif (rqdpc) {\n+\t\t\tring->rx_stats.drops += rqdpc;\n+\t\t\tnet_stats->rx_fifo_errors += rqdpc;\n+\t\t}\n+\n+\t\tdo {\n+\t\t\tstart = u64_stats_fetch_begin_irq(&ring->rx_syncp);\n+\t\t\t_bytes = ring->rx_stats.bytes;\n+\t\t\t_packets = ring->rx_stats.packets;\n+\t\t} while (u64_stats_fetch_retry_irq(&ring->rx_syncp, start));\n+\t\tbytes += _bytes;\n+\t\tpackets += _packets;\n+\t}\n+\n+\tnet_stats->rx_bytes = bytes;\n+\tnet_stats->rx_packets = packets;\n+\n+\tpackets = 0;\n+\tbytes = 0;\n+\tfor (i = 0; i < adapter->num_tx_queues; i++) {\n+\t\tstruct igc_ring *ring = adapter->tx_ring[i];\n+\n+\t\tdo {\n+\t\t\tstart = u64_stats_fetch_begin_irq(&ring->tx_syncp);\n+\t\t\t_bytes = ring->tx_stats.bytes;\n+\t\t\t_packets = ring->tx_stats.packets;\n+\t\t} while (u64_stats_fetch_retry_irq(&ring->tx_syncp, start));\n+\t\tbytes += _bytes;\n+\t\tpackets += _packets;\n+\t}\n+\tnet_stats->tx_bytes = bytes;\n+\tnet_stats->tx_packets = packets;\n+\trcu_read_unlock();\n+\n+\t/* read stats registers */\n+\tadapter->stats.crcerrs += rd32(IGC_CRCERRS);\n+\tadapter->stats.gprc += rd32(IGC_GPRC);\n+\tadapter->stats.gorc += rd32(IGC_GORCL);\n+\trd32(IGC_GORCH); /* clear GORCL */\n+\tadapter->stats.bprc += rd32(IGC_BPRC);\n+\tadapter->stats.mprc += rd32(IGC_MPRC);\n+\tadapter->stats.roc += rd32(IGC_ROC);\n+\n+\tadapter->stats.prc64 += rd32(IGC_PRC64);\n+\tadapter->stats.prc127 += rd32(IGC_PRC127);\n+\tadapter->stats.prc255 += rd32(IGC_PRC255);\n+\tadapter->stats.prc511 += rd32(IGC_PRC511);\n+\tadapter->stats.prc1023 += rd32(IGC_PRC1023);\n+\tadapter->stats.prc1522 += rd32(IGC_PRC1522);\n+\tadapter->stats.symerrs += rd32(IGC_SYMERRS);\n+\tadapter->stats.sec += rd32(IGC_SEC);\n+\n+\tmpc = rd32(IGC_MPC);\n+\tadapter->stats.mpc += mpc;\n+\tnet_stats->rx_fifo_errors += mpc;\n+\tadapter->stats.scc += rd32(IGC_SCC);\n+\tadapter->stats.ecol += rd32(IGC_ECOL);\n+\tadapter->stats.mcc += rd32(IGC_MCC);\n+\tadapter->stats.latecol += rd32(IGC_LATECOL);\n+\tadapter->stats.dc += rd32(IGC_DC);\n+\tadapter->stats.rlec += rd32(IGC_RLEC);\n+\tadapter->stats.xonrxc += rd32(IGC_XONRXC);\n+\tadapter->stats.xontxc += rd32(IGC_XONTXC);\n+\tadapter->stats.xoffrxc += rd32(IGC_XOFFRXC);\n+\tadapter->stats.xofftxc += rd32(IGC_XOFFTXC);\n+\tadapter->stats.fcruc += rd32(IGC_FCRUC);\n+\tadapter->stats.gptc += rd32(IGC_GPTC);\n+\tadapter->stats.gotc += rd32(IGC_GOTCL);\n+\trd32(IGC_GOTCH); /* clear GOTCL */\n+\tadapter->stats.rnbc += rd32(IGC_RNBC);\n+\tadapter->stats.ruc += rd32(IGC_RUC);\n+\tadapter->stats.rfc += rd32(IGC_RFC);\n+\tadapter->stats.rjc += rd32(IGC_RJC);\n+\tadapter->stats.tor += rd32(IGC_TORH);\n+\tadapter->stats.tot += rd32(IGC_TOTH);\n+\tadapter->stats.tpr += rd32(IGC_TPR);\n+\n+\tadapter->stats.ptc64 += rd32(IGC_PTC64);\n+\tadapter->stats.ptc127 += rd32(IGC_PTC127);\n+\tadapter->stats.ptc255 += rd32(IGC_PTC255);\n+\tadapter->stats.ptc511 += rd32(IGC_PTC511);\n+\tadapter->stats.ptc1023 += rd32(IGC_PTC1023);\n+\tadapter->stats.ptc1522 += rd32(IGC_PTC1522);\n+\n+\tadapter->stats.mptc += rd32(IGC_MPTC);\n+\tadapter->stats.bptc += rd32(IGC_BPTC);\n+\n+\tadapter->stats.tpt += rd32(IGC_TPT);\n+\tadapter->stats.colc += rd32(IGC_COLC);\n+\n+\tadapter->stats.algnerrc += rd32(IGC_ALGNERRC);\n+\n+\tadapter->stats.tsctc += rd32(IGC_TSCTC);\n+\tadapter->stats.tsctfc += rd32(IGC_TSCTFC);\n+\n+\tadapter->stats.iac += rd32(IGC_IAC);\n+\tadapter->stats.icrxoc += rd32(IGC_ICRXOC);\n+\tadapter->stats.icrxptc += rd32(IGC_ICRXPTC);\n+\tadapter->stats.icrxatc += rd32(IGC_ICRXATC);\n+\tadapter->stats.ictxptc += rd32(IGC_ICTXPTC);\n+\tadapter->stats.ictxatc += rd32(IGC_ICTXATC);\n+\tadapter->stats.ictxqec += rd32(IGC_ICTXQEC);\n+\tadapter->stats.ictxqmtc += rd32(IGC_ICTXQMTC);\n+\tadapter->stats.icrxdmtc += rd32(IGC_ICRXDMTC);\n+\n+\t/* Fill out the OS statistics structure */\n+\tnet_stats->multicast = adapter->stats.mprc;\n+\tnet_stats->collisions = adapter->stats.colc;\n+\n+\t/* Rx Errors */\n+\n+\t/* RLEC on some newer hardware can be incorrect so build\n+\t * our own version based on RUC and ROC\n+\t */\n+\tnet_stats->rx_errors = adapter->stats.rxerrc +\n+\t\tadapter->stats.crcerrs + adapter->stats.algnerrc +\n+\t\tadapter->stats.ruc + adapter->stats.roc +\n+\t\tadapter->stats.cexterr;\n+\tnet_stats->rx_length_errors = adapter->stats.ruc +\n+\t\t\t\t adapter->stats.roc;\n+\tnet_stats->rx_crc_errors = adapter->stats.crcerrs;\n+\tnet_stats->rx_frame_errors = adapter->stats.algnerrc;\n+\tnet_stats->rx_missed_errors = adapter->stats.mpc;\n+\n+\t/* Tx Errors */\n+\tnet_stats->tx_errors = adapter->stats.ecol +\n+\t\t\t adapter->stats.latecol;\n+\tnet_stats->tx_aborted_errors = adapter->stats.ecol;\n+\tnet_stats->tx_window_errors = adapter->stats.latecol;\n+\tnet_stats->tx_carrier_errors = adapter->stats.tncrs;\n+\n+\t/* Tx Dropped needs to be maintained elsewhere */\n+\n+\t/* Management Stats */\n+\tadapter->stats.mgptc += rd32(IGC_MGTPTC);\n+\tadapter->stats.mgprc += rd32(IGC_MGTPRC);\n+\tadapter->stats.mgpdc += rd32(IGC_MGTPDC);\n }\n \n static void igc_nfc_filter_exit(struct igc_adapter *adapter)\n", "prefixes": [ "v1", "1/1" ] }