Patch Detail
get:
Show a patch.
patch:
Update a patch.
put:
Update a patch.
GET /api/patches/1199190/?format=api
{ "id": 1199190, "url": "http://patchwork.ozlabs.org/api/patches/1199190/?format=api", "web_url": "http://patchwork.ozlabs.org/project/intel-wired-lan/patch/20191122020224.1102649-3-vinicius.gomes@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": "<20191122020224.1102649-3-vinicius.gomes@intel.com>", "list_archive_url": null, "date": "2019-11-22T02:02:22", "name": "[next-queue,v1,2/4] igc: Add support for RX timestamping", "commit_ref": null, "pull_url": null, "state": "superseded", "archived": false, "hash": "6743c3665bbe1c5002db01049d3e8c9df6f9e0d0", "submitter": { "id": 72272, "url": "http://patchwork.ozlabs.org/api/people/72272/?format=api", "name": "Vinicius Costa Gomes", "email": "vinicius.gomes@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/20191122020224.1102649-3-vinicius.gomes@intel.com/mbox/", "series": [ { "id": 144449, "url": "http://patchwork.ozlabs.org/api/series/144449/?format=api", "web_url": "http://patchwork.ozlabs.org/project/intel-wired-lan/list/?series=144449", "date": "2019-11-22T02:02:20", "name": "igc: Add basic support for Timestamping/PTP", "version": 1, "mbox": "http://patchwork.ozlabs.org/series/144449/mbox/" } ], "comments": "http://patchwork.ozlabs.org/api/patches/1199190/comments/", "check": "pending", "checks": "http://patchwork.ozlabs.org/api/patches/1199190/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; spf=pass (sender SPF authorized)\n\tsmtp.mailfrom=osuosl.org (client-ip=140.211.166.138;\n\thelo=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 ECDHE-RSA-AES256-GCM-SHA384 (256/256\n\tbits)) (No client certificate requested)\n\tby ozlabs.org (Postfix) with ESMTPS id 47K07P5bJWz9sPT\n\tfor <incoming@patchwork.ozlabs.org>;\n\tFri, 22 Nov 2019 13:02:41 +1100 (AEDT)", "from localhost (localhost [127.0.0.1])\n\tby whitealder.osuosl.org (Postfix) with ESMTP id 53CDC844C0;\n\tFri, 22 Nov 2019 02:02:40 +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 32vc9kMc0zCj; Fri, 22 Nov 2019 02:02:34 +0000 (UTC)", "from ash.osuosl.org (ash.osuosl.org [140.211.166.34])\n\tby whitealder.osuosl.org (Postfix) with ESMTP id B99C986FEA;\n\tFri, 22 Nov 2019 02:02:34 +0000 (UTC)", "from fraxinus.osuosl.org (smtp4.osuosl.org [140.211.166.137])\n\tby ash.osuosl.org (Postfix) with ESMTP id A84261BF33D\n\tfor <intel-wired-lan@lists.osuosl.org>;\n\tFri, 22 Nov 2019 02:02:32 +0000 (UTC)", "from localhost (localhost [127.0.0.1])\n\tby fraxinus.osuosl.org (Postfix) with ESMTP id 9FED787251\n\tfor <intel-wired-lan@lists.osuosl.org>;\n\tFri, 22 Nov 2019 02:02:32 +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 1TtVh2jLxppI for <intel-wired-lan@lists.osuosl.org>;\n\tFri, 22 Nov 2019 02:02:31 +0000 (UTC)", "from mga05.intel.com (mga05.intel.com [192.55.52.43])\n\tby fraxinus.osuosl.org (Postfix) with ESMTPS id 384B887246\n\tfor <intel-wired-lan@lists.osuosl.org>;\n\tFri, 22 Nov 2019 02:02:31 +0000 (UTC)", "from fmsmga008.fm.intel.com ([10.253.24.58])\n\tby fmsmga105.fm.intel.com with ESMTP/TLS/DHE-RSA-AES256-GCM-SHA384;\n\t21 Nov 2019 18:02:30 -0800", "from vcostago-desk1.jf.intel.com ([10.54.70.26])\n\tby fmsmga008.fm.intel.com with ESMTP; 21 Nov 2019 18:02:30 -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.69,228,1571727600\"; d=\"scan'208\";a=\"205264937\"", "From": "Vinicius Costa Gomes <vinicius.gomes@intel.com>", "To": "intel-wired-lan@lists.osuosl.org", "Date": "Thu, 21 Nov 2019 18:02:22 -0800", "Message-Id": "<20191122020224.1102649-3-vinicius.gomes@intel.com>", "X-Mailer": "git-send-email 2.24.0", "In-Reply-To": "<20191122020224.1102649-1-vinicius.gomes@intel.com>", "References": "<20191122020224.1102649-1-vinicius.gomes@intel.com>", "MIME-Version": "1.0", "Subject": "[Intel-wired-lan] [next-queue PATCH v1 2/4] igc: Add support for RX\n\ttimestamping", "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>", "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 adds support for timestamping received packets.\n\nIt is based on the i210, as many features of i225 work the same way.\nThe main difference from i210 is that i225 has support for choosing\nthe timer register to use when timestamping packets. Right now, we\nonly support using timer 0. The other difference is that i225 stores\ntwo timestamps in the receive descriptor, right now, we only retrieve\none.\n\nSigned-off-by: Vinicius Costa Gomes <vinicius.gomes@intel.com>\n---\n drivers/net/ethernet/intel/igc/igc.h | 17 ++\n drivers/net/ethernet/intel/igc/igc_defines.h | 38 +++\n drivers/net/ethernet/intel/igc/igc_main.c | 10 +\n drivers/net/ethernet/intel/igc/igc_ptp.c | 272 +++++++++++++++++++\n drivers/net/ethernet/intel/igc/igc_regs.h | 3 +\n 5 files changed, 340 insertions(+)", "diff": "diff --git a/drivers/net/ethernet/intel/igc/igc.h b/drivers/net/ethernet/intel/igc/igc.h\nindex 31b0ed0aa090..686fe6d9dae6 100644\n--- a/drivers/net/ethernet/intel/igc/igc.h\n+++ b/drivers/net/ethernet/intel/igc/igc.h\n@@ -107,6 +107,20 @@ extern char igc_driver_version[];\n #define AUTO_ALL_MODES\t\t0\n #define IGC_RX_HDR_LEN\t\t\tIGC_RXBUFFER_256\n \n+/* Transmit and receive latency (for PTP timestamps) */\n+/* FIXME: These values were estimated using the ones that i210 has as\n+ * basis, they seem to provide good numbers with ptp4l/phc2sys, but we\n+ * need to confirm them.\n+ */\n+#define IGC_I225_TX_LATENCY_10\t\t9542\n+#define IGC_I225_TX_LATENCY_100\t\t1024\n+#define IGC_I225_TX_LATENCY_1000\t178\n+#define IGC_I225_TX_LATENCY_2500\t64\n+#define IGC_I225_RX_LATENCY_10\t\t20662\n+#define IGC_I225_RX_LATENCY_100\t\t2213\n+#define IGC_I225_RX_LATENCY_1000\t448\n+#define IGC_I225_RX_LATENCY_2500\t160\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@@ -537,6 +551,9 @@ int igc_erase_filter(struct igc_adapter *adapter,\n void igc_ptp_init(struct igc_adapter *adapter);\n void igc_ptp_reset(struct igc_adapter *adapter);\n void igc_ptp_stop(struct igc_adapter *adapter);\n+void igc_ptp_rx_rgtstamp(struct igc_q_vector *q_vector, struct sk_buff *skb);\n+void igc_ptp_rx_pktstamp(struct igc_q_vector *q_vector, void *va,\n+\t\t\t struct sk_buff *skb);\n int igc_ptp_set_ts_config(struct net_device *netdev, struct ifreq *ifr);\n int igc_ptp_get_ts_config(struct net_device *netdev, struct ifreq *ifr);\n #define igc_rx_pg_size(_ring) (PAGE_SIZE << igc_rx_pg_order(_ring))\ndiff --git a/drivers/net/ethernet/intel/igc/igc_defines.h b/drivers/net/ethernet/intel/igc/igc_defines.h\nindex fa345adad5c9..a5b7e5e05a89 100644\n--- a/drivers/net/ethernet/intel/igc/igc_defines.h\n+++ b/drivers/net/ethernet/intel/igc/igc_defines.h\n@@ -283,12 +283,21 @@\n #define IGC_RCTL_RDMTS_HALF\t0x00000000 /* Rx desc min thresh size */\n #define IGC_RCTL_BAM\t\t0x00008000 /* broadcast enable */\n \n+/* Split Replication Receive Control */\n+#define IGC_SRRCTL_TIMESTAMP\t\t0x04000\n+#define IGC_SRRCTL_TIMER1SEL(timer)\t(((timer) & 0x3) << 14)\n+#define IGC_SRRCTL_TIMER0SEL(timer)\t(((timer) & 0x3) << 17)\n+\n /* Receive Descriptor bit definitions */\n #define IGC_RXD_STAT_EOP\t0x02\t/* End of Packet */\n #define IGC_RXD_STAT_IXSM\t0x04\t/* Ignore checksum */\n #define IGC_RXD_STAT_UDPCS\t0x10\t/* UDP xsum calculated */\n #define IGC_RXD_STAT_TCPCS\t0x20\t/* TCP xsum calculated */\n \n+/* Advanced Receive Descriptor bit definitions */\n+#define IGC_RXDADV_STAT_TSIP\t0x08000 /* timestamp in packet */\n+#define IGC_RXDADV_STAT_TS\t0x10000 /* Pkt was time stamped */\n+\n #define IGC_RXDEXT_STATERR_CE\t\t0x01000000\n #define IGC_RXDEXT_STATERR_SE\t\t0x02000000\n #define IGC_RXDEXT_STATERR_SEQ\t\t0x04000000\n@@ -325,6 +334,7 @@\n \n #define I225_RXPBSIZE_DEFAULT\t0x000000A2 /* RXPBSIZE default */\n #define I225_TXPBSIZE_DEFAULT\t0x04000014 /* TXPBSIZE default */\n+#define IGC_RXPBS_CFG_TS_EN\t0x80000000 /* Timestamp in Rx buffer */\n \n /* Time Sync Interrupt Causes */\n #define IGC_TSICR_SYS_WRAP\tBIT(0) /* SYSTIM Wrap around. */\n@@ -336,6 +346,34 @@\n \n #define IGC_TSICR_INTERRUPTS\tIGC_TSICR_TXTS\n \n+/* PTP Queue Filter */\n+#define IGC_ETQF_1588\t\tBIT(30)\n+\n+#define IGC_FTQF_VF_BP\t\t0x00008000\n+#define IGC_FTQF_1588_TIME_STAMP\t0x08000000\n+#define IGC_FTQF_MASK\t\t\t0xF0000000\n+#define IGC_FTQF_MASK_PROTO_BP\t0x10000000\n+\n+/* Time Sync Receive Control bit definitions */\n+#define IGC_TSYNCRXCTL_VALID\t\t0x00000001 /* Rx timestamp valid */\n+#define IGC_TSYNCRXCTL_TYPE_MASK\t0x0000000E /* Rx type mask */\n+#define IGC_TSYNCRXCTL_TYPE_L2_V2\t0x00\n+#define IGC_TSYNCRXCTL_TYPE_L4_V1\t0x02\n+#define IGC_TSYNCRXCTL_TYPE_L2_L4_V2\t0x04\n+#define IGC_TSYNCRXCTL_TYPE_ALL\t\t0x08\n+#define IGC_TSYNCRXCTL_TYPE_EVENT_V2\t0x0A\n+#define IGC_TSYNCRXCTL_ENABLED\t\t0x00000010 /* enable Rx timestamping */\n+#define IGC_TSYNCRXCTL_SYSCFI\t\t0x00000020 /* Sys clock frequency */\n+\n+/* Time Sync Receive Configuration */\n+#define IGC_TSYNCRXCFG_PTP_V1_CTRLT_MASK\t0x000000FF\n+#define IGC_TSYNCRXCFG_PTP_V1_SYNC_MESSAGE\t0x00\n+#define IGC_TSYNCRXCFG_PTP_V1_DELAY_REQ_MESSAGE\t0x01\n+\n+/* Immediate Interrupt Receive Extended */\n+#define IGC_IMIREXT_CTRL_BP\t0x00080000 /* Bypass check of ctrl bits */\n+#define IGC_IMIREXT_SIZE_BP\t0x00001000 /* Packet size bypass */\n+\n /* Receive Checksum Control */\n #define IGC_RXCSUM_CRCOFL\t0x00000800 /* CRC32 offload enable */\n #define IGC_RXCSUM_PCSD\t\t0x00002000 /* packet checksum disabled */\ndiff --git a/drivers/net/ethernet/intel/igc/igc_main.c b/drivers/net/ethernet/intel/igc/igc_main.c\nindex abdb827e646d..f6319cb6b5ca 100644\n--- a/drivers/net/ethernet/intel/igc/igc_main.c\n+++ b/drivers/net/ethernet/intel/igc/igc_main.c\n@@ -1272,6 +1272,10 @@ static void igc_process_skb_fields(struct igc_ring *rx_ring,\n \n \tigc_rx_checksum(rx_ring, rx_desc, skb);\n \n+\tif (igc_test_staterr(rx_desc, IGC_RXDADV_STAT_TS) &&\n+\t !igc_test_staterr(rx_desc, IGC_RXDADV_STAT_TSIP))\n+\t\tigc_ptp_rx_rgtstamp(rx_ring->q_vector, skb);\n+\n \tskb_record_rx_queue(skb, rx_ring->queue_index);\n \n \tskb->protocol = eth_type_trans(skb, rx_ring->netdev);\n@@ -1391,6 +1395,12 @@ static struct sk_buff *igc_construct_skb(struct igc_ring *rx_ring,\n \tif (unlikely(!skb))\n \t\treturn NULL;\n \n+\tif (unlikely(igc_test_staterr(rx_desc, IGC_RXDADV_STAT_TSIP))) {\n+\t\tigc_ptp_rx_pktstamp(rx_ring->q_vector, va, skb);\n+\t\tva += IGC_TS_HDR_LEN;\n+\t\tsize -= IGC_TS_HDR_LEN;\n+\t}\n+\n \t/* Determine available headroom for copy */\n \theadlen = size;\n \tif (headlen > IGC_RX_HDR_LEN)\ndiff --git a/drivers/net/ethernet/intel/igc/igc_ptp.c b/drivers/net/ethernet/intel/igc/igc_ptp.c\nindex aaf10617d222..b39d14d40ec9 100644\n--- a/drivers/net/ethernet/intel/igc/igc_ptp.c\n+++ b/drivers/net/ethernet/intel/igc/igc_ptp.c\n@@ -134,9 +134,281 @@ static int igc_ptp_feature_enable_i225(struct ptp_clock_info *ptp,\n \treturn -EOPNOTSUPP;\n }\n \n+/**\n+ * igc_ptp_systim_to_hwtstamp - convert system time value to hw timestamp\n+ * @adapter: board private structure\n+ * @hwtstamps: timestamp structure to update\n+ * @systim: unsigned 64bit system time value.\n+ *\n+ * We need to convert the system time value stored in the RX/TXSTMP registers\n+ * into a hwtstamp which can be used by the upper level timestamping functions.\n+ **/\n+static void igc_ptp_systim_to_hwtstamp(struct igc_adapter *adapter,\n+\t\t\t\t struct skb_shared_hwtstamps *hwtstamps,\n+\t\t\t\t u64 systim)\n+{\n+\tswitch (adapter->hw.mac.type) {\n+\tcase igc_i225:\n+\t\tmemset(hwtstamps, 0, sizeof(*hwtstamps));\n+\t\t/* Upper 32 bits contain s, lower 32 bits contain ns. */\n+\t\thwtstamps->hwtstamp = ktime_set(systim >> 32,\n+\t\t\t\t\t\tsystim & 0xFFFFFFFF);\n+\t\tbreak;\n+\tdefault:\n+\t\tbreak;\n+\t}\n+}\n+\n+/**\n+ * igc_ptp_rx_pktstamp - retrieve Rx per packet timestamp\n+ * @q_vector: Pointer to interrupt specific structure\n+ * @va: Pointer to address containing Rx buffer\n+ * @skb: Buffer containing timestamp and packet\n+ *\n+ * This function is meant to retrieve the first timestamp from the\n+ * first buffer of an incoming frame. The value is stored in little\n+ * endian format starting on byte 0. There's a second timestamp\n+ * starting on byte 8.\n+ **/\n+void igc_ptp_rx_pktstamp(struct igc_q_vector *q_vector, void *va,\n+\t\t\t struct sk_buff *skb)\n+{\n+\t__le64 *regval = (__le64 *)va;\n+\tstruct igc_adapter *adapter = q_vector->adapter;\n+\tint adjust = 0;\n+\n+\t/* The timestamp is recorded in little endian format.\n+\t * DWORD: | 0 | 1 | 2 | 3\n+\t * Field: | Timer0 Low | Timer0 High | Timer1 Low | Timer1 High\n+\t */\n+\tigc_ptp_systim_to_hwtstamp(adapter, skb_hwtstamps(skb),\n+\t\t\t\t le64_to_cpu(regval[0]));\n+\n+\t/* adjust timestamp for the RX latency based on link speed */\n+\tif (adapter->hw.mac.type == igc_i225) {\n+\t\tswitch (adapter->link_speed) {\n+\t\tcase SPEED_10:\n+\t\t\tadjust = IGC_I225_RX_LATENCY_10;\n+\t\t\tbreak;\n+\t\tcase SPEED_100:\n+\t\t\tadjust = IGC_I225_RX_LATENCY_100;\n+\t\t\tbreak;\n+\t\tcase SPEED_1000:\n+\t\t\tadjust = IGC_I225_RX_LATENCY_1000;\n+\t\t\tbreak;\n+\t\tcase SPEED_2500:\n+\t\t\tadjust = IGC_I225_RX_LATENCY_2500;\n+\t\t\tbreak;\n+\t\t}\n+\t}\n+\tskb_hwtstamps(skb)->hwtstamp =\n+\t\tktime_sub_ns(skb_hwtstamps(skb)->hwtstamp, adjust);\n+}\n+\n+/**\n+ * igc_ptp_rx_rgtstamp - retrieve Rx timestamp stored in register\n+ * @q_vector: Pointer to interrupt specific structure\n+ * @skb: Buffer containing timestamp and packet\n+ *\n+ * This function is meant to retrieve a timestamp from the internal registers\n+ * of the adapter and store it in the skb.\n+ */\n+void igc_ptp_rx_rgtstamp(struct igc_q_vector *q_vector,\n+\t\t\t struct sk_buff *skb)\n+{\n+\tstruct igc_adapter *adapter = q_vector->adapter;\n+\tstruct igc_hw *hw = &adapter->hw;\n+\tu64 regval;\n+\n+\t/* If this bit is set, then the RX registers contain the time\n+\t * stamp. No other packet will be time stamped until we read\n+\t * these registers, so read the registers to make them\n+\t * available again. Because only one packet can be time\n+\t * stamped at a time, we know that the register values must\n+\t * belong to this one here and therefore we don't need to\n+\t * compare any of the additional attributes stored for it.\n+\t *\n+\t * If nothing went wrong, then it should have a shared\n+\t * tx_flags that we can turn into a skb_shared_hwtstamps.\n+\t */\n+\tif (!(rd32(IGC_TSYNCRXCTL) & IGC_TSYNCRXCTL_VALID))\n+\t\treturn;\n+\n+\tregval = rd32(IGC_RXSTMPL);\n+\tregval |= (u64)rd32(IGC_RXSTMPH) << 32;\n+\n+\tigc_ptp_systim_to_hwtstamp(adapter, skb_hwtstamps(skb), regval);\n+\n+\t/* Update the last_rx_timestamp timer in order to enable watchdog check\n+\t * for error case of latched timestamp on a dropped packet.\n+\t */\n+\tadapter->last_rx_timestamp = jiffies;\n+}\n+\n+/**\n+ * igc_ptp_enable_tstamp_rxqueue - Enable RX timestamp for a queue\n+ * @rx_ring: Pointer to RX queue\n+ * @timer: Index for timer\n+ *\n+ * This function enables RX timestamping for a queue, and selects\n+ * which 1588 timer will provide the timestamp.\n+ */\n+static void igc_ptp_enable_tstamp_rxqueue(struct igc_adapter *adapter,\n+\t\t\t\t\t struct igc_ring *rx_ring, u8 timer)\n+{\n+\tstruct igc_hw *hw = &adapter->hw;\n+\tint reg_idx = rx_ring->reg_idx;\n+\tu32 srrctl = rd32(IGC_SRRCTL(reg_idx));\n+\n+\tsrrctl |= IGC_SRRCTL_TIMESTAMP;\n+\tsrrctl |= IGC_SRRCTL_TIMER1SEL(timer);\n+\tsrrctl |= IGC_SRRCTL_TIMER0SEL(timer);\n+\n+\twr32(IGC_SRRCTL(reg_idx), srrctl);\n+}\n+\n+static void igc_ptp_enable_tstamp_all_rxqueues(struct igc_adapter *adapter,\n+\t\t\t\t\t u8 timer)\n+{\n+\tint i;\n+\n+\tfor (i = 0; i < adapter->num_rx_queues; i++) {\n+\t\tstruct igc_ring *ring = adapter->rx_ring[i];\n+\n+\t\tigc_ptp_enable_tstamp_rxqueue(adapter, ring, timer);\n+\t}\n+}\n+\n+/**\n+ * igc_ptp_set_timestamp_mode - setup hardware for timestamping\n+ * @adapter: networking device structure\n+ * @config: hwtstamp configuration\n+ *\n+ * Incoming time stamping has to be configured via the hardware\n+ * filters. Not all combinations are supported, in particular event\n+ * type has to be specified. Matching the kind of event packet is\n+ * not supported, with the exception of \"all V2 events regardless of\n+ * level 2 or 4\".\n+ *\n+ */\n static int igc_ptp_set_timestamp_mode(struct igc_adapter *adapter,\n \t\t\t\t struct hwtstamp_config *config)\n {\n+\tstruct igc_hw *hw = &adapter->hw;\n+\tu32 tsync_rx_ctl = IGC_TSYNCRXCTL_ENABLED;\n+\tu32 tsync_rx_cfg = 0;\n+\tbool is_l4 = false;\n+\tbool is_l2 = false;\n+\tu32 regval;\n+\n+\t/* reserved for future extensions */\n+\tif (config->flags)\n+\t\treturn -EINVAL;\n+\n+\tswitch (config->rx_filter) {\n+\tcase HWTSTAMP_FILTER_NONE:\n+\t\ttsync_rx_ctl = 0;\n+\t\tbreak;\n+\tcase HWTSTAMP_FILTER_PTP_V1_L4_SYNC:\n+\t\ttsync_rx_ctl |= IGC_TSYNCRXCTL_TYPE_L4_V1;\n+\t\ttsync_rx_cfg = IGC_TSYNCRXCFG_PTP_V1_SYNC_MESSAGE;\n+\t\tis_l4 = true;\n+\t\tbreak;\n+\tcase HWTSTAMP_FILTER_PTP_V1_L4_DELAY_REQ:\n+\t\ttsync_rx_ctl |= IGC_TSYNCRXCTL_TYPE_L4_V1;\n+\t\ttsync_rx_cfg = IGC_TSYNCRXCFG_PTP_V1_DELAY_REQ_MESSAGE;\n+\t\tis_l4 = true;\n+\t\tbreak;\n+\tcase HWTSTAMP_FILTER_PTP_V2_EVENT:\n+\tcase HWTSTAMP_FILTER_PTP_V2_L2_EVENT:\n+\tcase HWTSTAMP_FILTER_PTP_V2_L4_EVENT:\n+\tcase HWTSTAMP_FILTER_PTP_V2_SYNC:\n+\tcase HWTSTAMP_FILTER_PTP_V2_L2_SYNC:\n+\tcase HWTSTAMP_FILTER_PTP_V2_L4_SYNC:\n+\tcase HWTSTAMP_FILTER_PTP_V2_DELAY_REQ:\n+\tcase HWTSTAMP_FILTER_PTP_V2_L2_DELAY_REQ:\n+\tcase HWTSTAMP_FILTER_PTP_V2_L4_DELAY_REQ:\n+\t\ttsync_rx_ctl |= IGC_TSYNCRXCTL_TYPE_EVENT_V2;\n+\t\tconfig->rx_filter = HWTSTAMP_FILTER_PTP_V2_EVENT;\n+\t\tis_l2 = true;\n+\t\tis_l4 = true;\n+\t\tbreak;\n+\tcase HWTSTAMP_FILTER_PTP_V1_L4_EVENT:\n+\tcase HWTSTAMP_FILTER_NTP_ALL:\n+\tcase HWTSTAMP_FILTER_ALL:\n+\t\ttsync_rx_ctl |= IGC_TSYNCRXCTL_TYPE_ALL;\n+\t\tconfig->rx_filter = HWTSTAMP_FILTER_ALL;\n+\t\tbreak;\n+\t\t/* fall through */\n+\tdefault:\n+\t\tconfig->rx_filter = HWTSTAMP_FILTER_NONE;\n+\t\treturn -ERANGE;\n+\t}\n+\n+\t/* Per-packet timestamping only works if all packets are\n+\t * timestamped, so enable timestamping in all packets as long\n+\t * as one rx filter was configured.\n+\t */\n+\tif (tsync_rx_ctl) {\n+\t\ttsync_rx_ctl = IGC_TSYNCRXCTL_ENABLED;\n+\t\ttsync_rx_ctl |= IGC_TSYNCRXCTL_TYPE_ALL;\n+\t\tconfig->rx_filter = HWTSTAMP_FILTER_ALL;\n+\t\tis_l2 = true;\n+\t\tis_l4 = true;\n+\n+\t\tif (hw->mac.type == igc_i225) {\n+\t\t\tregval = rd32(IGC_RXPBS);\n+\t\t\tregval |= IGC_RXPBS_CFG_TS_EN;\n+\t\t\twr32(IGC_RXPBS, regval);\n+\n+\t\t\t/* FIXME: For now, only support retrieving RX\n+\t\t\t * timestamps from timer 0\n+\t\t\t */\n+\t\t\tigc_ptp_enable_tstamp_all_rxqueues(adapter, 0);\n+\t\t}\n+\t}\n+\n+\t/* enable/disable RX */\n+\tregval = rd32(IGC_TSYNCRXCTL);\n+\tregval &= ~(IGC_TSYNCRXCTL_ENABLED | IGC_TSYNCRXCTL_TYPE_MASK);\n+\tregval |= tsync_rx_ctl;\n+\twr32(IGC_TSYNCRXCTL, regval);\n+\n+\t/* define which PTP packets are time stamped */\n+\twr32(IGC_TSYNCRXCFG, tsync_rx_cfg);\n+\n+\t/* define ethertype filter for timestamped packets */\n+\tif (is_l2)\n+\t\twr32(IGC_ETQF(3),\n+\t\t (IGC_ETQF_FILTER_ENABLE | /* enable filter */\n+\t\t IGC_ETQF_1588 | /* enable timestamping */\n+\t\t ETH_P_1588)); /* 1588 eth protocol type */\n+\telse\n+\t\twr32(IGC_ETQF(3), 0);\n+\n+\t/* L4 Queue Filter[3]: filter by destination port and protocol */\n+\tif (is_l4) {\n+\t\tu32 ftqf = (IPPROTO_UDP /* UDP */\n+\t\t\t | IGC_FTQF_VF_BP /* VF not compared */\n+\t\t\t | IGC_FTQF_1588_TIME_STAMP /* Enable Timestamp */\n+\t\t\t | IGC_FTQF_MASK); /* mask all inputs */\n+\t\tftqf &= ~IGC_FTQF_MASK_PROTO_BP; /* enable protocol check */\n+\n+\t\twr32(IGC_IMIR(3), htons(PTP_EV_PORT));\n+\t\twr32(IGC_IMIREXT(3),\n+\t\t (IGC_IMIREXT_SIZE_BP | IGC_IMIREXT_CTRL_BP));\n+\t\twr32(IGC_FTQF(3), ftqf);\n+\t} else {\n+\t\twr32(IGC_FTQF(3), IGC_FTQF_MASK);\n+\t}\n+\twrfl();\n+\n+\t/* clear TX/RX time stamp registers, just to be sure */\n+\tregval = rd32(IGC_TXSTMPL);\n+\tregval = rd32(IGC_TXSTMPH);\n+\tregval = rd32(IGC_RXSTMPL);\n+\tregval = rd32(IGC_RXSTMPH);\n+\n \treturn 0;\n }\n \ndiff --git a/drivers/net/ethernet/intel/igc/igc_regs.h b/drivers/net/ethernet/intel/igc/igc_regs.h\nindex 0d2e99884887..4107c92bfe3d 100644\n--- a/drivers/net/ethernet/intel/igc/igc_regs.h\n+++ b/drivers/net/ethernet/intel/igc/igc_regs.h\n@@ -224,6 +224,9 @@\n #define IGC_IMIREXT(_i)\t(0x05AA0 + ((_i) * 4)) /* Immediate INTR Ext*/\n \n #define IGC_FTQF(_n)\t(0x059E0 + (4 * (_n))) /* 5-tuple Queue Fltr */\n+\n+#define IGC_RXPBS\t0x02404 /* Rx Packet Buffer Size - RW */\n+\n /* System Time Registers */\n #define IGC_SYSTIML\t0x0B600 /* System time register Low - RO */\n #define IGC_SYSTIMH\t0x0B604 /* System time register High - RO */\n", "prefixes": [ "next-queue", "v1", "2/4" ] }