Patch Detail
get:
Show a patch.
patch:
Update a patch.
put:
Update a patch.
GET /api/patches/961183/?format=api
{ "id": 961183, "url": "http://patchwork.ozlabs.org/api/patches/961183/?format=api", "web_url": "http://patchwork.ozlabs.org/project/intel-wired-lan/patch/20180823070603.12424-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": "<20180823070603.12424-1-sasha.neftin@intel.com>", "list_archive_url": null, "date": "2018-08-23T07:06:03", "name": "[v6,05/11] igc: Add support for Tx/Rx rings", "commit_ref": null, "pull_url": null, "state": "superseded", "archived": false, "hash": "7ee8b843e5bed6b9912e6f03ffc3fbb529be44bc", "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/20180823070603.12424-1-sasha.neftin@intel.com/mbox/", "series": [ { "id": 62082, "url": "http://patchwork.ozlabs.org/api/series/62082/?format=api", "web_url": "http://patchwork.ozlabs.org/project/intel-wired-lan/list/?series=62082", "date": "2018-08-23T07:05:52", "name": "[v6,01/11] igc: Add skeletal frame for Intel(R) 2.5G Ethernet Controller support.", "version": 6, "mbox": "http://patchwork.ozlabs.org/series/62082/mbox/" } ], "comments": "http://patchwork.ozlabs.org/api/patches/961183/comments/", "check": "pending", "checks": "http://patchwork.ozlabs.org/api/patches/961183/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.138; helo=whitealder.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 whitealder.osuosl.org (smtp1.osuosl.org [140.211.166.138])\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 41wwSW1hZXz9s3C\n\tfor <incoming@patchwork.ozlabs.org>;\n\tThu, 23 Aug 2018 17:06:34 +1000 (AEST)", "from localhost (localhost [127.0.0.1])\n\tby whitealder.osuosl.org (Postfix) with ESMTP id 7029A87726;\n\tThu, 23 Aug 2018 07:06:33 +0000 (UTC)", "from whitealder.osuosl.org ([127.0.0.1])\n\tby localhost (.osuosl.org [127.0.0.1]) (amavisd-new, port 10024)\n\twith ESMTP id FEsRRJwBFAU4; Thu, 23 Aug 2018 07:06:28 +0000 (UTC)", "from ash.osuosl.org (ash.osuosl.org [140.211.166.34])\n\tby whitealder.osuosl.org (Postfix) with ESMTP id E077A87479;\n\tThu, 23 Aug 2018 07:06:28 +0000 (UTC)", "from whitealder.osuosl.org (smtp1.osuosl.org [140.211.166.138])\n\tby ash.osuosl.org (Postfix) with ESMTP id 447EC1CF379\n\tfor <intel-wired-lan@lists.osuosl.org>;\n\tThu, 23 Aug 2018 07:06:09 +0000 (UTC)", "from localhost (localhost [127.0.0.1])\n\tby whitealder.osuosl.org (Postfix) with ESMTP id 33FB786428\n\tfor <intel-wired-lan@lists.osuosl.org>;\n\tThu, 23 Aug 2018 07:06:09 +0000 (UTC)", "from whitealder.osuosl.org ([127.0.0.1])\n\tby localhost (.osuosl.org [127.0.0.1]) (amavisd-new, port 10024)\n\twith ESMTP id SKU8JAanAK7c for <intel-wired-lan@lists.osuosl.org>;\n\tThu, 23 Aug 2018 07:06:07 +0000 (UTC)", "from mga02.intel.com (mga02.intel.com [134.134.136.20])\n\tby whitealder.osuosl.org (Postfix) with ESMTPS id C668C85BB0\n\tfor <intel-wired-lan@lists.osuosl.org>;\n\tThu, 23 Aug 2018 07:06:06 +0000 (UTC)", "from orsmga005.jf.intel.com ([10.7.209.41])\n\tby orsmga101.jf.intel.com with ESMTP/TLS/DHE-RSA-AES256-GCM-SHA384;\n\t23 Aug 2018 00:06:06 -0700", "from ccdlinuxdev08.iil.intel.com ([143.185.161.150])\n\tby orsmga005.jf.intel.com with ESMTP; 23 Aug 2018 00:06:03 -0700" ], "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.53,277,1531810800\"; d=\"scan'208\";a=\"251244142\"", "From": "Sasha Neftin <sasha.neftin@intel.com>", "To": "sasha.neftin@intel.com,\n\tintel-wired-lan@lists.osuosl.org", "Date": "Thu, 23 Aug 2018 10:06:03 +0300", "Message-Id": "<20180823070603.12424-1-sasha.neftin@intel.com>", "X-Mailer": "git-send-email 2.11.0", "Subject": "[Intel-wired-lan] [PATCH v6 05/11] igc: Add support for Tx/Rx rings", "X-BeenThere": "intel-wired-lan@osuosl.org", "X-Mailman-Version": "2.1.24", "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 change adds the defines and structures necessary to support both Tx\nand Rx descriptor rings.\n\nSasha Neftin (v2):\nfixed code indentation\n\nSasha Nedftin (v3):\nminor code fixes\n\nSasha Nedftin (v4):\nrefactor of igc_clean_tx_ring method and resovle rmmod hang problem\nremove unused code\naddress comments\nfix code indentation\nfix xmas layout\nfix header of igc_tx_buffer method\nremove duplicate defines of IGC_TX_HTHRESH and IGC_TX_PTHRESH\nfix typo\nreplace e1000_ prefix with igc_prefix\n\nSasha Nedftin (v5):\nremove unused defines\n\nSasha Nedftin (v6):\nminor cosmetic changes\n\nSigned-off-by: Sasha Neftin <sasha.neftin@intel.com>\n---\n drivers/net/ethernet/intel/igc/Makefile | 2 +-\n drivers/net/ethernet/intel/igc/igc.h | 126 +++\n drivers/net/ethernet/intel/igc/igc_base.c | 83 ++\n drivers/net/ethernet/intel/igc/igc_base.h | 89 ++\n drivers/net/ethernet/intel/igc/igc_defines.h | 43 +\n drivers/net/ethernet/intel/igc/igc_hw.h | 1 +\n drivers/net/ethernet/intel/igc/igc_main.c | 836 +++++++++++++++++++\n drivers/net/ethernet/intel/igc/igc_regs.h | 3 +\n 8 files changed, 1182 insertions(+), 1 deletion(-)\n create mode 100644 drivers/net/ethernet/intel/igc/igc_base.c\n create mode 100644 drivers/net/ethernet/intel/igc/igc_base.h", "diff": "diff --git a/drivers/net/ethernet/intel/igc/Makefile b/drivers/net/ethernet/intel/igc/Makefile\nindex 06e0b9e23a8c..c32c45300692 100644\n--- a/drivers/net/ethernet/intel/igc/Makefile\n+++ b/drivers/net/ethernet/intel/igc/Makefile\n@@ -7,4 +7,4 @@\n \n obj-$(CONFIG_IGC) += igc.o\n \n-igc-objs := igc_main.o igc_mac.o\n+igc-objs := igc_main.o igc_mac.o igc_base.o\ndiff --git a/drivers/net/ethernet/intel/igc/igc.h b/drivers/net/ethernet/intel/igc/igc.h\nindex a279bf2716b9..daf5a766285c 100644\n--- a/drivers/net/ethernet/intel/igc/igc.h\n+++ b/drivers/net/ethernet/intel/igc/igc.h\n@@ -46,6 +46,45 @@ extern char igc_driver_version[];\n #define MAX_Q_VECTORS\t\t\t8\n #define MAX_STD_JUMBO_FRAME_SIZE\t9216\n \n+/* Supported Rx Buffer Sizes */\n+#define IGC_RXBUFFER_256\t\t256\n+#define IGC_RXBUFFER_2048\t\t2048\n+#define IGC_RXBUFFER_3072\t\t3072\n+\n+#define IGC_RX_HDR_LEN\t\t\tIGC_RXBUFFER_256\n+\n+/* RX and TX descriptor control thresholds.\n+ * PTHRESH - MAC will consider prefetch if it has fewer than this number of\n+ * descriptors available in its onboard memory.\n+ * Setting this to 0 disables RX descriptor prefetch.\n+ * HTHRESH - MAC will only prefetch if there are at least this many descriptors\n+ * available in host memory.\n+ * If PTHRESH is 0, this should also be 0.\n+ * WTHRESH - RX descriptor writeback threshold - MAC will delay writing back\n+ * descriptors until either it has this many to write back, or the\n+ * ITR timer expires.\n+ */\n+#define IGC_RX_PTHRESH\t\t\t8\n+#define IGC_RX_HTHRESH\t\t\t8\n+#define IGC_TX_PTHRESH\t\t\t8\n+#define IGC_TX_HTHRESH\t\t\t1\n+#define IGC_RX_WTHRESH\t\t\t4\n+#define IGC_TX_WTHRESH\t\t\t16\n+\n+#define IGC_RX_DMA_ATTR \\\n+\t(DMA_ATTR_SKIP_CPU_SYNC | DMA_ATTR_WEAK_ORDERING)\n+\n+#define IGC_TS_HDR_LEN\t\t\t16\n+\n+#define IGC_SKB_PAD\t\t\t(NET_SKB_PAD + NET_IP_ALIGN)\n+\n+#if (PAGE_SIZE < 8192)\n+#define IGC_MAX_FRAME_BUILD_SKB \\\n+\t(SKB_WITH_OVERHEAD(IGC_RXBUFFER_2048) - IGC_SKB_PAD - IGC_TS_HDR_LEN)\n+#else\n+#define IGC_MAX_FRAME_BUILD_SKB (IGC_RXBUFFER_2048 - IGC_TS_HDR_LEN)\n+#endif\n+\n enum igc_state_t {\n \t__IGC_TESTING,\n \t__IGC_RESETTING,\n@@ -53,6 +92,34 @@ enum igc_state_t {\n \t__IGC_PTP_TX_IN_PROGRESS,\n };\n \n+/**\n+ * wrapper around a pointer to a socket buffer,\n+ * so a DMA handle can be stored along with the buffer\n+ **/\n+struct igc_tx_buffer {\n+\tunion igc_adv_tx_desc *next_to_watch;\n+\tunsigned long time_stamp;\n+\tstruct sk_buff *skb;\n+\tunsigned int bytecount;\n+\tu16 gso_segs;\n+\t__be16 protocol;\n+\n+\tDEFINE_DMA_UNMAP_ADDR(dma);\n+\tDEFINE_DMA_UNMAP_LEN(len);\n+\tu32 tx_flags;\n+};\n+\n+struct igc_rx_buffer {\n+\tdma_addr_t dma;\n+\tstruct page *page;\n+#if (BITS_PER_LONG > 32) || (PAGE_SIZE >= 65536)\n+\t__u32 page_offset;\n+#else\n+\t__u16 page_offset;\n+#endif\n+\t__u16 pagecnt_bias;\n+};\n+\n struct igc_tx_queue_stats {\n \tu64 packets;\n \tu64 bytes;\n@@ -218,4 +285,63 @@ struct igc_adapter {\n \tstruct igc_mac_addr *mac_table;\n };\n \n+/* igc_desc_unused - calculate if we have unused descriptors */\n+static inline u16 igc_desc_unused(const struct igc_ring *ring)\n+{\n+\tu16 ntc = ring->next_to_clean;\n+\tu16 ntu = ring->next_to_use;\n+\n+\treturn ((ntc > ntu) ? 0 : ring->count) + ntc - ntu - 1;\n+}\n+\n+static inline struct netdev_queue *txring_txq(const struct igc_ring *tx_ring)\n+{\n+\treturn netdev_get_tx_queue(tx_ring->netdev, tx_ring->queue_index);\n+}\n+\n+enum igc_ring_flags_t {\n+\tIGC_RING_FLAG_RX_3K_BUFFER,\n+\tIGC_RING_FLAG_RX_BUILD_SKB_ENABLED,\n+\tIGC_RING_FLAG_RX_SCTP_CSUM,\n+\tIGC_RING_FLAG_RX_LB_VLAN_BSWAP,\n+\tIGC_RING_FLAG_TX_CTX_IDX,\n+\tIGC_RING_FLAG_TX_DETECT_HANG\n+};\n+\n+#define ring_uses_large_buffer(ring) \\\n+\ttest_bit(IGC_RING_FLAG_RX_3K_BUFFER, &(ring)->flags)\n+\n+#define ring_uses_build_skb(ring) \\\n+\ttest_bit(IGC_RING_FLAG_RX_BUILD_SKB_ENABLED, &(ring)->flags)\n+\n+static inline unsigned int igc_rx_bufsz(struct igc_ring *ring)\n+{\n+#if (PAGE_SIZE < 8192)\n+\tif (ring_uses_large_buffer(ring))\n+\t\treturn IGC_RXBUFFER_3072;\n+\n+\tif (ring_uses_build_skb(ring))\n+\t\treturn IGC_MAX_FRAME_BUILD_SKB + IGC_TS_HDR_LEN;\n+#endif\n+\treturn IGC_RXBUFFER_2048;\n+}\n+\n+static inline unsigned int igc_rx_pg_order(struct igc_ring *ring)\n+{\n+#if (PAGE_SIZE < 8192)\n+\tif (ring_uses_large_buffer(ring))\n+\t\treturn 1;\n+#endif\n+\treturn 0;\n+}\n+\n+#define igc_rx_pg_size(_ring) (PAGE_SIZE << igc_rx_pg_order(_ring))\n+\n+#define IGC_RX_DESC(R, i) \\\n+\t(&(((union igc_adv_rx_desc *)((R)->desc))[i]))\n+#define IGC_TX_DESC(R, i) \\\n+\t(&(((union igc_adv_tx_desc *)((R)->desc))[i]))\n+#define IGC_TX_CTXTDESC(R, i) \\\n+\t(&(((struct igc_adv_tx_context_desc *)((R)->desc))[i]))\n+\n #endif /* _IGC_H_ */\ndiff --git a/drivers/net/ethernet/intel/igc/igc_base.c b/drivers/net/ethernet/intel/igc/igc_base.c\nnew file mode 100644\nindex 000000000000..008ddbc2228c\n--- /dev/null\n+++ b/drivers/net/ethernet/intel/igc/igc_base.c\n@@ -0,0 +1,83 @@\n+// SPDX-License-Identifier: GPL-2.0\n+/* Copyright (c) 2018 Intel Corporation */\n+\n+#include <linux/delay.h>\n+\n+#include \"igc_hw.h\"\n+#include \"igc_i225.h\"\n+\n+/**\n+ * igc_rx_fifo_flush_base - Clean rx fifo after Rx enable\n+ * @hw: pointer to the HW structure\n+ *\n+ * After Rx enable, if manageability is enabled then there is likely some\n+ * bad data at the start of the fifo and possibly in the DMA fifo. This\n+ * function clears the fifos and flushes any packets that came in as rx was\n+ * being enabled.\n+ **/\n+void igc_rx_fifo_flush_base(struct igc_hw *hw)\n+{\n+\tu32 rctl, rlpml, rxdctl[4], rfctl, temp_rctl, rx_enabled;\n+\tint i, ms_wait;\n+\n+\t/* disable IPv6 options as per hardware errata */\n+\trfctl = rd32(IGC_RFCTL);\n+\trfctl |= IGC_RFCTL_IPV6_EX_DIS;\n+\twr32(IGC_RFCTL, rfctl);\n+\n+\tif (!(rd32(IGC_MANC) & IGC_MANC_RCV_TCO_EN))\n+\t\treturn;\n+\n+\t/* Disable all Rx queues */\n+\tfor (i = 0; i < 4; i++) {\n+\t\trxdctl[i] = rd32(IGC_RXDCTL(i));\n+\t\twr32(IGC_RXDCTL(i),\n+\t\t rxdctl[i] & ~IGC_RXDCTL_QUEUE_ENABLE);\n+\t}\n+\t/* Poll all queues to verify they have shut down */\n+\tfor (ms_wait = 0; ms_wait < 10; ms_wait++) {\n+\t\tusleep_range(1000, 2000);\n+\t\trx_enabled = 0;\n+\t\tfor (i = 0; i < 4; i++)\n+\t\t\trx_enabled |= rd32(IGC_RXDCTL(i));\n+\t\tif (!(rx_enabled & IGC_RXDCTL_QUEUE_ENABLE))\n+\t\t\tbreak;\n+\t}\n+\n+\tif (ms_wait == 10)\n+\t\tpr_debug(\"Queue disable timed out after 10ms\\n\");\n+\n+\t/* Clear RLPML, RCTL.SBP, RFCTL.LEF, and set RCTL.LPE so that all\n+\t * incoming packets are rejected. Set enable and wait 2ms so that\n+\t * any packet that was coming in as RCTL.EN was set is flushed\n+\t */\n+\twr32(IGC_RFCTL, rfctl & ~IGC_RFCTL_LEF);\n+\n+\trlpml = rd32(IGC_RLPML);\n+\twr32(IGC_RLPML, 0);\n+\n+\trctl = rd32(IGC_RCTL);\n+\ttemp_rctl = rctl & ~(IGC_RCTL_EN | IGC_RCTL_SBP);\n+\ttemp_rctl |= IGC_RCTL_LPE;\n+\n+\twr32(IGC_RCTL, temp_rctl);\n+\twr32(IGC_RCTL, temp_rctl | IGC_RCTL_EN);\n+\twrfl();\n+\tusleep_range(2000, 3000);\n+\n+\t/* Enable Rx queues that were previously enabled and restore our\n+\t * previous state\n+\t */\n+\tfor (i = 0; i < 4; i++)\n+\t\twr32(IGC_RXDCTL(i), rxdctl[i]);\n+\twr32(IGC_RCTL, rctl);\n+\twrfl();\n+\n+\twr32(IGC_RLPML, rlpml);\n+\twr32(IGC_RFCTL, rfctl);\n+\n+\t/* Flush receive errors generated by workaround */\n+\trd32(IGC_ROC);\n+\trd32(IGC_RNBC);\n+\trd32(IGC_MPC);\n+}\ndiff --git a/drivers/net/ethernet/intel/igc/igc_base.h b/drivers/net/ethernet/intel/igc/igc_base.h\nnew file mode 100644\nindex 000000000000..4bdb4ecf3bc8\n--- /dev/null\n+++ b/drivers/net/ethernet/intel/igc/igc_base.h\n@@ -0,0 +1,89 @@\n+/* SPDX-License-Identifier: GPL-2.0 */\n+/* Copyright (c) 2018 Intel Corporation */\n+\n+#ifndef _IGC_BASE_H\n+#define _IGC_BASE_H\n+\n+/* forward declaration */\n+void igc_rx_fifo_flush_base(struct igc_hw *hw);\n+\n+/* Transmit Descriptor - Advanced */\n+union igc_adv_tx_desc {\n+\tstruct {\n+\t\t__le64 buffer_addr; /* Address of descriptor's data buf */\n+\t\t__le32 cmd_type_len;\n+\t\t__le32 olinfo_status;\n+\t} read;\n+\tstruct {\n+\t\t__le64 rsvd; /* Reserved */\n+\t\t__le32 nxtseq_seed;\n+\t\t__le32 status;\n+\t} wb;\n+};\n+\n+struct igc_adv_data_desc {\n+\t__le64 buffer_addr; /* Address of the descriptor's data buffer */\n+\tunion {\n+\t\tu32 data;\n+\t\tstruct {\n+\t\t\tu32 datalen:16; /* Data buffer length */\n+\t\t\tu32 rsvd:4;\n+\t\t\tu32 dtyp:4; /* Descriptor type */\n+\t\t\tu32 dcmd:8; /* Descriptor command */\n+\t\t} config;\n+\t} lower;\n+\tunion {\n+\t\tu32 data;\n+\t\tstruct {\n+\t\t\tu32 status:4; /* Descriptor status */\n+\t\t\tu32 idx:4;\n+\t\t\tu32 popts:6; /* Packet Options */\n+\t\t\tu32 paylen:18; /* Payload length */\n+\t\t} options;\n+\t} upper;\n+};\n+\n+/* Receive Descriptor - Advanced */\n+union igc_adv_rx_desc {\n+\tstruct {\n+\t\t__le64 pkt_addr; /* Packet buffer address */\n+\t\t__le64 hdr_addr; /* Header buffer address */\n+\t} read;\n+\tstruct {\n+\t\tstruct {\n+\t\t\tunion {\n+\t\t\t\t__le32 data;\n+\t\t\t\tstruct {\n+\t\t\t\t\t__le16 pkt_info; /*RSS type, Pkt type*/\n+\t\t\t\t\t/* Split Header, header buffer len */\n+\t\t\t\t\t__le16 hdr_info;\n+\t\t\t\t} hs_rss;\n+\t\t\t} lo_dword;\n+\t\t\tunion {\n+\t\t\t\t__le32 rss; /* RSS Hash */\n+\t\t\t\tstruct {\n+\t\t\t\t\t__le16 ip_id; /* IP id */\n+\t\t\t\t\t__le16 csum; /* Packet Checksum */\n+\t\t\t\t} csum_ip;\n+\t\t\t} hi_dword;\n+\t\t} lower;\n+\t\tstruct {\n+\t\t\t__le32 status_error; /* ext status/error */\n+\t\t\t__le16 length; /* Packet length */\n+\t\t\t__le16 vlan; /* VLAN tag */\n+\t\t} upper;\n+\t} wb; /* writeback */\n+};\n+\n+/* Additional Transmit Descriptor Control definitions */\n+#define IGC_TXDCTL_QUEUE_ENABLE\t0x02000000 /* Ena specific Tx Queue */\n+\n+/* Additional Receive Descriptor Control definitions */\n+#define IGC_RXDCTL_QUEUE_ENABLE\t0x02000000 /* Ena specific Rx Queue */\n+\n+/* SRRCTL bit definitions */\n+#define IGC_SRRCTL_BSIZEPKT_SHIFT\t\t10 /* Shift _right_ */\n+#define IGC_SRRCTL_BSIZEHDRSIZE_SHIFT\t\t2 /* Shift _left_ */\n+#define IGC_SRRCTL_DESCTYPE_ADV_ONEBUF\t0x02000000\n+\n+#endif /* _IGC_BASE_H */\ndiff --git a/drivers/net/ethernet/intel/igc/igc_defines.h b/drivers/net/ethernet/intel/igc/igc_defines.h\nindex fcd14dfb7517..075ad3667ad6 100644\n--- a/drivers/net/ethernet/intel/igc/igc_defines.h\n+++ b/drivers/net/ethernet/intel/igc/igc_defines.h\n@@ -54,6 +54,10 @@\n #define IGC_ICR_RXO\t\tBIT(6)\t/* Rx overrun */\n #define IGC_ICR_RXT0\t\tBIT(7)\t/* Rx timer intr (ring 0) */\n #define IGC_ICR_DRSTA\t\tBIT(30)\t/* Device Reset Asserted */\n+\n+/* If this bit asserted, the driver should claim the interrupt */\n+#define IGC_ICR_INT_ASSERTED\tBIT(31)\n+\n #define IGC_ICS_RXT0\t\tIGC_ICR_RXT0 /* Rx timer intr */\n \n #define IMS_ENABLE_MASK ( \\\n@@ -83,6 +87,45 @@\n #define IGC_GPIE_EIAME\t\t0x40000000\n #define IGC_GPIE_PBA\t\t0x80000000\n \n+/* Transmit Control */\n+#define IGC_TCTL_EN\t\t0x00000002 /* enable Tx */\n+#define IGC_TCTL_PSP\t\t0x00000008 /* pad short packets */\n+#define IGC_TCTL_CT\t\t0x00000ff0 /* collision threshold */\n+#define IGC_TCTL_COLD\t\t0x003ff000 /* collision distance */\n+#define IGC_TCTL_RTLC\t\t0x01000000 /* Re-transmit on late collision */\n+#define IGC_TCTL_MULR\t\t0x10000000 /* Multiple request support */\n+\n+#define IGC_CT_SHIFT\t\t\t4\n+#define IGC_COLLISION_THRESHOLD\t\t15\n+\n+/* Management Control */\n+#define IGC_MANC_RCV_TCO_EN\t0x00020000 /* Receive TCO Packets Enabled */\n+\n+/* Receive Control */\n+#define IGC_RCTL_RST\t\t0x00000001 /* Software reset */\n+#define IGC_RCTL_EN\t\t0x00000002 /* enable */\n+#define IGC_RCTL_SBP\t\t0x00000004 /* store bad packet */\n+#define IGC_RCTL_UPE\t\t0x00000008 /* unicast promisc enable */\n+#define IGC_RCTL_MPE\t\t0x00000010 /* multicast promisc enable */\n+#define IGC_RCTL_LPE\t\t0x00000020 /* long packet enable */\n+#define IGC_RCTL_LBM_MAC\t0x00000040 /* MAC loopback mode */\n+#define IGC_RCTL_LBM_TCVR\t0x000000C0 /* tcvr loopback mode */\n+\n+#define IGC_RCTL_RDMTS_HALF\t0x00000000 /* Rx desc min thresh size */\n+#define IGC_RCTL_BAM\t\t0x00008000 /* broadcast enable */\n+\n+/* Header split receive */\n+#define IGC_RFCTL_IPV6_EX_DIS\t0x00010000\n+#define IGC_RFCTL_LEF\t\t0x00040000\n+\n+#define IGC_RCTL_SZ_256\t\t0x00030000 /* Rx buffer size 256 */\n+\n+#define IGC_RCTL_MO_SHIFT\t12 /* multicast offset shift */\n+#define IGC_RCTL_CFIEN\t\t0x00080000 /* canonical form enable */\n+#define IGC_RCTL_DPF\t\t0x00400000 /* discard pause frames */\n+#define IGC_RCTL_PMCF\t\t0x00800000 /* pass MAC control frames */\n+#define IGC_RCTL_SECRC\t\t0x04000000 /* Strip Ethernet CRC */\n+\n #define IGC_N0_QUEUE -1\n \n #endif /* _IGC_DEFINES_H_ */\ndiff --git a/drivers/net/ethernet/intel/igc/igc_hw.h b/drivers/net/ethernet/intel/igc/igc_hw.h\nindex 46e4e1aa860c..ae728ce2c672 100644\n--- a/drivers/net/ethernet/intel/igc/igc_hw.h\n+++ b/drivers/net/ethernet/intel/igc/igc_hw.h\n@@ -10,6 +10,7 @@\n #include \"igc_defines.h\"\n #include \"igc_mac.h\"\n #include \"igc_i225.h\"\n+#include \"igc_base.h\"\n \n #define IGC_DEV_ID_I225_LM\t\t\t0x15F2\n #define IGC_DEV_ID_I225_V\t\t\t0x15F3\ndiff --git a/drivers/net/ethernet/intel/igc/igc_main.c b/drivers/net/ethernet/intel/igc/igc_main.c\nindex e663db1e03bb..c210791bbf49 100644\n--- a/drivers/net/ethernet/intel/igc/igc_main.c\n+++ b/drivers/net/ethernet/intel/igc/igc_main.c\n@@ -29,11 +29,21 @@ static const struct pci_device_id igc_pci_tbl[] = {\n MODULE_DEVICE_TABLE(pci, igc_pci_tbl);\n \n /* forward declaration */\n+static int igc_setup_all_tx_resources(struct igc_adapter *adapter);\n+static void igc_clean_tx_ring(struct igc_ring *tx_ring);\n+static void igc_free_all_tx_resources(struct igc_adapter *adapter);\n+static int igc_setup_all_rx_resources(struct igc_adapter *adapter);\n static int igc_sw_init(struct igc_adapter *);\n static void igc_configure(struct igc_adapter *adapter);\n+static void igc_configure_tx(struct igc_adapter *);\n+static void igc_configure_rx(struct igc_adapter *adapter);\n static void igc_power_down_link(struct igc_adapter *adapter);\n static void igc_set_default_mac_filter(struct igc_adapter *adapter);\n+static void igc_set_rx_mode(struct net_device *netdev);\n+static void igc_setup_mrqc(struct igc_adapter *adapter);\n static irqreturn_t igc_msix_ring(int irq, void *data);\n+static irqreturn_t igc_intr_msi(int irq, void *data);\n+static irqreturn_t igc_intr(int irq, void *data);\n static void igc_write_itr(struct igc_q_vector *q_vector);\n static int igc_request_msix(struct igc_adapter *adapter);\n static void igc_assign_vector(struct igc_q_vector *q_vector, int msix_vector);\n@@ -124,6 +134,527 @@ static void igc_get_hw_control(struct igc_adapter *adapter)\n \t ctrl_ext | IGC_CTRL_EXT_DRV_LOAD);\n }\n \n+/**\n+ * igc_free_tx_resources - Free Tx Resources per Queue\n+ * @tx_ring: Tx descriptor ring for a specific queue\n+ *\n+ * Free all transmit software resources\n+ **/\n+static void igc_free_tx_resources(struct igc_ring *tx_ring)\n+{\n+\tigc_clean_tx_ring(tx_ring);\n+\n+\tvfree(tx_ring->tx_buffer_info);\n+\ttx_ring->tx_buffer_info = NULL;\n+\n+\t/* if not set, then don't free */\n+\tif (!tx_ring->desc)\n+\t\treturn;\n+\n+\tdma_free_coherent(tx_ring->dev, tx_ring->size,\n+\t\t\t tx_ring->desc, tx_ring->dma);\n+\n+\ttx_ring->desc = NULL;\n+}\n+\n+/**\n+ * igc_free_all_tx_resources - Free Tx Resources for All Queues\n+ * @adapter: board private structure\n+ *\n+ * Free all transmit software resources\n+ **/\n+static void igc_free_all_tx_resources(struct igc_adapter *adapter)\n+{\n+\tint i;\n+\n+\tfor (i = 0; i < adapter->num_tx_queues; i++)\n+\t\tigc_free_tx_resources(adapter->tx_ring[i]);\n+}\n+\n+/**\n+ * igc_clean_tx_ring - Free Tx Buffers\n+ * @tx_ring: ring to be cleaned\n+ **/\n+static void igc_clean_tx_ring(struct igc_ring *tx_ring)\n+{\n+\tu16 i = tx_ring->next_to_clean;\n+\tstruct igc_tx_buffer *tx_buffer = &tx_ring->tx_buffer_info[i];\n+\n+\twhile (i != tx_ring->next_to_use) {\n+\t\tunion igc_adv_tx_desc *eop_desc, *tx_desc;\n+\n+\t\t/* Free all the Tx ring sk_buffs */\n+\t\tdev_kfree_skb_any(tx_buffer->skb);\n+\n+\t\t/* unmap skb header data */\n+\t\tdma_unmap_single(tx_ring->dev,\n+\t\t\t\t dma_unmap_addr(tx_buffer, dma),\n+\t\t\t\t dma_unmap_len(tx_buffer, len),\n+\t\t\t\t DMA_TO_DEVICE);\n+\n+\t\t/* check for eop_desc to determine the end of the packet */\n+\t\teop_desc = tx_buffer->next_to_watch;\n+\t\ttx_desc = IGC_TX_DESC(tx_ring, i);\n+\n+\t\t/* unmap remaining buffers */\n+\t\twhile (tx_desc != eop_desc) {\n+\t\t\ttx_buffer++;\n+\t\t\ttx_desc++;\n+\t\t\ti++;\n+\t\t\tif (unlikely(i == tx_ring->count)) {\n+\t\t\t\ti = 0;\n+\t\t\t\ttx_buffer = tx_ring->tx_buffer_info;\n+\t\t\t\ttx_desc = IGC_TX_DESC(tx_ring, 0);\n+\t\t\t}\n+\n+\t\t\t/* unmap any remaining paged data */\n+\t\t\tif (dma_unmap_len(tx_buffer, len))\n+\t\t\t\tdma_unmap_page(tx_ring->dev,\n+\t\t\t\t\t dma_unmap_addr(tx_buffer, dma),\n+\t\t\t\t\t dma_unmap_len(tx_buffer, len),\n+\t\t\t\t\t DMA_TO_DEVICE);\n+\t\t}\n+\n+\t\t/* move us one more past the eop_desc for start of next pkt */\n+\t\ttx_buffer++;\n+\t\ti++;\n+\t\tif (unlikely(i == tx_ring->count)) {\n+\t\t\ti = 0;\n+\t\t\ttx_buffer = tx_ring->tx_buffer_info;\n+\t\t}\n+\t}\n+\n+\t/* reset BQL for queue */\n+\tnetdev_tx_reset_queue(txring_txq(tx_ring));\n+\n+\t/* reset next_to_use and next_to_clean */\n+\ttx_ring->next_to_use = 0;\n+\ttx_ring->next_to_clean = 0;\n+}\n+\n+/**\n+ * igc_setup_tx_resources - allocate Tx resources (Descriptors)\n+ * @tx_ring: tx descriptor ring (for a specific queue) to setup\n+ *\n+ * Return 0 on success, negative on failure\n+ **/\n+static int igc_setup_tx_resources(struct igc_ring *tx_ring)\n+{\n+\tstruct device *dev = tx_ring->dev;\n+\tint size = 0;\n+\n+\tsize = sizeof(struct igc_tx_buffer) * tx_ring->count;\n+\ttx_ring->tx_buffer_info = vzalloc(size);\n+\tif (!tx_ring->tx_buffer_info)\n+\t\tgoto err;\n+\n+\t/* round up to nearest 4K */\n+\ttx_ring->size = tx_ring->count * sizeof(union igc_adv_tx_desc);\n+\ttx_ring->size = ALIGN(tx_ring->size, 4096);\n+\n+\ttx_ring->desc = dma_alloc_coherent(dev, tx_ring->size,\n+\t\t\t\t\t &tx_ring->dma, GFP_KERNEL);\n+\n+\tif (!tx_ring->desc)\n+\t\tgoto err;\n+\n+\ttx_ring->next_to_use = 0;\n+\ttx_ring->next_to_clean = 0;\n+\n+\treturn 0;\n+\n+err:\n+\tvfree(tx_ring->tx_buffer_info);\n+\tdev_err(dev,\n+\t\t\"Unable to allocate memory for the transmit descriptor ring\\n\");\n+\treturn -ENOMEM;\n+}\n+\n+/**\n+ * igc_setup_all_tx_resources - wrapper to allocate Tx resources for all queues\n+ * @adapter: board private structure\n+ *\n+ * Return 0 on success, negative on failure\n+ **/\n+static int igc_setup_all_tx_resources(struct igc_adapter *adapter)\n+{\n+\tstruct pci_dev *pdev = adapter->pdev;\n+\tint i, err = 0;\n+\n+\tfor (i = 0; i < adapter->num_tx_queues; i++) {\n+\t\terr = igc_setup_tx_resources(adapter->tx_ring[i]);\n+\t\tif (err) {\n+\t\t\tdev_err(&pdev->dev,\n+\t\t\t\t\"Allocation for Tx Queue %u failed\\n\", i);\n+\t\t\tfor (i--; i >= 0; i--)\n+\t\t\t\tigc_free_tx_resources(adapter->tx_ring[i]);\n+\t\t\tbreak;\n+\t\t}\n+\t}\n+\n+\treturn err;\n+}\n+\n+/**\n+ * igc_clean_rx_ring - Free Rx Buffers per Queue\n+ * @rx_ring: ring to free buffers from\n+ **/\n+static void igc_clean_rx_ring(struct igc_ring *rx_ring)\n+{\n+\tu16 i = rx_ring->next_to_clean;\n+\n+\tif (rx_ring->skb)\n+\t\tdev_kfree_skb(rx_ring->skb);\n+\trx_ring->skb = NULL;\n+\n+\t/* Free all the Rx ring sk_buffs */\n+\twhile (i != rx_ring->next_to_alloc) {\n+\t\tstruct igc_rx_buffer *buffer_info = &rx_ring->rx_buffer_info[i];\n+\n+\t\t/* Invalidate cache lines that may have been written to by\n+\t\t * device so that we avoid corrupting memory.\n+\t\t */\n+\t\tdma_sync_single_range_for_cpu(rx_ring->dev,\n+\t\t\t\t\t buffer_info->dma,\n+\t\t\t\t\t buffer_info->page_offset,\n+\t\t\t\t\t igc_rx_bufsz(rx_ring),\n+\t\t\t\t\t DMA_FROM_DEVICE);\n+\n+\t\t/* free resources associated with mapping */\n+\t\tdma_unmap_page_attrs(rx_ring->dev,\n+\t\t\t\t buffer_info->dma,\n+\t\t\t\t igc_rx_pg_size(rx_ring),\n+\t\t\t\t DMA_FROM_DEVICE,\n+\t\t\t\t IGC_RX_DMA_ATTR);\n+\t\t__page_frag_cache_drain(buffer_info->page,\n+\t\t\t\t\tbuffer_info->pagecnt_bias);\n+\n+\t\ti++;\n+\t\tif (i == rx_ring->count)\n+\t\t\ti = 0;\n+\t}\n+\n+\trx_ring->next_to_alloc = 0;\n+\trx_ring->next_to_clean = 0;\n+\trx_ring->next_to_use = 0;\n+}\n+\n+/**\n+ * igc_free_rx_resources - Free Rx Resources\n+ * @rx_ring: ring to clean the resources from\n+ *\n+ * Free all receive software resources\n+ **/\n+static void igc_free_rx_resources(struct igc_ring *rx_ring)\n+{\n+\tigc_clean_rx_ring(rx_ring);\n+\n+\tvfree(rx_ring->rx_buffer_info);\n+\trx_ring->rx_buffer_info = NULL;\n+\n+\t/* if not set, then don't free */\n+\tif (!rx_ring->desc)\n+\t\treturn;\n+\n+\tdma_free_coherent(rx_ring->dev, rx_ring->size,\n+\t\t\t rx_ring->desc, rx_ring->dma);\n+\n+\trx_ring->desc = NULL;\n+}\n+\n+/**\n+ * igc_free_all_rx_resources - Free Rx Resources for All Queues\n+ * @adapter: board private structure\n+ *\n+ * Free all receive software resources\n+ **/\n+static void igc_free_all_rx_resources(struct igc_adapter *adapter)\n+{\n+\tint i;\n+\n+\tfor (i = 0; i < adapter->num_rx_queues; i++)\n+\t\tigc_free_rx_resources(adapter->rx_ring[i]);\n+}\n+\n+/**\n+ * igc_setup_rx_resources - allocate Rx resources (Descriptors)\n+ * @rx_ring: rx descriptor ring (for a specific queue) to setup\n+ *\n+ * Returns 0 on success, negative on failure\n+ **/\n+static int igc_setup_rx_resources(struct igc_ring *rx_ring)\n+{\n+\tstruct device *dev = rx_ring->dev;\n+\tint size, desc_len;\n+\n+\tsize = sizeof(struct igc_rx_buffer) * rx_ring->count;\n+\trx_ring->rx_buffer_info = vzalloc(size);\n+\tif (!rx_ring->rx_buffer_info)\n+\t\tgoto err;\n+\n+\tdesc_len = sizeof(union igc_adv_rx_desc);\n+\n+\t/* Round up to nearest 4K */\n+\trx_ring->size = rx_ring->count * desc_len;\n+\trx_ring->size = ALIGN(rx_ring->size, 4096);\n+\n+\trx_ring->desc = dma_alloc_coherent(dev, rx_ring->size,\n+\t\t\t\t\t &rx_ring->dma, GFP_KERNEL);\n+\n+\tif (!rx_ring->desc)\n+\t\tgoto err;\n+\n+\trx_ring->next_to_alloc = 0;\n+\trx_ring->next_to_clean = 0;\n+\trx_ring->next_to_use = 0;\n+\n+\treturn 0;\n+\n+err:\n+\tvfree(rx_ring->rx_buffer_info);\n+\trx_ring->rx_buffer_info = NULL;\n+\tdev_err(dev,\n+\t\t\"Unable to allocate memory for the receive descriptor ring\\n\");\n+\treturn -ENOMEM;\n+}\n+\n+/**\n+ * igc_setup_all_rx_resources - wrapper to allocate Rx resources\n+ * (Descriptors) for all queues\n+ * @adapter: board private structure\n+ *\n+ * Return 0 on success, negative on failure\n+ **/\n+static int igc_setup_all_rx_resources(struct igc_adapter *adapter)\n+{\n+\tstruct pci_dev *pdev = adapter->pdev;\n+\tint i, err = 0;\n+\n+\tfor (i = 0; i < adapter->num_rx_queues; i++) {\n+\t\terr = igc_setup_rx_resources(adapter->rx_ring[i]);\n+\t\tif (err) {\n+\t\t\tdev_err(&pdev->dev,\n+\t\t\t\t\"Allocation for Rx Queue %u failed\\n\", i);\n+\t\t\tfor (i--; i >= 0; i--)\n+\t\t\t\tigc_free_rx_resources(adapter->rx_ring[i]);\n+\t\t\tbreak;\n+\t\t}\n+\t}\n+\n+\treturn err;\n+}\n+\n+/**\n+ * igc_configure_rx_ring - Configure a receive ring after Reset\n+ * @adapter: board private structure\n+ * @ring: receive ring to be configured\n+ *\n+ * Configure the Rx unit of the MAC after a reset.\n+ **/\n+static void igc_configure_rx_ring(struct igc_adapter *adapter,\n+\t\t\t\t struct igc_ring *ring)\n+{\n+\tstruct igc_hw *hw = &adapter->hw;\n+\tunion igc_adv_rx_desc *rx_desc;\n+\tint reg_idx = ring->reg_idx;\n+\tu32 srrctl = 0, rxdctl = 0;\n+\tu64 rdba = ring->dma;\n+\n+\t/* disable the queue */\n+\twr32(IGC_RXDCTL(reg_idx), 0);\n+\n+\t/* Set DMA base address registers */\n+\twr32(IGC_RDBAL(reg_idx),\n+\t rdba & 0x00000000ffffffffULL);\n+\twr32(IGC_RDBAH(reg_idx), rdba >> 32);\n+\twr32(IGC_RDLEN(reg_idx),\n+\t ring->count * sizeof(union igc_adv_rx_desc));\n+\n+\t/* initialize head and tail */\n+\tring->tail = adapter->io_addr + IGC_RDT(reg_idx);\n+\twr32(IGC_RDH(reg_idx), 0);\n+\twritel(0, ring->tail);\n+\n+\t/* reset next-to- use/clean to place SW in sync with hardware */\n+\tring->next_to_clean = 0;\n+\tring->next_to_use = 0;\n+\n+\t/* set descriptor configuration */\n+\tsrrctl = IGC_RX_HDR_LEN << IGC_SRRCTL_BSIZEHDRSIZE_SHIFT;\n+\tif (ring_uses_large_buffer(ring))\n+\t\tsrrctl |= IGC_RXBUFFER_3072 >> IGC_SRRCTL_BSIZEPKT_SHIFT;\n+\telse\n+\t\tsrrctl |= IGC_RXBUFFER_2048 >> IGC_SRRCTL_BSIZEPKT_SHIFT;\n+\tsrrctl |= IGC_SRRCTL_DESCTYPE_ADV_ONEBUF;\n+\n+\twr32(IGC_SRRCTL(reg_idx), srrctl);\n+\n+\trxdctl |= IGC_RX_PTHRESH;\n+\trxdctl |= IGC_RX_HTHRESH << 8;\n+\trxdctl |= IGC_RX_WTHRESH << 16;\n+\n+\t/* initialize rx_buffer_info */\n+\tmemset(ring->rx_buffer_info, 0,\n+\t sizeof(struct igc_rx_buffer) * ring->count);\n+\n+\t/* initialize Rx descriptor 0 */\n+\trx_desc = IGC_RX_DESC(ring, 0);\n+\trx_desc->wb.upper.length = 0;\n+\n+\t/* enable receive descriptor fetching */\n+\trxdctl |= IGC_RXDCTL_QUEUE_ENABLE;\n+\n+\twr32(IGC_RXDCTL(reg_idx), rxdctl);\n+}\n+\n+/**\n+ * igc_configure_rx - Configure receive Unit after Reset\n+ * @adapter: board private structure\n+ *\n+ * Configure the Rx unit of the MAC after a reset.\n+ **/\n+static void igc_configure_rx(struct igc_adapter *adapter)\n+{\n+\tint i;\n+\n+\t/* Setup the HW Rx Head and Tail Descriptor Pointers and\n+\t * the Base and Length of the Rx Descriptor Ring\n+\t */\n+\tfor (i = 0; i < adapter->num_rx_queues; i++)\n+\t\tigc_configure_rx_ring(adapter, adapter->rx_ring[i]);\n+}\n+\n+/**\n+ * igc_configure_tx_ring - Configure transmit ring after Reset\n+ * @adapter: board private structure\n+ * @ring: tx ring to configure\n+ *\n+ * Configure a transmit ring after a reset.\n+ **/\n+static void igc_configure_tx_ring(struct igc_adapter *adapter,\n+\t\t\t\t struct igc_ring *ring)\n+{\n+\tstruct igc_hw *hw = &adapter->hw;\n+\tint reg_idx = ring->reg_idx;\n+\tu64 tdba = ring->dma;\n+\tu32 txdctl = 0;\n+\n+\t/* disable the queue */\n+\twr32(IGC_TXDCTL(reg_idx), 0);\n+\twrfl();\n+\tmdelay(10);\n+\n+\twr32(IGC_TDLEN(reg_idx),\n+\t ring->count * sizeof(union igc_adv_tx_desc));\n+\twr32(IGC_TDBAL(reg_idx),\n+\t tdba & 0x00000000ffffffffULL);\n+\twr32(IGC_TDBAH(reg_idx), tdba >> 32);\n+\n+\tring->tail = adapter->io_addr + IGC_TDT(reg_idx);\n+\twr32(IGC_TDH(reg_idx), 0);\n+\twritel(0, ring->tail);\n+\n+\ttxdctl |= IGC_TX_PTHRESH;\n+\ttxdctl |= IGC_TX_HTHRESH << 8;\n+\ttxdctl |= IGC_TX_WTHRESH << 16;\n+\n+\ttxdctl |= IGC_TXDCTL_QUEUE_ENABLE;\n+\twr32(IGC_TXDCTL(reg_idx), txdctl);\n+}\n+\n+/**\n+ * igc_configure_tx - Configure transmit Unit after Reset\n+ * @adapter: board private structure\n+ *\n+ * Configure the Tx unit of the MAC after a reset.\n+ **/\n+static void igc_configure_tx(struct igc_adapter *adapter)\n+{\n+\tint i;\n+\n+\tfor (i = 0; i < adapter->num_tx_queues; i++)\n+\t\tigc_configure_tx_ring(adapter, adapter->tx_ring[i]);\n+}\n+\n+/**\n+ * igc_setup_mrqc - configure the multiple receive queue control registers\n+ * @adapter: Board private structure\n+ **/\n+static void igc_setup_mrqc(struct igc_adapter *adapter)\n+{\n+}\n+\n+/**\n+ * igc_setup_rctl - configure the receive control registers\n+ * @adapter: Board private structure\n+ **/\n+static void igc_setup_rctl(struct igc_adapter *adapter)\n+{\n+\tstruct igc_hw *hw = &adapter->hw;\n+\tu32 rctl;\n+\n+\trctl = rd32(IGC_RCTL);\n+\n+\trctl &= ~(3 << IGC_RCTL_MO_SHIFT);\n+\trctl &= ~(IGC_RCTL_LBM_TCVR | IGC_RCTL_LBM_MAC);\n+\n+\trctl |= IGC_RCTL_EN | IGC_RCTL_BAM | IGC_RCTL_RDMTS_HALF |\n+\t\t(hw->mac.mc_filter_type << IGC_RCTL_MO_SHIFT);\n+\n+\t/* enable stripping of CRC. Newer features require\n+\t * that the HW strips the CRC.\n+\t */\n+\trctl |= IGC_RCTL_SECRC;\n+\n+\t/* disable store bad packets and clear size bits. */\n+\trctl &= ~(IGC_RCTL_SBP | IGC_RCTL_SZ_256);\n+\n+\t/* enable LPE to allow for reception of jumbo frames */\n+\trctl |= IGC_RCTL_LPE;\n+\n+\t/* disable queue 0 to prevent tail write w/o re-config */\n+\twr32(IGC_RXDCTL(0), 0);\n+\n+\t/* This is useful for sniffing bad packets. */\n+\tif (adapter->netdev->features & NETIF_F_RXALL) {\n+\t\t/* UPE and MPE will be handled by normal PROMISC logic\n+\t\t * in set_rx_mode\n+\t\t */\n+\t\trctl |= (IGC_RCTL_SBP | /* Receive bad packets */\n+\t\t\t IGC_RCTL_BAM | /* RX All Bcast Pkts */\n+\t\t\t IGC_RCTL_PMCF); /* RX All MAC Ctrl Pkts */\n+\n+\t\trctl &= ~(IGC_RCTL_DPF | /* Allow filtered pause */\n+\t\t\t IGC_RCTL_CFIEN); /* Disable VLAN CFIEN Filter */\n+\t}\n+\n+\twr32(IGC_RCTL, rctl);\n+}\n+\n+/**\n+ * igc_setup_tctl - configure the transmit control registers\n+ * @adapter: Board private structure\n+ **/\n+static void igc_setup_tctl(struct igc_adapter *adapter)\n+{\n+\tstruct igc_hw *hw = &adapter->hw;\n+\tu32 tctl;\n+\n+\t/* disable queue 0 which icould be enabled by default */\n+\twr32(IGC_TXDCTL(0), 0);\n+\n+\t/* Program the Transmit Control Register */\n+\ttctl = rd32(IGC_TCTL);\n+\ttctl &= ~IGC_TCTL_CT;\n+\ttctl |= IGC_TCTL_PSP | IGC_TCTL_RTLC |\n+\t\t(IGC_COLLISION_THRESHOLD << IGC_CT_SHIFT);\n+\n+\t/* Enable transmits */\n+\ttctl |= IGC_TCTL_EN;\n+\n+\twr32(IGC_TCTL, tctl);\n+}\n+\n /**\n * igc_set_mac - Change the Ethernet Address of the NIC\n * @netdev: network interface device structure\n@@ -156,6 +687,121 @@ static netdev_tx_t igc_xmit_frame(struct sk_buff *skb,\n \treturn NETDEV_TX_OK;\n }\n \n+static inline unsigned int igc_rx_offset(struct igc_ring *rx_ring)\n+{\n+\treturn ring_uses_build_skb(rx_ring) ? IGC_SKB_PAD : 0;\n+}\n+\n+static bool igc_alloc_mapped_page(struct igc_ring *rx_ring,\n+\t\t\t\t struct igc_rx_buffer *bi)\n+{\n+\tstruct page *page = bi->page;\n+\tdma_addr_t dma;\n+\n+\t/* since we are recycling buffers we should seldom need to alloc */\n+\tif (likely(page))\n+\t\treturn true;\n+\n+\t/* alloc new page for storage */\n+\tpage = dev_alloc_pages(igc_rx_pg_order(rx_ring));\n+\tif (unlikely(!page)) {\n+\t\trx_ring->rx_stats.alloc_failed++;\n+\t\treturn false;\n+\t}\n+\n+\t/* map page for use */\n+\tdma = dma_map_page_attrs(rx_ring->dev, page, 0,\n+\t\t\t\t igc_rx_pg_size(rx_ring),\n+\t\t\t\t DMA_FROM_DEVICE,\n+\t\t\t\t IGC_RX_DMA_ATTR);\n+\n+\t/* if mapping failed free memory back to system since\n+\t * there isn't much point in holding memory we can't use\n+\t */\n+\tif (dma_mapping_error(rx_ring->dev, dma)) {\n+\t\t__free_page(page);\n+\n+\t\trx_ring->rx_stats.alloc_failed++;\n+\t\treturn false;\n+\t}\n+\n+\tbi->dma = dma;\n+\tbi->page = page;\n+\tbi->page_offset = igc_rx_offset(rx_ring);\n+\tbi->pagecnt_bias = 1;\n+\n+\treturn true;\n+}\n+\n+/**\n+ * igc_alloc_rx_buffers - Replace used receive buffers; packet split\n+ * @adapter: address of board private structure\n+ **/\n+static void igc_alloc_rx_buffers(struct igc_ring *rx_ring, u16 cleaned_count)\n+{\n+\tunion igc_adv_rx_desc *rx_desc;\n+\tu16 i = rx_ring->next_to_use;\n+\tstruct igc_rx_buffer *bi;\n+\tu16 bufsz;\n+\n+\t/* nothing to do */\n+\tif (!cleaned_count)\n+\t\treturn;\n+\n+\trx_desc = IGC_RX_DESC(rx_ring, i);\n+\tbi = &rx_ring->rx_buffer_info[i];\n+\ti -= rx_ring->count;\n+\n+\tbufsz = igc_rx_bufsz(rx_ring);\n+\n+\tdo {\n+\t\tif (!igc_alloc_mapped_page(rx_ring, bi))\n+\t\t\tbreak;\n+\n+\t\t/* sync the buffer for use by the device */\n+\t\tdma_sync_single_range_for_device(rx_ring->dev, bi->dma,\n+\t\t\t\t\t\t bi->page_offset, bufsz,\n+\t\t\t\t\t\t DMA_FROM_DEVICE);\n+\n+\t\t/* Refresh the desc even if buffer_addrs didn't change\n+\t\t * because each write-back erases this info.\n+\t\t */\n+\t\trx_desc->read.pkt_addr = cpu_to_le64(bi->dma + bi->page_offset);\n+\n+\t\trx_desc++;\n+\t\tbi++;\n+\t\ti++;\n+\t\tif (unlikely(!i)) {\n+\t\t\trx_desc = IGC_RX_DESC(rx_ring, 0);\n+\t\t\tbi = rx_ring->rx_buffer_info;\n+\t\t\ti -= rx_ring->count;\n+\t\t}\n+\n+\t\t/* clear the length for the next_to_use descriptor */\n+\t\trx_desc->wb.upper.length = 0;\n+\n+\t\tcleaned_count--;\n+\t} while (cleaned_count);\n+\n+\ti += rx_ring->count;\n+\n+\tif (rx_ring->next_to_use != i) {\n+\t\t/* record the next descriptor to use */\n+\t\trx_ring->next_to_use = i;\n+\n+\t\t/* update next to alloc since we have filled the ring */\n+\t\trx_ring->next_to_alloc = i;\n+\n+\t\t/* Force memory writes to complete before letting h/w\n+\t\t * know there are new descriptors to fetch. (Only\n+\t\t * applicable for weak-ordered memory model archs,\n+\t\t * such as IA-64).\n+\t\t */\n+\t\twmb();\n+\t\twritel(i, rx_ring->tail);\n+\t}\n+}\n+\n /**\n * igc_ioctl - I/O control method\n * @netdev: network interface device structure\n@@ -195,6 +841,11 @@ static void igc_up(struct igc_adapter *adapter)\n \t/* Clear any pending interrupts. */\n \trd32(IGC_ICR);\n \tigc_irq_enable(adapter);\n+\n+\tnetif_tx_start_all_queues(adapter->netdev);\n+\n+\t/* start the watchdog. */\n+\thw->mac.get_link_status = 1;\n }\n \n /**\n@@ -293,7 +944,30 @@ static struct net_device_stats *igc_get_stats(struct net_device *netdev)\n **/\n static void igc_configure(struct igc_adapter *adapter)\n {\n+\tstruct net_device *netdev = adapter->netdev;\n+\tint i = 0;\n+\n \tigc_get_hw_control(adapter);\n+\tigc_set_rx_mode(netdev);\n+\n+\tigc_setup_tctl(adapter);\n+\tigc_setup_mrqc(adapter);\n+\tigc_setup_rctl(adapter);\n+\n+\tigc_configure_tx(adapter);\n+\tigc_configure_rx(adapter);\n+\n+\tigc_rx_fifo_flush_base(&adapter->hw);\n+\n+\t/* call igc_desc_unused which always leaves\n+\t * at least 1 descriptor unused to make sure\n+\t * next_to_use != next_to_clean\n+\t */\n+\tfor (i = 0; i < adapter->num_rx_queues; i++) {\n+\t\tstruct igc_ring *ring = adapter->rx_ring[i];\n+\n+\t\tigc_alloc_rx_buffers(ring, igc_desc_unused(ring));\n+\t}\n }\n \n /**\n@@ -341,6 +1015,19 @@ static void igc_set_default_mac_filter(struct igc_adapter *adapter)\n \tigc_rar_set_index(adapter, 0);\n }\n \n+/**\n+ * igc_set_rx_mode - Secondary Unicast, Multicast and Promiscuous mode set\n+ * @netdev: network interface device structure\n+ *\n+ * The set_rx_mode entry point is called whenever the unicast or multicast\n+ * address lists or the network interface flags are updated. This routine is\n+ * responsible for configuring the hardware for proper unicast, multicast,\n+ * promiscuous mode, and all-multi behavior.\n+ **/\n+static void igc_set_rx_mode(struct net_device *netdev)\n+{\n+}\n+\n /**\n * igc_msix_other - msix other interrupt handler\n * @irq: interrupt number\n@@ -778,6 +1465,83 @@ static void igc_update_itr(struct igc_q_vector *q_vector,\n \tring_container->itr = itrval;\n }\n \n+/**\n+ * igc_intr_msi - Interrupt Handler\n+ * @irq: interrupt number\n+ * @data: pointer to a network interface device structure\n+ **/\n+static irqreturn_t igc_intr_msi(int irq, void *data)\n+{\n+\tstruct igc_adapter *adapter = data;\n+\tstruct igc_q_vector *q_vector = adapter->q_vector[0];\n+\tstruct igc_hw *hw = &adapter->hw;\n+\t/* read ICR disables interrupts using IAM */\n+\tu32 icr = rd32(IGC_ICR);\n+\n+\tigc_write_itr(q_vector);\n+\n+\tif (icr & IGC_ICR_DRSTA)\n+\t\tschedule_work(&adapter->reset_task);\n+\n+\tif (icr & IGC_ICR_DOUTSYNC) {\n+\t\t/* HW is reporting DMA is out of sync */\n+\t\tadapter->stats.doosync++;\n+\t}\n+\n+\tif (icr & (IGC_ICR_RXSEQ | IGC_ICR_LSC)) {\n+\t\thw->mac.get_link_status = 1;\n+\t\tif (!test_bit(__IGC_DOWN, &adapter->state))\n+\t\t\tmod_timer(&adapter->watchdog_timer, jiffies + 1);\n+\t}\n+\n+\tnapi_schedule(&q_vector->napi);\n+\n+\treturn IRQ_HANDLED;\n+}\n+\n+/**\n+ * igc_intr - Legacy Interrupt Handler\n+ * @irq: interrupt number\n+ * @data: pointer to a network interface device structure\n+ **/\n+static irqreturn_t igc_intr(int irq, void *data)\n+{\n+\tstruct igc_adapter *adapter = data;\n+\tstruct igc_q_vector *q_vector = adapter->q_vector[0];\n+\tstruct igc_hw *hw = &adapter->hw;\n+\t/* Interrupt Auto-Mask...upon reading ICR, interrupts are masked. No\n+\t * need for the IMC write\n+\t */\n+\tu32 icr = rd32(IGC_ICR);\n+\n+\t/* IMS will not auto-mask if INT_ASSERTED is not set, and if it is\n+\t * not set, then the adapter didn't send an interrupt\n+\t */\n+\tif (!(icr & IGC_ICR_INT_ASSERTED))\n+\t\treturn IRQ_NONE;\n+\n+\tigc_write_itr(q_vector);\n+\n+\tif (icr & IGC_ICR_DRSTA)\n+\t\tschedule_work(&adapter->reset_task);\n+\n+\tif (icr & IGC_ICR_DOUTSYNC) {\n+\t\t/* HW is reporting DMA is out of sync */\n+\t\tadapter->stats.doosync++;\n+\t}\n+\n+\tif (icr & (IGC_ICR_RXSEQ | IGC_ICR_LSC)) {\n+\t\thw->mac.get_link_status = 1;\n+\t\t/* guard against interrupt when we're going down */\n+\t\tif (!test_bit(__IGC_DOWN, &adapter->state))\n+\t\t\tmod_timer(&adapter->watchdog_timer, jiffies + 1);\n+\t}\n+\n+\tnapi_schedule(&q_vector->napi);\n+\n+\treturn IRQ_HANDLED;\n+}\n+\n static void igc_ring_irq_enable(struct igc_q_vector *q_vector)\n {\n \tstruct igc_adapter *adapter = q_vector->adapter;\n@@ -1140,6 +1904,29 @@ static int igc_alloc_q_vectors(struct igc_adapter *adapter)\n \treturn -ENOMEM;\n }\n \n+/**\n+ * igc_cache_ring_register - Descriptor ring to register mapping\n+ * @adapter: board private structure to initialize\n+ *\n+ * Once we know the feature-set enabled for the device, we'll cache\n+ * the register offset the descriptor ring is assigned to.\n+ **/\n+static void igc_cache_ring_register(struct igc_adapter *adapter)\n+{\n+\tint i = 0, j = 0;\n+\n+\tswitch (adapter->hw.mac.type) {\n+\tcase igc_i225:\n+\t/* Fall through */\n+\tdefault:\n+\t\tfor (; i < adapter->num_rx_queues; i++)\n+\t\t\tadapter->rx_ring[i]->reg_idx = i;\n+\t\tfor (; j < adapter->num_tx_queues; j++)\n+\t\t\tadapter->tx_ring[j]->reg_idx = j;\n+\t\tbreak;\n+\t}\n+}\n+\n /**\n * igc_init_interrupt_scheme - initialize interrupts, allocate queues/vectors\n * @adapter: Pointer to adapter structure\n@@ -1159,6 +1946,8 @@ static int igc_init_interrupt_scheme(struct igc_adapter *adapter, bool msix)\n \t\tgoto err_alloc_q_vectors;\n \t}\n \n+\tigc_cache_ring_register(adapter);\n+\n \treturn 0;\n \n err_alloc_q_vectors:\n@@ -1246,6 +2035,8 @@ static void igc_irq_enable(struct igc_adapter *adapter)\n **/\n static int igc_request_irq(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 (adapter->flags & IGC_FLAG_HAS_MSIX) {\n@@ -1253,14 +2044,38 @@ static int igc_request_irq(struct igc_adapter *adapter)\n \t\tif (!err)\n \t\t\tgoto request_done;\n \t\t/* fall back to MSI */\n+\t\tigc_free_all_tx_resources(adapter);\n+\t\tigc_free_all_rx_resources(adapter);\n \n \t\tigc_clear_interrupt_scheme(adapter);\n \t\terr = igc_init_interrupt_scheme(adapter, false);\n \t\tif (err)\n \t\t\tgoto request_done;\n+\t\tigc_setup_all_tx_resources(adapter);\n+\t\tigc_setup_all_rx_resources(adapter);\n \t\tigc_configure(adapter);\n \t}\n \n+\tigc_assign_vector(adapter->q_vector[0], 0);\n+\n+\tif (adapter->flags & IGC_FLAG_HAS_MSI) {\n+\t\terr = request_irq(pdev->irq, &igc_intr_msi, 0,\n+\t\t\t\t netdev->name, adapter);\n+\t\tif (!err)\n+\t\t\tgoto request_done;\n+\n+\t\t/* fall back to legacy interrupts */\n+\t\tigc_reset_interrupt_capability(adapter);\n+\t\tadapter->flags &= ~IGC_FLAG_HAS_MSI;\n+\t}\n+\n+\terr = request_irq(pdev->irq, &igc_intr, IRQF_SHARED,\n+\t\t\t netdev->name, adapter);\n+\n+\tif (err)\n+\t\tdev_err(&pdev->dev, \"Error %d getting interrupt\\n\",\n+\t\t\terr);\n+\n request_done:\n \treturn err;\n }\n@@ -1321,6 +2136,16 @@ static int __igc_open(struct net_device *netdev, bool resuming)\n \n \tnetif_carrier_off(netdev);\n \n+\t/* allocate transmit descriptors */\n+\terr = igc_setup_all_tx_resources(adapter);\n+\tif (err)\n+\t\tgoto err_setup_tx;\n+\n+\t/* allocate receive descriptors */\n+\terr = igc_setup_all_rx_resources(adapter);\n+\tif (err)\n+\t\tgoto err_setup_rx;\n+\n \tigc_power_up_link(adapter);\n \n \tigc_configure(adapter);\n@@ -1347,6 +2172,8 @@ static int __igc_open(struct net_device *netdev, bool resuming)\n \trd32(IGC_ICR);\n \tigc_irq_enable(adapter);\n \n+\tnetif_tx_start_all_queues(netdev);\n+\n \t/* start the watchdog. */\n \thw->mac.get_link_status = 1;\n \n@@ -1357,6 +2184,11 @@ static int __igc_open(struct net_device *netdev, bool resuming)\n err_req_irq:\n \tigc_release_hw_control(adapter);\n \tigc_power_down_link(adapter);\n+\tigc_free_all_rx_resources(adapter);\n+err_setup_rx:\n+\tigc_free_all_tx_resources(adapter);\n+err_setup_tx:\n+\tigc_reset(adapter);\n \n \treturn err;\n }\n@@ -1389,6 +2221,9 @@ static int __igc_close(struct net_device *netdev, bool suspending)\n \n \tigc_free_irq(adapter);\n \n+\tigc_free_all_tx_resources(adapter);\n+\tigc_free_all_rx_resources(adapter);\n+\n \treturn 0;\n }\n \n@@ -1403,6 +2238,7 @@ static const struct net_device_ops igc_netdev_ops = {\n \t.ndo_open = igc_open,\n \t.ndo_stop = igc_close,\n \t.ndo_start_xmit = igc_xmit_frame,\n+\t.ndo_set_rx_mode = igc_set_rx_mode,\n \t.ndo_set_mac_address = igc_set_mac,\n \t.ndo_change_mtu = igc_change_mtu,\n \t.ndo_get_stats = igc_get_stats,\ndiff --git a/drivers/net/ethernet/intel/igc/igc_regs.h b/drivers/net/ethernet/intel/igc/igc_regs.h\nindex d390b5336cc7..753ac667c5a9 100644\n--- a/drivers/net/ethernet/intel/igc/igc_regs.h\n+++ b/drivers/net/ethernet/intel/igc/igc_regs.h\n@@ -168,6 +168,9 @@\n #define IGC_SCVPC\t0x04228 /* SerDes/SGMII Code Violation Pkt Count */\n #define IGC_HRMPC\t0x0A018 /* Header Redirection Missed Packet Count */\n \n+/* Management registers */\n+#define IGC_MANC\t0x05820 /* Management Control - RW */\n+\n /* forward declaration */\n struct igc_hw;\n u32 igc_rd32(struct igc_hw *hw, u32 reg);\n", "prefixes": [ "v6", "05/11" ] }