Patch Detail
get:
Show a patch.
patch:
Update a patch.
put:
Update a patch.
GET /api/patches/1203359/?format=api
{ "id": 1203359, "url": "http://patchwork.ozlabs.org/api/patches/1203359/?format=api", "web_url": "http://patchwork.ozlabs.org/project/intel-wired-lan/patch/20191202231953.2203397-4-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": "<20191202231953.2203397-4-vinicius.gomes@intel.com>", "list_archive_url": null, "date": "2019-12-02T23:19:51", "name": "[next-queue,v3,3/5] igc: Add support for TX timestamping", "commit_ref": null, "pull_url": null, "state": "accepted", "archived": false, "hash": "c83f807d4fb616ea603e99a8fb4a41fc14bdf368", "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/20191202231953.2203397-4-vinicius.gomes@intel.com/mbox/", "series": [ { "id": 146115, "url": "http://patchwork.ozlabs.org/api/series/146115/?format=api", "web_url": "http://patchwork.ozlabs.org/project/intel-wired-lan/list/?series=146115", "date": "2019-12-02T23:19:53", "name": "igc: Add basic support for Timestamping/PTP", "version": 3, "mbox": "http://patchwork.ozlabs.org/series/146115/mbox/" } ], "comments": "http://patchwork.ozlabs.org/api/patches/1203359/comments/", "check": "pending", "checks": "http://patchwork.ozlabs.org/api/patches/1203359/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 47Rh0y4xSPz9sRQ\n\tfor <incoming@patchwork.ozlabs.org>;\n\tTue, 3 Dec 2019 10:20:18 +1100 (AEDT)", "from localhost (localhost [127.0.0.1])\n\tby whitealder.osuosl.org (Postfix) with ESMTP id DD7A886382;\n\tMon, 2 Dec 2019 23:20:16 +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 eldBluS9U2oo; Mon, 2 Dec 2019 23:20:14 +0000 (UTC)", "from ash.osuosl.org (ash.osuosl.org [140.211.166.34])\n\tby whitealder.osuosl.org (Postfix) with ESMTP id 2C42886ED5;\n\tMon, 2 Dec 2019 23:20:14 +0000 (UTC)", "from fraxinus.osuosl.org (smtp4.osuosl.org [140.211.166.137])\n\tby ash.osuosl.org (Postfix) with ESMTP id 6C9461BF391\n\tfor <intel-wired-lan@lists.osuosl.org>;\n\tMon, 2 Dec 2019 23:20:12 +0000 (UTC)", "from localhost (localhost [127.0.0.1])\n\tby fraxinus.osuosl.org (Postfix) with ESMTP id 6978A8623B\n\tfor <intel-wired-lan@lists.osuosl.org>;\n\tMon, 2 Dec 2019 23:20:12 +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 cAHnz1MfvOkj for <intel-wired-lan@lists.osuosl.org>;\n\tMon, 2 Dec 2019 23:20:11 +0000 (UTC)", "from mga02.intel.com (mga02.intel.com [134.134.136.20])\n\tby fraxinus.osuosl.org (Postfix) with ESMTPS id ACBE385DC0\n\tfor <intel-wired-lan@lists.osuosl.org>;\n\tMon, 2 Dec 2019 23:20:07 +0000 (UTC)", "from orsmga006.jf.intel.com ([10.7.209.51])\n\tby orsmga101.jf.intel.com with ESMTP/TLS/DHE-RSA-AES256-GCM-SHA384;\n\t02 Dec 2019 15:19:53 -0800", "from vcostago-desk1.jf.intel.com ([10.54.70.26])\n\tby orsmga006.jf.intel.com with ESMTP; 02 Dec 2019 15:19:55 -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,270,1571727600\"; d=\"scan'208\";a=\"213201669\"", "From": "Vinicius Costa Gomes <vinicius.gomes@intel.com>", "To": "intel-wired-lan@lists.osuosl.org", "Date": "Mon, 2 Dec 2019 15:19:51 -0800", "Message-Id": "<20191202231953.2203397-4-vinicius.gomes@intel.com>", "X-Mailer": "git-send-email 2.24.0", "In-Reply-To": "<20191202231953.2203397-1-vinicius.gomes@intel.com>", "References": "<20191202231953.2203397-1-vinicius.gomes@intel.com>", "MIME-Version": "1.0", "Subject": "[Intel-wired-lan] [next-queue PATCH v3 3/5] igc: Add support for TX\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 packets being transmitted.\n\nBased on the code from i210. The basic differences is that i225 has 4\nregisters to store the transmit timestamps (i210 has one). Right now,\nwe only support retrieving from one register, support for using the\nother registers will be added later.\n\nSigned-off-by: Vinicius Costa Gomes <vinicius.gomes@intel.com>\n---\n drivers/net/ethernet/intel/igc/igc.h | 2 +\n drivers/net/ethernet/intel/igc/igc_defines.h | 14 +++\n drivers/net/ethernet/intel/igc/igc_main.c | 49 +++++++++++\n drivers/net/ethernet/intel/igc/igc_ptp.c | 92 ++++++++++++++++++++\n 4 files changed, 157 insertions(+)", "diff": "diff --git a/drivers/net/ethernet/intel/igc/igc.h b/drivers/net/ethernet/intel/igc/igc.h\nindex ae9161482c84..cad1db035008 100644\n--- a/drivers/net/ethernet/intel/igc/igc.h\n+++ b/drivers/net/ethernet/intel/igc/igc.h\n@@ -558,6 +558,8 @@ 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+void igc_ptp_tx_hang(struct igc_adapter *adapter);\n+\n #define igc_rx_pg_size(_ring) (PAGE_SIZE << igc_rx_pg_order(_ring))\n \n #define IGC_TXD_DCMD\t(IGC_ADVTXD_DCMD_EOP | IGC_ADVTXD_DCMD_RS)\ndiff --git a/drivers/net/ethernet/intel/igc/igc_defines.h b/drivers/net/ethernet/intel/igc/igc_defines.h\nindex ea30e9756389..2ecaeddc6d3d 100644\n--- a/drivers/net/ethernet/intel/igc/igc_defines.h\n+++ b/drivers/net/ethernet/intel/igc/igc_defines.h\n@@ -401,10 +401,24 @@\n #define IGC_TSYNCRXCFG_PTP_V1_SYNC_MESSAGE\t0x00\n #define IGC_TSYNCRXCFG_PTP_V1_DELAY_REQ_MESSAGE\t0x01\n \n+/* Immediate Interrupt Receive */\n+#define IGC_IMIR_CLEAR_MASK\t0xF001FFFF /* IMIR Reg Clear Mask */\n+#define IGC_IMIR_PORT_BYPASS\t0x20000 /* IMIR Port Bypass Bit */\n+#define IGC_IMIR_PRIORITY_SHIFT\t29 /* IMIR Priority Shift */\n+#define IGC_IMIREXT_CLEAR_MASK\t0x7FFFF /* IMIREXT Reg Clear Mask */\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+/* Time Sync Transmit Control bit definitions */\n+#define IGC_TSYNCTXCTL_VALID\t\t\t0x00000001 /* Tx timestamp valid */\n+#define IGC_TSYNCTXCTL_ENABLED\t\t\t0x00000010 /* enable Tx timestamping */\n+#define IGC_TSYNCTXCTL_MAX_ALLOWED_DLY_MASK\t0x0000F000 /* max delay */\n+#define IGC_TSYNCTXCTL_SYNC_COMP_ERR\t\t0x20000000 /* sync err */\n+#define IGC_TSYNCTXCTL_SYNC_COMP\t\t0x40000000 /* sync complete */\n+#define IGC_TSYNCTXCTL_START_SYNC\t\t0x80000000 /* initiate sync */\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 ffde4dc7c226..e48ff6df1a15 100644\n--- a/drivers/net/ethernet/intel/igc/igc_main.c\n+++ b/drivers/net/ethernet/intel/igc/igc_main.c\n@@ -987,6 +987,11 @@ static inline int igc_maybe_stop_tx(struct igc_ring *tx_ring, const u16 size)\n \treturn __igc_maybe_stop_tx(tx_ring, size);\n }\n \n+#define IGC_SET_FLAG(_input, _flag, _result) \\\n+\t(((_flag) <= (_result)) ?\t\t\t\t\\\n+\t ((u32)((_input) & (_flag)) * ((_result) / (_flag))) :\t\\\n+\t ((u32)((_input) & (_flag)) / ((_flag) / (_result))))\n+\n static u32 igc_tx_cmd_type(struct sk_buff *skb, u32 tx_flags)\n {\n \t/* set type for advanced descriptor with frame checksum insertion */\n@@ -994,6 +999,10 @@ static u32 igc_tx_cmd_type(struct sk_buff *skb, u32 tx_flags)\n \t\t IGC_ADVTXD_DCMD_DEXT |\n \t\t IGC_ADVTXD_DCMD_IFCS;\n \n+\t/* set timestamp bit if present */\n+\tcmd_type |= IGC_SET_FLAG(tx_flags, IGC_TX_FLAGS_TSTAMP,\n+\t\t\t\t (IGC_ADVTXD_MAC_TSTAMP));\n+\n \treturn cmd_type;\n }\n \n@@ -1192,6 +1201,26 @@ static netdev_tx_t igc_xmit_frame_ring(struct sk_buff *skb,\n \tfirst->bytecount = skb->len;\n \tfirst->gso_segs = 1;\n \n+\tif (unlikely(skb_shinfo(skb)->tx_flags & SKBTX_HW_TSTAMP)) {\n+\t\tstruct igc_adapter *adapter = netdev_priv(tx_ring->netdev);\n+\n+\t\t/* FIXME: add support for retrieving timestamps from\n+\t\t * the other timer registers before skipping the\n+\t\t * timestamping request.\n+\t\t */\n+\t\tif (adapter->tstamp_config.tx_type == HWTSTAMP_TX_ON &&\n+\t\t !test_and_set_bit_lock(__IGC_PTP_TX_IN_PROGRESS,\n+\t\t\t\t\t &adapter->state)) {\n+\t\t\tskb_shinfo(skb)->tx_flags |= SKBTX_IN_PROGRESS;\n+\t\t\ttx_flags |= IGC_TX_FLAGS_TSTAMP;\n+\n+\t\t\tadapter->ptp_tx_skb = skb_get(skb);\n+\t\t\tadapter->ptp_tx_start = jiffies;\n+\t\t} else {\n+\t\t\tadapter->tx_hwtstamp_skipped++;\n+\t\t}\n+\t}\n+\n \t/* record initial flags and protocol */\n \tfirst->tx_flags = tx_flags;\n \tfirst->protocol = protocol;\n@@ -3648,6 +3677,21 @@ int igc_del_mac_steering_filter(struct igc_adapter *adapter,\n \t\t\t\t\tIGC_MAC_STATE_QUEUE_STEERING | flags);\n }\n \n+static void igc_tsync_interrupt(struct igc_adapter *adapter)\n+{\n+\tstruct igc_hw *hw = &adapter->hw;\n+\tu32 ack = 0, tsicr = rd32(IGC_TSICR);\n+\n+\tif (tsicr & IGC_TSICR_TXTS) {\n+\t\t/* retrieve hardware timestamp */\n+\t\tschedule_work(&adapter->ptp_tx_work);\n+\t\tack |= IGC_TSICR_TXTS;\n+\t}\n+\n+\t/* acknowledge the interrupts */\n+\twr32(IGC_TSICR, ack);\n+}\n+\n /**\n * igc_msix_other - msix other interrupt handler\n * @irq: interrupt number\n@@ -3675,6 +3719,9 @@ static irqreturn_t igc_msix_other(int irq, void *data)\n \t\t\tmod_timer(&adapter->watchdog_timer, jiffies + 1);\n \t}\n \n+\tif (icr & IGC_ICR_TS)\n+\t\tigc_tsync_interrupt(adapter);\n+\n \twr32(IGC_EIMS, adapter->eims_other);\n \n \treturn IRQ_HANDLED;\n@@ -4004,6 +4051,8 @@ static void igc_watchdog_task(struct work_struct *work)\n \t\twr32(IGC_ICS, IGC_ICS_RXDMT0);\n \t}\n \n+\tigc_ptp_tx_hang(adapter);\n+\n \t/* Reset the timer */\n \tif (!test_bit(__IGC_DOWN, &adapter->state)) {\n \t\tif (adapter->flags & IGC_FLAG_NEED_LINK_UPDATE)\ndiff --git a/drivers/net/ethernet/intel/igc/igc_ptp.c b/drivers/net/ethernet/intel/igc/igc_ptp.c\nindex b39d14d40ec9..b63a03157ec1 100644\n--- a/drivers/net/ethernet/intel/igc/igc_ptp.c\n+++ b/drivers/net/ethernet/intel/igc/igc_ptp.c\n@@ -284,6 +284,12 @@ static void igc_ptp_enable_tstamp_all_rxqueues(struct igc_adapter *adapter,\n * @adapter: networking device structure\n * @config: hwtstamp configuration\n *\n+ * Outgoing time stamping can be enabled and disabled. Play nice and\n+ * disable it when requested, although it shouldn't case any overhead\n+ * when no packet needs it. At most one packet in the queue may be\n+ * marked for time stamping, otherwise it would be impossible to tell\n+ * for sure to which packet the hardware time stamp belongs.\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@@ -295,6 +301,7 @@ 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_tx_ctl = IGC_TSYNCTXCTL_ENABLED;\n \tu32 tsync_rx_ctl = IGC_TSYNCRXCTL_ENABLED;\n \tu32 tsync_rx_cfg = 0;\n \tbool is_l4 = false;\n@@ -305,6 +312,15 @@ static int igc_ptp_set_timestamp_mode(struct igc_adapter *adapter,\n \tif (config->flags)\n \t\treturn -EINVAL;\n \n+\tswitch (config->tx_type) {\n+\tcase HWTSTAMP_TX_OFF:\n+\t\ttsync_tx_ctl = 0;\n+\tcase HWTSTAMP_TX_ON:\n+\t\tbreak;\n+\tdefault:\n+\t\treturn -ERANGE;\n+\t}\n+\n \tswitch (config->rx_filter) {\n \tcase HWTSTAMP_FILTER_NONE:\n \t\ttsync_rx_ctl = 0;\n@@ -368,6 +384,15 @@ static int igc_ptp_set_timestamp_mode(struct igc_adapter *adapter,\n \t\t}\n \t}\n \n+\tif (tsync_tx_ctl)\n+\t\ttsync_tx_ctl = IGC_TSYNCTXCTL_ENABLED;\n+\n+\t/* enable/disable TX */\n+\tregval = rd32(IGC_TSYNCTXCTL);\n+\tregval &= ~IGC_TSYNCTXCTL_ENABLED;\n+\tregval |= tsync_tx_ctl;\n+\twr32(IGC_TSYNCTXCTL, regval);\n+\n \t/* enable/disable RX */\n \tregval = rd32(IGC_TSYNCRXCTL);\n \tregval &= ~(IGC_TSYNCRXCTL_ENABLED | IGC_TSYNCRXCTL_TYPE_MASK);\n@@ -442,8 +467,75 @@ void igc_ptp_tx_hang(struct igc_adapter *adapter)\n \t}\n }\n \n+/**\n+ * igc_ptp_tx_hwtstamp - utility function which checks for TX time stamp\n+ * @adapter: Board private structure.\n+ *\n+ * If we were asked to do hardware stamping and such a time stamp is\n+ * available, then it must have been for this skb here because we only\n+ * allow only one such packet into the queue.\n+ */\n+static void igc_ptp_tx_hwtstamp(struct igc_adapter *adapter)\n+{\n+\tstruct sk_buff *skb = adapter->ptp_tx_skb;\n+\tstruct skb_shared_hwtstamps shhwtstamps;\n+\tstruct igc_hw *hw = &adapter->hw;\n+\tu64 regval;\n+\n+\tregval = rd32(IGC_TXSTMPL);\n+\tregval |= (u64)rd32(IGC_TXSTMPH) << 32;\n+\tigc_ptp_systim_to_hwtstamp(adapter, &shhwtstamps, regval);\n+\n+\t/* Clear the lock early before calling skb_tstamp_tx so that\n+\t * applications are not woken up before the lock bit is clear. We use\n+\t * a copy of the skb pointer to ensure other threads can't change it\n+\t * while we're notifying the stack.\n+\t */\n+\tadapter->ptp_tx_skb = NULL;\n+\tclear_bit_unlock(__IGC_PTP_TX_IN_PROGRESS, &adapter->state);\n+\n+\t/* Notify the stack and free the skb after we've unlocked */\n+\tskb_tstamp_tx(skb, &shhwtstamps);\n+\tdev_kfree_skb_any(skb);\n+}\n+\n+/**\n+ * igc_ptp_tx_work\n+ * @work: pointer to work struct\n+ *\n+ * This work function polls the TSYNCTXCTL valid bit to determine when a\n+ * timestamp has been taken for the current stored skb.\n+ */\n void igc_ptp_tx_work(struct work_struct *work)\n {\n+\tstruct igc_adapter *adapter = container_of(work, struct igc_adapter,\n+\t\t\t\t\t\t ptp_tx_work);\n+\tstruct igc_hw *hw = &adapter->hw;\n+\tu32 tsynctxctl;\n+\n+\tif (!adapter->ptp_tx_skb)\n+\t\treturn;\n+\n+\tif (time_is_before_jiffies(adapter->ptp_tx_start +\n+\t\t\t\t IGC_PTP_TX_TIMEOUT)) {\n+\t\tdev_kfree_skb_any(adapter->ptp_tx_skb);\n+\t\tadapter->ptp_tx_skb = NULL;\n+\t\tclear_bit_unlock(__IGC_PTP_TX_IN_PROGRESS, &adapter->state);\n+\t\tadapter->tx_hwtstamp_timeouts++;\n+\t\t/* Clear the tx valid bit in TSYNCTXCTL register to enable\n+\t\t * interrupt\n+\t\t */\n+\t\trd32(IGC_TXSTMPH);\n+\t\tdev_warn(&adapter->pdev->dev, \"clearing Tx timestamp hang\\n\");\n+\t\treturn;\n+\t}\n+\n+\ttsynctxctl = rd32(IGC_TSYNCTXCTL);\n+\tif (tsynctxctl & IGC_TSYNCTXCTL_VALID)\n+\t\tigc_ptp_tx_hwtstamp(adapter);\n+\telse\n+\t\t/* reschedule to check later */\n+\t\tschedule_work(&adapter->ptp_tx_work);\n }\n \n /**\n", "prefixes": [ "next-queue", "v3", "3/5" ] }