From patchwork Thu Apr 18 05:25:00 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Mateusz Polchlopek X-Patchwork-Id: 1924823 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@legolas.ozlabs.org Authentication-Results: legolas.ozlabs.org; dkim=pass (2048-bit key; unprotected) header.d=osuosl.org header.i=@osuosl.org header.a=rsa-sha256 header.s=default header.b=lrrojNn/; dkim-atps=neutral Authentication-Results: legolas.ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=osuosl.org (client-ip=2605:bc80:3010::138; helo=smtp1.osuosl.org; envelope-from=intel-wired-lan-bounces@osuosl.org; receiver=patchwork.ozlabs.org) Received: from smtp1.osuosl.org (smtp1.osuosl.org [IPv6:2605:bc80:3010::138]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature ECDSA (secp384r1) server-digest SHA384) (No client certificate requested) by legolas.ozlabs.org (Postfix) with ESMTPS id 4VKmh443Vqz1yZ2 for ; Thu, 18 Apr 2024 15:35:16 +1000 (AEST) Received: from localhost (localhost [127.0.0.1]) by smtp1.osuosl.org (Postfix) with ESMTP id 30E1180ECF; Thu, 18 Apr 2024 05:35:10 +0000 (UTC) X-Virus-Scanned: amavis at osuosl.org Received: from smtp1.osuosl.org ([127.0.0.1]) by localhost (smtp1.osuosl.org [127.0.0.1]) (amavis, port 10024) with ESMTP id 6GtXwrG-ZxPz; Thu, 18 Apr 2024 05:35:08 +0000 (UTC) X-Comment: SPF check N/A for local connections - client-ip=140.211.166.34; helo=ash.osuosl.org; envelope-from=intel-wired-lan-bounces@osuosl.org; receiver= DKIM-Filter: OpenDKIM Filter v2.11.0 smtp1.osuosl.org B964581F47 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=osuosl.org; s=default; t=1713418507; bh=g07g41OJ2QjIGipeH1ktcOai23mrbvNBvzzoMKsYkhU=; h=From:To:Date:In-Reply-To:References:Subject:List-Id: List-Unsubscribe:List-Archive:List-Post:List-Help:List-Subscribe: Cc:From; b=lrrojNn/z2n6tzfAAAg5YrjoVdgatDkAY7awecy9WtWbJ0MqYj/JjhuRriubUVywN JiWDjBlhxUwyyGhbqezr+d7/U8D60jV4QDpBvZt2xesVqypsAxnHs/8peaGm1a+O9q ze4DsqLnBYJCBkC2YELN4jGf0OYeJx+iuAnAa9fJrFYCtak6Vbtwr18F82YSbW0gw5 dtDQjZDZIflM5gPtKCCexXjW/SaS6dmh5wy/WDhTdXAiy/o07kZlaIp7hqyk4c3zg9 1AJLGI1pg12grgziilDsWJKVoGr0q6AiLYcbTKSNL0Sk0T4KR6aQ1Zs3xqq7I4+rU4 rWEkQbPgv3VBg== Received: from ash.osuosl.org (ash.osuosl.org [140.211.166.34]) by smtp1.osuosl.org (Postfix) with ESMTP id B964581F47; Thu, 18 Apr 2024 05:35:07 +0000 (UTC) X-Original-To: intel-wired-lan@lists.osuosl.org Delivered-To: intel-wired-lan@lists.osuosl.org Received: from smtp2.osuosl.org (smtp2.osuosl.org [140.211.166.133]) by ash.osuosl.org (Postfix) with ESMTP id 9B9C51BF3A7 for ; Thu, 18 Apr 2024 05:34:56 +0000 (UTC) Received: from localhost (localhost [127.0.0.1]) by smtp2.osuosl.org (Postfix) with ESMTP id 884B240153 for ; Thu, 18 Apr 2024 05:34:56 +0000 (UTC) X-Virus-Scanned: amavis at osuosl.org Received: from smtp2.osuosl.org ([127.0.0.1]) by localhost (smtp2.osuosl.org [127.0.0.1]) (amavis, port 10024) with ESMTP id bjNOQ7IK3q1W for ; Thu, 18 Apr 2024 05:34:55 +0000 (UTC) Received-SPF: Pass (mailfrom) identity=mailfrom; client-ip=198.175.65.19; helo=mgamail.intel.com; envelope-from=mateusz.polchlopek@intel.com; receiver= DMARC-Filter: OpenDMARC Filter v1.4.2 smtp2.osuosl.org 701C64043A DKIM-Filter: OpenDKIM Filter v2.11.0 smtp2.osuosl.org 701C64043A Received: from mgamail.intel.com (mgamail.intel.com [198.175.65.19]) by smtp2.osuosl.org (Postfix) with ESMTPS id 701C64043A for ; Thu, 18 Apr 2024 05:34:55 +0000 (UTC) X-CSE-ConnectionGUID: X1pseYdUT6C2DQ+WC13XLQ== X-CSE-MsgGUID: ac7fN+XwRXqPtMrRJa93UA== X-IronPort-AV: E=McAfee;i="6600,9927,11047"; a="8814693" X-IronPort-AV: E=Sophos;i="6.07,211,1708416000"; d="scan'208";a="8814693" Received: from fmviesa009.fm.intel.com ([10.60.135.149]) by orvoesa111.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 17 Apr 2024 22:34:55 -0700 X-CSE-ConnectionGUID: MLZerBqfRyySfM/O30Fy+A== X-CSE-MsgGUID: Xyh67xQ7ROaK3Y2aD2unBg== X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="6.07,211,1708416000"; d="scan'208";a="22947416" Received: from irvmail002.ir.intel.com ([10.43.11.120]) by fmviesa009.fm.intel.com with ESMTP; 17 Apr 2024 22:34:53 -0700 Received: from fedora.igk.intel.com (Metan_eth.igk.intel.com [10.123.220.124]) by irvmail002.ir.intel.com (Postfix) with ESMTP id 867A128775; Thu, 18 Apr 2024 06:34:51 +0100 (IST) From: Mateusz Polchlopek To: intel-wired-lan@lists.osuosl.org Date: Thu, 18 Apr 2024 01:25:00 -0400 Message-Id: <20240418052500.50678-13-mateusz.polchlopek@intel.com> X-Mailer: git-send-email 2.38.1 In-Reply-To: <20240418052500.50678-1-mateusz.polchlopek@intel.com> References: <20240418052500.50678-1-mateusz.polchlopek@intel.com> MIME-Version: 1.0 X-Mailman-Original-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1713418495; x=1744954495; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=7miIVTjdXmjuLc51YGyDuBABAsDbSsCdgs5ojvEuWDY=; b=T99VwiTCJrOTSuVGoPnwKhikpt9G3LV1NZT6yKMsR5oLfax0Y1iCZBH6 x66rzxG8D88gdnZ9JmR4h/p6ryaw53zyO8D8a80NBqBLVVMUlIcDm1YDu rFjEa3jLTlWxRBD1SUM7CjuqzZnNop+oLQbYMgFXml1A6fTV0PIWDeI4Q BxHtXsPbc6BKnD1w6WyhlPfOI98GWUPYdBN67Sv9sQU2PAOFGKt7n0UMt obOavvPus2D8U0bZiJVBFuJWwyUnq7mwGwh/WiQuGO2w0N5EY1wpcEfuP SOgs6mbcp0BGKqrbsfPMeda9IRTT8z72+6gpuQ4bwgQ6Q2ZRKqy5i2lKB A==; X-Mailman-Original-Authentication-Results: smtp2.osuosl.org; dmarc=pass (p=none dis=none) header.from=intel.com X-Mailman-Original-Authentication-Results: smtp2.osuosl.org; dkim=pass (2048-bit key) header.d=intel.com header.i=@intel.com header.a=rsa-sha256 header.s=Intel header.b=T99VwiTC Subject: [Intel-wired-lan] [PATCH iwl-next v5 12/12] iavf: add support for Rx timestamps to hotpath X-BeenThere: intel-wired-lan@osuosl.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Intel Wired Ethernet Linux Kernel Driver Development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Wojciech Drewek , netdev@vger.kernel.org, anthony.l.nguyen@intel.com, horms@kernel.org, Mateusz Polchlopek , Jacob Keller Errors-To: intel-wired-lan-bounces@osuosl.org Sender: "Intel-wired-lan" From: Jacob Keller Add support for receive timestamps to the Rx hotpath. This support only works when using the flexible descriptor format, so make sure that we request this format by default if we have receive timestamp support available in the PTP capabilities. In order to report the timestamps to userspace, we need to perform timestamp extension. The Rx descriptor does actually contain the "40 bit" timestamp. However, upper 32 bits which contain nanoseconds are conveniently stored separately in the descriptor. We could extract the 32bits and lower 8 bits, then perform a bitwise OR to calculate the 40bit value. This makes no sense, because the timestamp extension algorithm would simply discard the lower 8 bits anyways. Thus, implement timestamp extension as iavf_ptp_extend_32b_timestamp(), and extract and forward only the 32bits of nominal nanoseconds. Reviewed-by: Wojciech Drewek Signed-off-by: Jacob Keller Signed-off-by: Mateusz Polchlopek Reviewed-by: Rahul Rameshbabu Reviewed-by: Sunil Goutham --- drivers/net/ethernet/intel/iavf/iavf_main.c | 9 +++ drivers/net/ethernet/intel/iavf/iavf_ptp.c | 69 +++++++++++++++++++++ drivers/net/ethernet/intel/iavf/iavf_ptp.h | 4 ++ drivers/net/ethernet/intel/iavf/iavf_txrx.c | 44 +++++++++++++ 4 files changed, 126 insertions(+) diff --git a/drivers/net/ethernet/intel/iavf/iavf_main.c b/drivers/net/ethernet/intel/iavf/iavf_main.c index a75c5fbad13c..b12cdef50deb 100644 --- a/drivers/net/ethernet/intel/iavf/iavf_main.c +++ b/drivers/net/ethernet/intel/iavf/iavf_main.c @@ -726,6 +726,15 @@ static u8 iavf_select_rx_desc_format(struct iavf_adapter *adapter) if (!RXDID_ALLOWED(adapter)) return VIRTCHNL_RXDID_1_32B_BASE; + /* Rx timestamping requires the use of flexible NIC descriptors */ + if (iavf_ptp_cap_supported(adapter, VIRTCHNL_1588_PTP_CAP_RX_TSTAMP)) { + if (supported_rxdids & BIT(VIRTCHNL_RXDID_2_FLEX_SQ_NIC)) + return VIRTCHNL_RXDID_2_FLEX_SQ_NIC; + + dev_dbg(&adapter->pdev->dev, + "Unable to negotiate flexible descriptor format.\n"); + } + /* Warn if the PF does not list support for the default legacy * descriptor format. This shouldn't happen, as this is the format * used if VIRTCHNL_VF_OFFLOAD_RX_FLEX_DESC is not supported. It is diff --git a/drivers/net/ethernet/intel/iavf/iavf_ptp.c b/drivers/net/ethernet/intel/iavf/iavf_ptp.c index 4ae80eac8236..e99cf380011f 100644 --- a/drivers/net/ethernet/intel/iavf/iavf_ptp.c +++ b/drivers/net/ethernet/intel/iavf/iavf_ptp.c @@ -444,6 +444,9 @@ void iavf_ptp_release(struct iavf_adapter *adapter) adapter->aq_required &= ~IAVF_FLAG_AQ_SEND_PTP_CMD; spin_unlock(&adapter->ptp.aq_cmd_lock); + adapter->ptp.hwtstamp_config.rx_filter = HWTSTAMP_FILTER_NONE; + iavf_ptp_disable_rx_tstamp(adapter); + adapter->ptp.initialized = false; } @@ -477,3 +480,69 @@ void iavf_ptp_process_caps(struct iavf_adapter *adapter) iavf_ptp_disable_rx_tstamp(adapter); } } + +/** + * iavf_ptp_extend_32b_timestamp - Convert a 32b nanoseconds timestamp to 64b + * nanoseconds + * @cached_phc_time: recently cached copy of PHC time + * @in_tstamp: Ingress/egress 32b nanoseconds timestamp value + * + * Hardware captures timestamps which contain only 32 bits of nominal + * nanoseconds, as opposed to the 64bit timestamps that the stack expects. + * + * Extend the 32bit nanosecond timestamp using the following algorithm and + * assumptions: + * + * 1) have a recently cached copy of the PHC time + * 2) assume that the in_tstamp was captured 2^31 nanoseconds (~2.1 + * seconds) before or after the PHC time was captured. + * 3) calculate the delta between the cached time and the timestamp + * 4) if the delta is smaller than 2^31 nanoseconds, then the timestamp was + * captured after the PHC time. In this case, the full timestamp is just + * the cached PHC time plus the delta. + * 5) otherwise, if the delta is larger than 2^31 nanoseconds, then the + * timestamp was captured *before* the PHC time, i.e. because the PHC + * cache was updated after the timestamp was captured by hardware. In this + * case, the full timestamp is the cached time minus the inverse delta. + * + * This algorithm works even if the PHC time was updated after a Tx timestamp + * was requested, but before the Tx timestamp event was reported from + * hardware. + * + * This calculation primarily relies on keeping the cached PHC time up to + * date. If the timestamp was captured more than 2^31 nanoseconds after the + * PHC time, it is possible that the lower 32bits of PHC time have + * overflowed more than once, and we might generate an incorrect timestamp. + * + * This is prevented by (a) periodically updating the cached PHC time once + * a second, and (b) discarding any Tx timestamp packet if it has waited for + * a timestamp for more than one second. + * + * Return: extended timestamp (to 64b) + */ +u64 iavf_ptp_extend_32b_timestamp(u64 cached_phc_time, u32 in_tstamp) +{ + const u64 mask = GENMASK_ULL(31, 0); + u32 delta; + u64 ns; + + /* Calculate the delta between the lower 32bits of the cached PHC + * time and the in_tstamp value + */ + delta = (in_tstamp - (u32)(cached_phc_time & mask)); + + /* Do not assume that the in_tstamp is always more recent than the + * cached PHC time. If the delta is large, it indicates that the + * in_tstamp was taken in the past, and should be converted + * forward. + */ + if (delta > (mask / 2)) { + /* reverse the delta calculation here */ + delta = ((u32)(cached_phc_time & mask) - in_tstamp); + ns = cached_phc_time - delta; + } else { + ns = cached_phc_time + delta; + } + + return ns; +} diff --git a/drivers/net/ethernet/intel/iavf/iavf_ptp.h b/drivers/net/ethernet/intel/iavf/iavf_ptp.h index 337bf184a7ea..66e113ae27f5 100644 --- a/drivers/net/ethernet/intel/iavf/iavf_ptp.h +++ b/drivers/net/ethernet/intel/iavf/iavf_ptp.h @@ -6,6 +6,9 @@ #include +/* bit indicating whether a 40bit timestamp is valid */ +#define IAVF_PTP_40B_TSTAMP_VALID BIT(0) + /* structure used to queue PTP commands for processing */ struct iavf_ptp_aq_cmd { struct list_head list; @@ -38,5 +41,6 @@ void iavf_virtchnl_send_ptp_cmd(struct iavf_adapter *adapter); long iavf_ptp_do_aux_work(struct ptp_clock_info *ptp); int iavf_ptp_get_ts_config(struct iavf_adapter *adapter, struct ifreq *ifr); int iavf_ptp_set_ts_config(struct iavf_adapter *adapter, struct ifreq *ifr); +u64 iavf_ptp_extend_32b_timestamp(u64 cached_phc_time, u32 in_tstamp); #endif /* _IAVF_PTP_H_ */ diff --git a/drivers/net/ethernet/intel/iavf/iavf_txrx.c b/drivers/net/ethernet/intel/iavf/iavf_txrx.c index 8e90b0b2a292..9a2bd5176818 100644 --- a/drivers/net/ethernet/intel/iavf/iavf_txrx.c +++ b/drivers/net/ethernet/intel/iavf/iavf_txrx.c @@ -1239,6 +1239,48 @@ static void iavf_flex_rx_hash(struct iavf_ring *ring, } } +/** + * iavf_flex_rx_tstamp - Capture Rx timestamp from the descriptor + * @rx_ring: descriptor ring + * @rx_desc: specific descriptor + * @skb: skb currently being received + * + * Read the Rx timestamp value from the descriptor and pass it to the stack. + * + * This function only operates on the VIRTCHNL_RXDID_2_FLEX_SQ_NIC flexible + * descriptor writeback format. + */ +static void iavf_flex_rx_tstamp(struct iavf_ring *rx_ring, + union iavf_rx_desc *rx_desc, + struct sk_buff *skb) +{ + struct skb_shared_hwtstamps *skb_tstamps; + struct iavf_adapter *adapter; + u32 tstamp; + u64 ns; + + /* Skip processing if timestamps aren't enabled */ + if (!(rx_ring->flags & IAVF_TXRX_FLAGS_HW_TSTAMP)) + return; + + /* Check if this Rx descriptor has a valid timestamp */ + if (!(rx_desc->flex_wb.ts_low & IAVF_PTP_40B_TSTAMP_VALID)) + return; + + adapter = netdev_priv(rx_ring->netdev); + + /* the ts_low field only contains the valid bit and sub-nanosecond + * precision, so we don't need to extract it. + */ + tstamp = le32_to_cpu(rx_desc->flex_wb.flex_ts.ts_high); + ns = iavf_ptp_extend_32b_timestamp(adapter->ptp.cached_phc_time, + tstamp); + + skb_tstamps = skb_hwtstamps(skb); + memset(skb_tstamps, 0, sizeof(*skb_tstamps)); + skb_tstamps->hwtstamp = ns_to_ktime(ns); +} + /** * iavf_process_skb_fields - Populate skb header fields from Rx descriptor * @rx_ring: rx descriptor ring packet is being transacted on @@ -1262,6 +1304,8 @@ static void iavf_process_skb_fields(struct iavf_ring *rx_ring, iavf_flex_rx_hash(rx_ring, rx_desc, skb, rx_ptype); iavf_flex_rx_csum(rx_ring->vsi, skb, rx_desc); + + iavf_flex_rx_tstamp(rx_ring, rx_desc, skb); } skb_record_rx_queue(skb, rx_ring->queue_index);