From patchwork Sun Apr 3 17:55:40 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Gerhard Engleder X-Patchwork-Id: 12799662 X-Patchwork-Delegate: kuba@kernel.org Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 86D3AC4332F for ; Sun, 3 Apr 2022 17:56:32 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S241715AbiDCR6X (ORCPT ); Sun, 3 Apr 2022 13:58:23 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:50376 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1359712AbiDCR6K (ORCPT ); Sun, 3 Apr 2022 13:58:10 -0400 Received: from mail-ed1-x52e.google.com (mail-ed1-x52e.google.com [IPv6:2a00:1450:4864:20::52e]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id C400838BC3 for ; Sun, 3 Apr 2022 10:55:59 -0700 (PDT) Received: by mail-ed1-x52e.google.com with SMTP id b24so8506174edu.10 for ; Sun, 03 Apr 2022 10:55:59 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=engleder-embedded-com.20210112.gappssmtp.com; s=20210112; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=CnjlWhysPRTkp9rGG1iCRqY0fG2HcVGyZm/JObISTGY=; b=n6YCJC+ds9WInEHMqk9oLdSQc5UklvQt/YcJ+q7x648AevVMkCt9YFktffj3h4N5o5 q4anA9THQBoXomnivcNLDwGe1Npxz4A3TwI9tFYctv3247FuoQAK3Y9acjOCZ6mQNmWH xwqAQoDsqx4s6H5z6lGdrFfsSNNtxwFyKhOYXZm5iFhCuDkdmcFUfIa/BDHvyW1+C5Ec mvnxSrs38k/KAOtPpR8cGTMZHyLorgi8oZSYu8SUi8vWPMoAIlvvJ0ePgRR0yLYOD2fi oofxLccao8VyOlG1gT7TQOaCAHuZKez0SqSGkpisbslvGmbWn4gkH3BdWPMH2VD6Bwa5 GO7w== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=CnjlWhysPRTkp9rGG1iCRqY0fG2HcVGyZm/JObISTGY=; b=X/ve7eosdcD6Gcahygg1IkepoSwYmOuM6S8+ZOqaYXrq4z5VVyDj7AH2bu2dBapYHw DMTNVa5BkU3KpyoOoI3b6p98tRYjqyMH9Xvk7b0WraaCUddw3HJ2cluqCsFOJkXDJ2wV AeOs6mAUCRvvTqMXDFEnmh/rAOezDg/M8CF0pt9i8hOD4kWgvqxBsXx5R6JTPdjcknDH tkda2hJPPIxG6POaBnXQBGEkfYh0JGc5VOI8Ify8jlmjxYPcLDpXZcglLKL6Orirq8Ct gULL3/zyItKbk+y6c3T2JDhxcYHy6IZnTYFACB6qZ/OMGULIdL+P9pHho2ow15XskjEc ZYJw== X-Gm-Message-State: AOAM530xafoVoyZtr3LPwbw5oFccn64GxUTMOrdr+LA4t4STCuW/Bmo7 npopvJ+DdB+xM9BIy6g1hHeHOaDGrLWQs6If X-Google-Smtp-Source: ABdhPJwZm/O/bExIo0jFIOMmGlwtJ3s/1KhTg+e3wdxGU5SCQiRKrIjmkIKeF+unv9VN0Blj3sLNcQ== X-Received: by 2002:a05:6402:1385:b0:413:2bc6:4400 with SMTP id b5-20020a056402138500b004132bc64400mr30288727edv.94.1649008558251; Sun, 03 Apr 2022 10:55:58 -0700 (PDT) Received: from hornet.engleder.at ([2001:871:23a:8366:6e3b:e5ff:fe2c:34c1]) by smtp.gmail.com with ESMTPSA id q7-20020a170906540700b006d5eca5c9cfsm3451065ejo.191.2022.04.03.10.55.57 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sun, 03 Apr 2022 10:55:57 -0700 (PDT) From: Gerhard Engleder To: richardcochran@gmail.com, vinicius.gomes@intel.com, yangbo.lu@nxp.com, davem@davemloft.net, kuba@kernel.org Cc: mlichvar@redhat.com, netdev@vger.kernel.org, Gerhard Engleder Subject: [PATCH net-next v2 1/5] ptp: Add cycles support for virtual clocks Date: Sun, 3 Apr 2022 19:55:40 +0200 Message-Id: <20220403175544.26556-2-gerhard@engleder-embedded.com> X-Mailer: git-send-email 2.20.1 In-Reply-To: <20220403175544.26556-1-gerhard@engleder-embedded.com> References: <20220403175544.26556-1-gerhard@engleder-embedded.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org X-Patchwork-Delegate: kuba@kernel.org ptp vclocks require a free running time for their timecounter. Currently only a physical clock forced to free running is supported. If vclocks are used, then the physical clock cannot be synchronized anymore. The synchronized time is not available in hardware in this case. As a result, timed transmission with TAPRIO hardware support is not possible anymore. If hardware would support a free running time additionally to the physical clock, then the physical clock does not need to be forced to free running. Thus, the physical clocks can still be synchronized while vclocks are in use. The physical clock could be used to synchronize the time domain of the TSN network and trigger TAPRIO. In parallel vclocks can be used to synchronize other time domains. Introduce support for a free running cycle counter called cycles to physical clocks. Rework ptp vclocks to use this free running cycle counter. Default implementation is based on time of physical clock. Thus, behavior of ptp vclocks based on physical clocks without free running cycle counter is identical to previous behavior. Signed-off-by: Gerhard Engleder --- drivers/ptp/ptp_clock.c | 31 +++++++++++++++++++++++++++---- drivers/ptp/ptp_private.h | 10 ++++++++++ drivers/ptp/ptp_sysfs.c | 10 ++++++---- drivers/ptp/ptp_vclock.c | 13 +++++-------- include/linux/ptp_clock_kernel.h | 31 +++++++++++++++++++++++++++++++ 5 files changed, 79 insertions(+), 16 deletions(-) diff --git a/drivers/ptp/ptp_clock.c b/drivers/ptp/ptp_clock.c index b6f2cfd15dd2..11b8190807c3 100644 --- a/drivers/ptp/ptp_clock.c +++ b/drivers/ptp/ptp_clock.c @@ -77,8 +77,8 @@ static int ptp_clock_settime(struct posix_clock *pc, const struct timespec64 *tp { struct ptp_clock *ptp = container_of(pc, struct ptp_clock, clock); - if (ptp_vclock_in_use(ptp)) { - pr_err("ptp: virtual clock in use\n"); + if (ptp_clock_freerun(ptp)) { + pr_err("ptp: physical clock is free running\n"); return -EBUSY; } @@ -103,8 +103,8 @@ static int ptp_clock_adjtime(struct posix_clock *pc, struct __kernel_timex *tx) struct ptp_clock_info *ops; int err = -EOPNOTSUPP; - if (ptp_vclock_in_use(ptp)) { - pr_err("ptp: virtual clock in use\n"); + if (ptp_clock_freerun(ptp)) { + pr_err("ptp: physical clock is free running\n"); return -EBUSY; } @@ -178,6 +178,14 @@ static void ptp_clock_release(struct device *dev) kfree(ptp); } +static int ptp_getcycles64(struct ptp_clock_info *info, struct timespec64 *ts) +{ + if (info->getcyclesx64) + return info->getcyclesx64(info, ts, NULL); + else + return info->gettime64(info, ts); +} + static void ptp_aux_kworker(struct kthread_work *work) { struct ptp_clock *ptp = container_of(work, struct ptp_clock, @@ -225,6 +233,21 @@ struct ptp_clock *ptp_clock_register(struct ptp_clock_info *info, mutex_init(&ptp->n_vclocks_mux); init_waitqueue_head(&ptp->tsev_wq); + if (!ptp->info->getcycles64 && !ptp->info->getcyclesx64) { + /* Free running cycle counter not supported, use time. */ + ptp->info->getcycles64 = ptp_getcycles64; + + if (ptp->info->gettimex64) + ptp->info->getcyclesx64 = ptp->info->gettimex64; + + if (ptp->info->getcrosststamp) + ptp->info->getcrosscycles = ptp->info->getcrosststamp; + } else { + ptp->has_cycles = true; + if (!ptp->info->getcycles64 && ptp->info->getcyclesx64) + ptp->info->getcycles64 = ptp_getcycles64; + } + if (ptp->info->do_aux_work) { kthread_init_delayed_work(&ptp->aux_work, ptp_aux_kworker); ptp->kworker = kthread_create_worker(0, "ptp%d", ptp->index); diff --git a/drivers/ptp/ptp_private.h b/drivers/ptp/ptp_private.h index dba6be477067..ab47c10b3874 100644 --- a/drivers/ptp/ptp_private.h +++ b/drivers/ptp/ptp_private.h @@ -52,6 +52,7 @@ struct ptp_clock { int *vclock_index; struct mutex n_vclocks_mux; /* protect concurrent n_vclocks access */ bool is_virtual_clock; + bool has_cycles; }; #define info_to_vclock(d) container_of((d), struct ptp_vclock, info) @@ -96,6 +97,15 @@ static inline bool ptp_vclock_in_use(struct ptp_clock *ptp) return in_use; } +/* Check if ptp clock shall be free running */ +static inline bool ptp_clock_freerun(struct ptp_clock *ptp) +{ + if (ptp->has_cycles) + return false; + + return ptp_vclock_in_use(ptp); +} + extern struct class *ptp_class; /* diff --git a/drivers/ptp/ptp_sysfs.c b/drivers/ptp/ptp_sysfs.c index 9233bfedeb17..414a70d32571 100644 --- a/drivers/ptp/ptp_sysfs.c +++ b/drivers/ptp/ptp_sysfs.c @@ -231,10 +231,12 @@ static ssize_t n_vclocks_store(struct device *dev, *(ptp->vclock_index + ptp->n_vclocks - i) = -1; } - if (num == 0) - dev_info(dev, "only physical clock in use now\n"); - else - dev_info(dev, "guarantee physical clock free running\n"); + if (!ptp->has_cycles) { + if (num == 0) + dev_info(dev, "only physical clock in use now\n"); + else + dev_info(dev, "guarantee physical clock free running\n"); + } ptp->n_vclocks = num; mutex_unlock(&ptp->n_vclocks_mux); diff --git a/drivers/ptp/ptp_vclock.c b/drivers/ptp/ptp_vclock.c index cb179a3ea508..3a095eab9cc5 100644 --- a/drivers/ptp/ptp_vclock.c +++ b/drivers/ptp/ptp_vclock.c @@ -68,7 +68,7 @@ static int ptp_vclock_gettimex(struct ptp_clock_info *ptp, int err; u64 ns; - err = pptp->info->gettimex64(pptp->info, &pts, sts); + err = pptp->info->getcyclesx64(pptp->info, &pts, sts); if (err) return err; @@ -104,7 +104,7 @@ static int ptp_vclock_getcrosststamp(struct ptp_clock_info *ptp, int err; u64 ns; - err = pptp->info->getcrosststamp(pptp->info, xtstamp); + err = pptp->info->getcrosscycles(pptp->info, xtstamp); if (err) return err; @@ -143,10 +143,7 @@ static u64 ptp_vclock_read(const struct cyclecounter *cc) struct ptp_clock *ptp = vclock->pclock; struct timespec64 ts = {}; - if (ptp->info->gettimex64) - ptp->info->gettimex64(ptp->info, &ts, NULL); - else - ptp->info->gettime64(ptp->info, &ts); + ptp->info->getcycles64(ptp->info, &ts); return timespec64_to_ns(&ts); } @@ -168,11 +165,11 @@ struct ptp_vclock *ptp_vclock_register(struct ptp_clock *pclock) vclock->pclock = pclock; vclock->info = ptp_vclock_info; - if (pclock->info->gettimex64) + if (pclock->info->getcyclesx64) vclock->info.gettimex64 = ptp_vclock_gettimex; else vclock->info.gettime64 = ptp_vclock_gettime; - if (pclock->info->getcrosststamp) + if (pclock->info->getcrosscycles) vclock->info.getcrosststamp = ptp_vclock_getcrosststamp; vclock->cc = ptp_vclock_cc; diff --git a/include/linux/ptp_clock_kernel.h b/include/linux/ptp_clock_kernel.h index 554454cb8693..3ea7110a9d70 100644 --- a/include/linux/ptp_clock_kernel.h +++ b/include/linux/ptp_clock_kernel.h @@ -108,6 +108,32 @@ struct ptp_system_timestamp { * @settime64: Set the current time on the hardware clock. * parameter ts: Time value to set. * + * @getcycles64: Reads the current free running cycle counter from the hardware + * clock. + * If @getcycles64 and @getcyclesx64 are not supported, then + * @gettime64 or @gettimex64 will be used as default + * implementation. + * parameter ts: Holds the result. + * + * @getcyclesx64: Reads the current free running cycle counter from the + * hardware clock and optionally also the system clock. + * If @getcycles64 and @getcyclesx64 are not supported, then + * @gettimex64 will be used as default implementation if + * available. + * parameter ts: Holds the PHC timestamp. + * parameter sts: If not NULL, it holds a pair of timestamps + * from the system clock. The first reading is made right before + * reading the lowest bits of the PHC timestamp and the second + * reading immediately follows that. + * + * @getcrosscycles: Reads the current free running cycle counter from the + * hardware clock and system clock simultaneously. + * If @getcycles64 and @getcyclesx64 are not supported, then + * @getcrosststamp will be used as default implementation if + * available. + * parameter cts: Contains timestamp (device,system) pair, + * where system time is realtime and monotonic. + * * @enable: Request driver to enable or disable an ancillary feature. * parameter request: Desired resource to enable or disable. * parameter on: Caller passes one to enable or zero to disable. @@ -155,6 +181,11 @@ struct ptp_clock_info { int (*getcrosststamp)(struct ptp_clock_info *ptp, struct system_device_crosststamp *cts); int (*settime64)(struct ptp_clock_info *p, const struct timespec64 *ts); + int (*getcycles64)(struct ptp_clock_info *ptp, struct timespec64 *ts); + int (*getcyclesx64)(struct ptp_clock_info *ptp, struct timespec64 *ts, + struct ptp_system_timestamp *sts); + int (*getcrosscycles)(struct ptp_clock_info *ptp, + struct system_device_crosststamp *cts); int (*enable)(struct ptp_clock_info *ptp, struct ptp_clock_request *request, int on); int (*verify)(struct ptp_clock_info *ptp, unsigned int pin, From patchwork Sun Apr 3 17:55:41 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Gerhard Engleder X-Patchwork-Id: 12799659 X-Patchwork-Delegate: kuba@kernel.org Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 56771C433F5 for ; Sun, 3 Apr 2022 17:56:32 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S240320AbiDCR6U (ORCPT ); Sun, 3 Apr 2022 13:58:20 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:50394 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S240283AbiDCR6I (ORCPT ); Sun, 3 Apr 2022 13:58:08 -0400 Received: from mail-ed1-x52c.google.com (mail-ed1-x52c.google.com [IPv6:2a00:1450:4864:20::52c]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 3A6D0387BF for ; Sun, 3 Apr 2022 10:56:01 -0700 (PDT) Received: by mail-ed1-x52c.google.com with SMTP id q26so912869edc.7 for ; Sun, 03 Apr 2022 10:56:01 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=engleder-embedded-com.20210112.gappssmtp.com; s=20210112; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=7dp4BMuH/kevxy3gi0HNX8htCjjZHnuqhGGK7or5vJ0=; b=4KLmeYu6kd/5Xw5bDnz1/sBSctSQxxUKuuyzsK8PtagSbxupDBbno7UCdCfnwxWL/L j6XDl/6iAnX0FkPqTe8XhO/wnISZZJigxsZUXEx++Lp8MJSa0574zjYK7pIfvH1BtJkQ NhakpFrp19cb9fMeq3cQ6rGf1fN+zFtACxXkot7k6FXEBD35OuFU94xE9PKd0h+43xtn Hh3w9ymtdQzV8eXNWRhtVrU1UP1dXRn6rbjxDJA4rdfDwp8bnO0itkpr5wZ97wgvRC81 3GE8Qxf6tUdisaS1UZKMWIaron2y4dEDaOHVytwO/z/MgijepCdAo1GndhsjUoLsTm/H baiQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=7dp4BMuH/kevxy3gi0HNX8htCjjZHnuqhGGK7or5vJ0=; b=O+M0Y1jendvanHPYZtz2LrimFP9EsyqQeSNTGxsg4oDYZz+mqr8xWIMEdpPOF4wEQC ZUw4qdC5kq2e3anajW0dWonCmRc4Dco1Kc0D0cVqmlWx09RCW0yEq4LB0YzD0jOGuyss xN/FQaNKzwUdLtgEf6apTvPoVnK8mM+R8ISu8QVVvfDKc9aHsctrMimDnTwup/dRctKV RKU3QVrDsrUb10RFdVp6vqSdjqqLac/Mfacy0eYwdjz2vZ9HTSUfeEU3qt3B1iYqcA6I CniVB45xDMb+eui8tAJlqRPCrL5rUu/kDak7uwnMbCkGJymp+AM3nW4jjkjH48QVLaLL e8TQ== X-Gm-Message-State: AOAM533vEFBX/nXYfizhOG/SeqOCMHYaTPW89ubYlSrM4xAMXslxbGhZ YJB3VibabUcZoWq01Wp3BeyfIg== X-Google-Smtp-Source: ABdhPJxpf365ozrjkhxIl+5LJU8tkGJOcxqvHwg60ruunIkeLeOG9NkRcuEmnYokPBYhpvapMPi0xg== X-Received: by 2002:aa7:c88b:0:b0:41c:c3d6:ab95 with SMTP id p11-20020aa7c88b000000b0041cc3d6ab95mr2653000eds.141.1649008559856; Sun, 03 Apr 2022 10:55:59 -0700 (PDT) Received: from hornet.engleder.at ([2001:871:23a:8366:6e3b:e5ff:fe2c:34c1]) by smtp.gmail.com with ESMTPSA id q7-20020a170906540700b006d5eca5c9cfsm3451065ejo.191.2022.04.03.10.55.58 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sun, 03 Apr 2022 10:55:59 -0700 (PDT) From: Gerhard Engleder To: richardcochran@gmail.com, vinicius.gomes@intel.com, yangbo.lu@nxp.com, davem@davemloft.net, kuba@kernel.org Cc: mlichvar@redhat.com, netdev@vger.kernel.org, Gerhard Engleder Subject: [PATCH net-next v2 2/5] ptp: Request cycles for TX timestamp Date: Sun, 3 Apr 2022 19:55:41 +0200 Message-Id: <20220403175544.26556-3-gerhard@engleder-embedded.com> X-Mailer: git-send-email 2.20.1 In-Reply-To: <20220403175544.26556-1-gerhard@engleder-embedded.com> References: <20220403175544.26556-1-gerhard@engleder-embedded.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org X-Patchwork-Delegate: kuba@kernel.org The free running cycle counter of physical clocks called cycles shall be used for hardware timestamps to enable synchronisation. Introduce new flag SKBTX_HW_TSTAMP_USE_CYCLES, which signals driver to provide a TX timestamp based on cycles if cycles are supported. Signed-off-by: Gerhard Engleder --- include/linux/skbuff.h | 3 +++ net/core/skbuff.c | 2 ++ net/socket.c | 11 ++++++++++- 3 files changed, 15 insertions(+), 1 deletion(-) diff --git a/include/linux/skbuff.h b/include/linux/skbuff.h index 3a30cae8b0a5..aeb3ed4d6cf8 100644 --- a/include/linux/skbuff.h +++ b/include/linux/skbuff.h @@ -578,6 +578,9 @@ enum { /* device driver is going to provide hardware time stamp */ SKBTX_IN_PROGRESS = 1 << 2, + /* generate hardware time stamp based on cycles if supported */ + SKBTX_HW_TSTAMP_USE_CYCLES = 1 << 3, + /* generate wifi status information (where possible) */ SKBTX_WIFI_STATUS = 1 << 4, diff --git a/net/core/skbuff.c b/net/core/skbuff.c index 10bde7c6db44..c0f8f1341c3f 100644 --- a/net/core/skbuff.c +++ b/net/core/skbuff.c @@ -4847,6 +4847,8 @@ void __skb_tstamp_tx(struct sk_buff *orig_skb, skb_shinfo(skb)->tx_flags |= skb_shinfo(orig_skb)->tx_flags & SKBTX_ANY_TSTAMP; skb_shinfo(skb)->tskey = skb_shinfo(orig_skb)->tskey; + } else { + skb_shinfo(skb)->tx_flags &= ~SKBTX_HW_TSTAMP_USE_CYCLES; } if (hwtstamps) diff --git a/net/socket.c b/net/socket.c index 6887840682bb..03911a3d8b33 100644 --- a/net/socket.c +++ b/net/socket.c @@ -683,9 +683,18 @@ void __sock_tx_timestamp(__u16 tsflags, __u8 *tx_flags) { u8 flags = *tx_flags; - if (tsflags & SOF_TIMESTAMPING_TX_HARDWARE) + if (tsflags & SOF_TIMESTAMPING_TX_HARDWARE) { flags |= SKBTX_HW_TSTAMP; + /* PTP hardware clocks can provide a free running cycle counter + * as a time base for virtual clocks. Tell driver to use the + * free running cycle counter for timestamp if socket is bound + * to virtual clock. + */ + if (tsflags & SOF_TIMESTAMPING_BIND_PHC) + flags |= SKBTX_HW_TSTAMP_USE_CYCLES; + } + if (tsflags & SOF_TIMESTAMPING_TX_SOFTWARE) flags |= SKBTX_SW_TSTAMP; From patchwork Sun Apr 3 17:55:42 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Gerhard Engleder X-Patchwork-Id: 12799660 X-Patchwork-Delegate: kuba@kernel.org Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 75FDDC433EF for ; Sun, 3 Apr 2022 17:56:32 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1359721AbiDCR6W (ORCPT ); Sun, 3 Apr 2022 13:58:22 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:50396 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S241715AbiDCR6J (ORCPT ); Sun, 3 Apr 2022 13:58:09 -0400 Received: from mail-ed1-x52a.google.com (mail-ed1-x52a.google.com [IPv6:2a00:1450:4864:20::52a]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id B3D3638BC4 for ; Sun, 3 Apr 2022 10:56:02 -0700 (PDT) Received: by mail-ed1-x52a.google.com with SMTP id d10so3742206edj.0 for ; Sun, 03 Apr 2022 10:56:02 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=engleder-embedded-com.20210112.gappssmtp.com; s=20210112; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=AYIelJuZzI5kgsOLCvf5vPLp/YR6VGIWXEq3pdxcCmo=; b=eiGAHL4cZh7nWNrnEGpELYmMmttbMCdBO85UziLxP+AnO0n2Um3NBLsUsfUIk7Fbg+ WfilwyhlRx00QfjxOovRWPT9SuJnm2d1jUIXdIdVM4hL+4VujzEjcijcEN5JKAyy+xZS q18UvYXQPTXsoBH5fZkwXfVyYbSA14LQrb0yyfrQGcziZOSfZ/AvsYu246Fz64Xxt0pw cLtXvVwhnHnIk8EFmrfCDaiCnMW5rOngRBOMX8+M+R6xGKwab1aBxk/75poZPqXYQ1Hl sAf/KG0KGYkg6twXIa2Ol1KiGIhfY5ONkfrWTi5Ujt9jN2MmwxBF/aJ7Lc50/egYl26M vhqw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=AYIelJuZzI5kgsOLCvf5vPLp/YR6VGIWXEq3pdxcCmo=; b=TNxzWjQrdV114HN4HsPWVFU972utH+gZv4zIeAOsTIceoljoxo4YRhQjRj1Fpq0NWb XI6Jx8mB268tRwAEq3iwe8CCGQ8cYv/Nihc1sM6GFNknnRQ4lbfatDaCJOfwWeTis77N uuTYB0Gy3vj810kJrUSc5AI0YBEfxYt6+NRlZIsWd851m0Kq9gIj9PifaCrEiJo/Zwpd BhF0S0QX5ft8Wy9+krIxcEV34Wg1aLxCz8JiCQpAw9X03r9np+PlfzjouwaXPRZ3lq7o agNGyqjmBfrkjswln5MsaV+Rx48iC42P5Smvd9+wRfpESJ5QlrFZ7DJQLi0hGpLyTSDw QYLQ== X-Gm-Message-State: AOAM531mzHW3mJ7fWea7w3etlj1O435tX3aAlbX8swPxzqhU7eXhSLaQ wTFUwsAIurm7j5EB8WEXuPwblnwyKD19ltU9 X-Google-Smtp-Source: ABdhPJx9wUDITPu0YPuN/2OhgBUELZKYtLa0jx08a1vHjVQE/iZa1EDVYbW7TGdvilBOWPsBflczOg== X-Received: by 2002:a05:6402:50cf:b0:418:ee57:ed9 with SMTP id h15-20020a05640250cf00b00418ee570ed9mr29457360edb.37.1649008561275; Sun, 03 Apr 2022 10:56:01 -0700 (PDT) Received: from hornet.engleder.at ([2001:871:23a:8366:6e3b:e5ff:fe2c:34c1]) by smtp.gmail.com with ESMTPSA id q7-20020a170906540700b006d5eca5c9cfsm3451065ejo.191.2022.04.03.10.56.00 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sun, 03 Apr 2022 10:56:00 -0700 (PDT) From: Gerhard Engleder To: richardcochran@gmail.com, vinicius.gomes@intel.com, yangbo.lu@nxp.com, davem@davemloft.net, kuba@kernel.org Cc: mlichvar@redhat.com, netdev@vger.kernel.org, Gerhard Engleder Subject: [PATCH net-next v2 3/5] ptp: Pass hwtstamp to ptp_convert_timestamp() Date: Sun, 3 Apr 2022 19:55:42 +0200 Message-Id: <20220403175544.26556-4-gerhard@engleder-embedded.com> X-Mailer: git-send-email 2.20.1 In-Reply-To: <20220403175544.26556-1-gerhard@engleder-embedded.com> References: <20220403175544.26556-1-gerhard@engleder-embedded.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org X-Patchwork-Delegate: kuba@kernel.org ptp_convert_timestamp() converts only the timestamp hwtstamp, which is a field of the argument with the type struct skb_shared_hwtstamps *. So a pointer to the hwtstamp field of this structure is sufficient. Rework ptp_convert_timestamp() to use an argument of type ktime_t *. This allows to add additional timestamp manipulation stages before the call of ptp_convert_timestamp(). Signed-off-by: Gerhard Engleder Acked-by: Richard Cochran --- drivers/ptp/ptp_vclock.c | 5 ++--- include/linux/ptp_clock_kernel.h | 7 +++---- net/socket.c | 2 +- 3 files changed, 6 insertions(+), 8 deletions(-) diff --git a/drivers/ptp/ptp_vclock.c b/drivers/ptp/ptp_vclock.c index 3a095eab9cc5..c30bcce2bb43 100644 --- a/drivers/ptp/ptp_vclock.c +++ b/drivers/ptp/ptp_vclock.c @@ -232,8 +232,7 @@ int ptp_get_vclocks_index(int pclock_index, int **vclock_index) } EXPORT_SYMBOL(ptp_get_vclocks_index); -ktime_t ptp_convert_timestamp(const struct skb_shared_hwtstamps *hwtstamps, - int vclock_index) +ktime_t ptp_convert_timestamp(const ktime_t *hwtstamp, int vclock_index) { char name[PTP_CLOCK_NAME_LEN] = ""; struct ptp_vclock *vclock; @@ -255,7 +254,7 @@ ktime_t ptp_convert_timestamp(const struct skb_shared_hwtstamps *hwtstamps, vclock = info_to_vclock(ptp->info); - ns = ktime_to_ns(hwtstamps->hwtstamp); + ns = ktime_to_ns(*hwtstamp); spin_lock_irqsave(&vclock->lock, flags); ns = timecounter_cyc2time(&vclock->tc, ns); diff --git a/include/linux/ptp_clock_kernel.h b/include/linux/ptp_clock_kernel.h index 3ea7110a9d70..ed6e15ead466 100644 --- a/include/linux/ptp_clock_kernel.h +++ b/include/linux/ptp_clock_kernel.h @@ -380,17 +380,16 @@ int ptp_get_vclocks_index(int pclock_index, int **vclock_index); /** * ptp_convert_timestamp() - convert timestamp to a ptp vclock time * - * @hwtstamps: skb_shared_hwtstamps structure pointer + * @hwtstamp: timestamp * @vclock_index: phc index of ptp vclock. * * Returns converted timestamp, or 0 on error. */ -ktime_t ptp_convert_timestamp(const struct skb_shared_hwtstamps *hwtstamps, - int vclock_index); +ktime_t ptp_convert_timestamp(const ktime_t *hwtstamp, int vclock_index); #else static inline int ptp_get_vclocks_index(int pclock_index, int **vclock_index) { return 0; } -static inline ktime_t ptp_convert_timestamp(const struct skb_shared_hwtstamps *hwtstamps, +static inline ktime_t ptp_convert_timestamp(const ktime_t *hwtstamp, int vclock_index) { return 0; } diff --git a/net/socket.c b/net/socket.c index 03911a3d8b33..4801aeaeb285 100644 --- a/net/socket.c +++ b/net/socket.c @@ -888,7 +888,7 @@ void __sock_recv_timestamp(struct msghdr *msg, struct sock *sk, (sk->sk_tsflags & SOF_TIMESTAMPING_RAW_HARDWARE) && !skb_is_swtx_tstamp(skb, false_tstamp)) { if (sk->sk_tsflags & SOF_TIMESTAMPING_BIND_PHC) - hwtstamp = ptp_convert_timestamp(shhwtstamps, + hwtstamp = ptp_convert_timestamp(&shhwtstamps->hwtstamp, sk->sk_bind_phc); else hwtstamp = shhwtstamps->hwtstamp; From patchwork Sun Apr 3 17:55:43 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Gerhard Engleder X-Patchwork-Id: 12799658 X-Patchwork-Delegate: kuba@kernel.org Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id E919DC433F5 for ; Sun, 3 Apr 2022 17:56:28 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1359716AbiDCR6U (ORCPT ); Sun, 3 Apr 2022 13:58:20 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:50408 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S240320AbiDCR6I (ORCPT ); Sun, 3 Apr 2022 13:58:08 -0400 Received: from mail-ej1-x62f.google.com (mail-ej1-x62f.google.com [IPv6:2a00:1450:4864:20::62f]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 70D6738BC5 for ; Sun, 3 Apr 2022 10:56:04 -0700 (PDT) Received: by mail-ej1-x62f.google.com with SMTP id i27so8478254ejd.9 for ; Sun, 03 Apr 2022 10:56:04 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=engleder-embedded-com.20210112.gappssmtp.com; s=20210112; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=f6a2ZXW2K0vychsyQbNsHz4PD6ItrRcaItNAke+6Q0s=; b=44QPGzoRNmscCxgXfqNl7pINOwqdFty3vVdYHry4mP6KJwfpU18SXUWpXtNdgOPSDm W9bmOfNtJi5qbzgClfNeeDMGURpY353UHUHvl6pixfZ/ajYZPJSKEVudBMPcQws/3eWl K//1OdLLksCeKBbjEk2D4s6tjgY/oOOlA8276EvryOQunnR8FbB+9RQRqWvLvdnWbAxV NJuRKlMfuN4aPC2Dglutwcac2LTjTylxRvTDKOOC43Yvi+nITN3w4mgbLIyFxtIcp1Bs 2i9Mv8kLmKZ/ZmCTSIPPnV3XCSKv72dveKIkkpx3y4oenqM0vHexSsb1lPvCiefTq25Q nRWQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=f6a2ZXW2K0vychsyQbNsHz4PD6ItrRcaItNAke+6Q0s=; b=dhpHmeR7nSlO3WOhHhMwRWJ/m43fxqT0jhjRaTcg6AUg1eFbbO7N/Y5i2CHFn7E7w9 HpJ42ob02af1OTce7kh3OkG121xave4WTqQdM2NNGBr4bvVeBhqTBq2rUuh2yb4AOTLU 0wuUc32KEg7rXFpkJPzU0MUPsuzQc6Ff15RV84ywL2qsjJsCBA/cIVIIejyOKIAAcstn HM9aeQPKPyi+E3NaTClkPe2HQd03vDN7h/Y9FXd/aWc/tI8EG5pi3oZtKj/QL+PauWXz uKpIZA2yT4Id7o1Vmz1ersntxyHofjiFRBS6H6fkFRy/1B3x9SN6xt4LPHB1iNH7wbNf RK2Q== X-Gm-Message-State: AOAM531nPOdwfL5gGprHBoLDT94dGnGuisEE8Y8s2Sv6STL7C+FEYqec lk2a5rh+UCRkvL0xXte/riuWrw== X-Google-Smtp-Source: ABdhPJyQQlYjw9vaDZIDDbR2TuYP3xINBC649e3a4aHK+Kn5bP8Mjbqz9FIyHCC2/rl2sWTkcZprYw== X-Received: by 2002:a17:907:8d1a:b0:6e0:6db8:8042 with SMTP id tc26-20020a1709078d1a00b006e06db88042mr7851903ejc.300.1649008562958; Sun, 03 Apr 2022 10:56:02 -0700 (PDT) Received: from hornet.engleder.at ([2001:871:23a:8366:6e3b:e5ff:fe2c:34c1]) by smtp.gmail.com with ESMTPSA id q7-20020a170906540700b006d5eca5c9cfsm3451065ejo.191.2022.04.03.10.56.02 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sun, 03 Apr 2022 10:56:02 -0700 (PDT) From: Gerhard Engleder To: richardcochran@gmail.com, vinicius.gomes@intel.com, yangbo.lu@nxp.com, davem@davemloft.net, kuba@kernel.org Cc: mlichvar@redhat.com, netdev@vger.kernel.org, Gerhard Engleder Subject: [PATCH net-next v2 4/5] ptp: Support late timestamp determination Date: Sun, 3 Apr 2022 19:55:43 +0200 Message-Id: <20220403175544.26556-5-gerhard@engleder-embedded.com> X-Mailer: git-send-email 2.20.1 In-Reply-To: <20220403175544.26556-1-gerhard@engleder-embedded.com> References: <20220403175544.26556-1-gerhard@engleder-embedded.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org X-Patchwork-Delegate: kuba@kernel.org If a physical clock supports a free running cycle counter, then timestamps shall be based on this time too. For TX it is known in advance before the transmission if a timestamp based on the free running cycle counter is needed. For RX it is impossible to know which timestamp is needed before the packet is received and assigned to a socket. Support late timestamp determination by a network device. Therefore, an address/cookie is stored within the new netdev_data field of struct skb_shared_hwtstamps. This address/cookie is provided to a new network device function called ndo_get_tstamp(), which returns a timestamp based on the normal/adjustable time or based on the free running cycle counter. If function is not supported, then timestamp handling is not changed. Signed-off-by: Gerhard Engleder --- include/linux/netdevice.h | 21 +++++++++++++++++++++ include/linux/skbuff.h | 11 ++++++++--- net/socket.c | 30 +++++++++++++++++++----------- 3 files changed, 48 insertions(+), 14 deletions(-) diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h index 59e27a2b7bf0..f6cc4c673082 100644 --- a/include/linux/netdevice.h +++ b/include/linux/netdevice.h @@ -1353,6 +1353,12 @@ struct netdev_net_notifier { * The caller must be under RCU read context. * int (*ndo_fill_forward_path)(struct net_device_path_ctx *ctx, struct net_device_path *path); * Get the forwarding path to reach the real device from the HW destination address + * ktime_t (*ndo_get_tstamp)(struct net_device *dev, + * const struct skb_shared_hwtstamps *hwtstamps, + * bool cycles); + * Get hardware timestamp based on normal/adjustable time or free running + * cycle counter. This function is required if physical clock supports a + * free running cycle counter. */ struct net_device_ops { int (*ndo_init)(struct net_device *dev); @@ -1570,6 +1576,9 @@ struct net_device_ops { struct net_device * (*ndo_get_peer_dev)(struct net_device *dev); int (*ndo_fill_forward_path)(struct net_device_path_ctx *ctx, struct net_device_path *path); + ktime_t (*ndo_get_tstamp)(struct net_device *dev, + const struct skb_shared_hwtstamps *hwtstamps, + bool cycles); }; /** @@ -4764,6 +4773,18 @@ static inline void netdev_rx_csum_fault(struct net_device *dev, void net_enable_timestamp(void); void net_disable_timestamp(void); +static inline ktime_t netdev_get_tstamp(struct net_device *dev, + const struct skb_shared_hwtstamps *hwtstamps, + bool cycles) +{ + const struct net_device_ops *ops = dev->netdev_ops; + + if (ops->ndo_get_tstamp) + return ops->ndo_get_tstamp(dev, hwtstamps, cycles); + + return hwtstamps->hwtstamp; +} + #ifdef CONFIG_PROC_FS int __init dev_proc_init(void); #else diff --git a/include/linux/skbuff.h b/include/linux/skbuff.h index aeb3ed4d6cf8..c428b678e7f1 100644 --- a/include/linux/skbuff.h +++ b/include/linux/skbuff.h @@ -551,8 +551,10 @@ static inline bool skb_frag_must_loop(struct page *p) /** * struct skb_shared_hwtstamps - hardware time stamps - * @hwtstamp: hardware time stamp transformed into duration - * since arbitrary point in time + * @hwtstamp: hardware time stamp transformed into duration + * since arbitrary point in time + * @netdev_data: address/cookie of network device driver used as + * reference to actual hardware time stamp * * Software time stamps generated by ktime_get_real() are stored in * skb->tstamp. @@ -564,7 +566,10 @@ static inline bool skb_frag_must_loop(struct page *p) * &skb_shared_info. Use skb_hwtstamps() to get a pointer. */ struct skb_shared_hwtstamps { - ktime_t hwtstamp; + union { + ktime_t hwtstamp; + void *netdev_data; + }; }; /* Definitions for tx_flags in struct skb_shared_info */ diff --git a/net/socket.c b/net/socket.c index 4801aeaeb285..d64bd3dfcf6a 100644 --- a/net/socket.c +++ b/net/socket.c @@ -805,21 +805,17 @@ static bool skb_is_swtx_tstamp(const struct sk_buff *skb, int false_tstamp) return skb->tstamp && !false_tstamp && skb_is_err_queue(skb); } -static void put_ts_pktinfo(struct msghdr *msg, struct sk_buff *skb) +static void put_ts_pktinfo(struct msghdr *msg, struct sk_buff *skb, + int if_index) { struct scm_ts_pktinfo ts_pktinfo; - struct net_device *orig_dev; if (!skb_mac_header_was_set(skb)) return; memset(&ts_pktinfo, 0, sizeof(ts_pktinfo)); - rcu_read_lock(); - orig_dev = dev_get_by_napi_id(skb_napi_id(skb)); - if (orig_dev) - ts_pktinfo.if_index = orig_dev->ifindex; - rcu_read_unlock(); + ts_pktinfo.if_index = if_index; ts_pktinfo.pkt_length = skb->len - skb_mac_offset(skb); put_cmsg(msg, SOL_SOCKET, SCM_TIMESTAMPING_PKTINFO, @@ -839,6 +835,8 @@ void __sock_recv_timestamp(struct msghdr *msg, struct sock *sk, int empty = 1, false_tstamp = 0; struct skb_shared_hwtstamps *shhwtstamps = skb_hwtstamps(skb); + struct net_device *orig_dev; + int if_index; ktime_t hwtstamp; /* Race occurred between timestamp enabling and packet @@ -887,18 +885,28 @@ void __sock_recv_timestamp(struct msghdr *msg, struct sock *sk, if (shhwtstamps && (sk->sk_tsflags & SOF_TIMESTAMPING_RAW_HARDWARE) && !skb_is_swtx_tstamp(skb, false_tstamp)) { + rcu_read_lock(); + orig_dev = dev_get_by_napi_id(skb_napi_id(skb)); + if (orig_dev) { + if_index = orig_dev->ifindex; + hwtstamp = netdev_get_tstamp(orig_dev, shhwtstamps, + sk->sk_tsflags & SOF_TIMESTAMPING_BIND_PHC); + } else { + if_index = 0; + hwtstamp = shhwtstamps->hwtstamp; + } + rcu_read_unlock(); + if (sk->sk_tsflags & SOF_TIMESTAMPING_BIND_PHC) - hwtstamp = ptp_convert_timestamp(&shhwtstamps->hwtstamp, + hwtstamp = ptp_convert_timestamp(&hwtstamp, sk->sk_bind_phc); - else - hwtstamp = shhwtstamps->hwtstamp; if (ktime_to_timespec64_cond(hwtstamp, tss.ts + 2)) { empty = 0; if ((sk->sk_tsflags & SOF_TIMESTAMPING_OPT_PKTINFO) && !skb_is_err_queue(skb)) - put_ts_pktinfo(msg, skb); + put_ts_pktinfo(msg, skb, if_index); } } if (!empty) { From patchwork Sun Apr 3 17:55:44 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Gerhard Engleder X-Patchwork-Id: 12799661 X-Patchwork-Delegate: kuba@kernel.org Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 87426C433FE for ; Sun, 3 Apr 2022 17:56:33 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1359712AbiDCR6Z (ORCPT ); Sun, 3 Apr 2022 13:58:25 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:50450 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1359713AbiDCR6K (ORCPT ); Sun, 3 Apr 2022 13:58:10 -0400 Received: from mail-ed1-x534.google.com (mail-ed1-x534.google.com [IPv6:2a00:1450:4864:20::534]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 5AB4538BC6 for ; Sun, 3 Apr 2022 10:56:06 -0700 (PDT) Received: by mail-ed1-x534.google.com with SMTP id g22so8567198edz.2 for ; Sun, 03 Apr 2022 10:56:06 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=engleder-embedded-com.20210112.gappssmtp.com; s=20210112; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=eN7Ia++fbxzWlp4pgjd3rWcUOX9NDzR4XKxfj+Wa6tY=; b=isXATMaeK5nEQY5xj7oMzfLSDfsdojBedTtUnZUl703kIzeEsDATv6shfZNseqfECB DHgMiRRntHAT0L1TDXzLD3RtObm2X8KYapxVwUuhsrbAiO2JNccW+OA0krnTuB9wzTR1 Wb0YaI8SzGF4d+m3WGUe9D19mfP6yeY+kt0QhlZj/s2QhIos3UBN+CdSvwAIlu004DBv PXkiQPyGT3R7NEymrEerskcmwmWWd1ChrXOdzq5WQwd0WJxAIujrDIfSJCplElVxS2DK 3LWeEA8qmqK0O7asglSRJ9uRRSGiyfChTwnPMAV0ZS3ko8HfAusEglY8efz7OWFdWgg4 FaIw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=eN7Ia++fbxzWlp4pgjd3rWcUOX9NDzR4XKxfj+Wa6tY=; b=XuLp7u/1IlizRA79xtPyQbN7EWNAP/GjCxjrhp7S8wuepznDKL3tcDv2Ri1/VpWj7K Aemngbm2Zf0zhoyfTo8z+lnhzESMGbyrNQNcfNp4tE7HFnaXrb1OSENVhEvwDu/dyfvC ykXkESxw385nYbxFWt+qkSvr6v4e6ccUsNMkK9NV8L9jQ77r38QwacA/8bcREoODg3yy 1KqQQHW47bOpjWp9DfZgSNnO0hdklgSM6fkRiv95LDnRffUVmxq6C0j/8WEgDt4ioUm4 ar3kKz72VHNMDoqegCue0c4eu6Zc3xQCDUaCvKe+EcXY7zMoJ2X96tUquR9vYVhYIhIU 1GrA== X-Gm-Message-State: AOAM531fMgDxQR+cH+nI5gkr6Z1xVy/Wha6MyXFUjfmIZmf+jC74hH6Z 83/zygnsGKy0TRiTE4XM0c5iyQ== X-Google-Smtp-Source: ABdhPJzX1Lns0EMXhZUmlIiQXchC+21Jbhchegh6IKqSi2jf7Q1QNLK9zVlzvk+W5x9JUds2kfjgSQ== X-Received: by 2002:aa7:cb96:0:b0:413:8d05:ebc with SMTP id r22-20020aa7cb96000000b004138d050ebcmr29504888edt.81.1649008564945; Sun, 03 Apr 2022 10:56:04 -0700 (PDT) Received: from hornet.engleder.at ([2001:871:23a:8366:6e3b:e5ff:fe2c:34c1]) by smtp.gmail.com with ESMTPSA id q7-20020a170906540700b006d5eca5c9cfsm3451065ejo.191.2022.04.03.10.56.04 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sun, 03 Apr 2022 10:56:04 -0700 (PDT) From: Gerhard Engleder To: richardcochran@gmail.com, vinicius.gomes@intel.com, yangbo.lu@nxp.com, davem@davemloft.net, kuba@kernel.org Cc: mlichvar@redhat.com, netdev@vger.kernel.org, Gerhard Engleder Subject: [PATCH net-next v2 5/5] tsnep: Add free running cycle counter support Date: Sun, 3 Apr 2022 19:55:44 +0200 Message-Id: <20220403175544.26556-6-gerhard@engleder-embedded.com> X-Mailer: git-send-email 2.20.1 In-Reply-To: <20220403175544.26556-1-gerhard@engleder-embedded.com> References: <20220403175544.26556-1-gerhard@engleder-embedded.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org X-Patchwork-Delegate: kuba@kernel.org The TSN endpoint Ethernet MAC supports a free running counter additionally to its clock. This free running counter can be read and hardware timestamps are supported. As the name implies, this counter cannot be set and its frequency cannot be adjusted. Add free running cycle counter support based on this free running counter to physical clock. This also requires hardware time stamps based on that free running counter. Signed-off-by: Gerhard Engleder --- drivers/net/ethernet/engleder/tsnep_hw.h | 9 +++++-- drivers/net/ethernet/engleder/tsnep_main.c | 31 ++++++++++++++++++---- drivers/net/ethernet/engleder/tsnep_ptp.c | 28 +++++++++++++++++++ 3 files changed, 61 insertions(+), 7 deletions(-) diff --git a/drivers/net/ethernet/engleder/tsnep_hw.h b/drivers/net/ethernet/engleder/tsnep_hw.h index 71cc8577d640..916ceac3ada2 100644 --- a/drivers/net/ethernet/engleder/tsnep_hw.h +++ b/drivers/net/ethernet/engleder/tsnep_hw.h @@ -43,6 +43,10 @@ #define ECM_RESET_CHANNEL 0x00000100 #define ECM_RESET_TXRX 0x00010000 +/* counter */ +#define ECM_COUNTER_LOW 0x0028 +#define ECM_COUNTER_HIGH 0x002C + /* control and status */ #define ECM_STATUS 0x0080 #define ECM_LINK_MODE_OFF 0x01000000 @@ -190,7 +194,8 @@ struct tsnep_tx_desc { /* tsnep TX descriptor writeback */ struct tsnep_tx_desc_wb { __le32 properties; - __le32 reserved1[3]; + __le32 reserved1; + __le64 counter; __le64 timestamp; __le32 dma_delay; __le32 reserved2; @@ -221,7 +226,7 @@ struct tsnep_rx_desc_wb { /* tsnep RX inline meta */ struct tsnep_rx_inline { - __le64 reserved; + __le64 counter; __le64 timestamp; }; diff --git a/drivers/net/ethernet/engleder/tsnep_main.c b/drivers/net/ethernet/engleder/tsnep_main.c index 904f3304727e..c97651903892 100644 --- a/drivers/net/ethernet/engleder/tsnep_main.c +++ b/drivers/net/ethernet/engleder/tsnep_main.c @@ -470,8 +470,15 @@ static bool tsnep_tx_poll(struct tsnep_tx *tx, int napi_budget) (__le32_to_cpu(entry->desc_wb->properties) & TSNEP_DESC_EXTENDED_WRITEBACK_FLAG)) { struct skb_shared_hwtstamps hwtstamps; - u64 timestamp = - __le64_to_cpu(entry->desc_wb->timestamp); + u64 timestamp; + + if (skb_shinfo(entry->skb)->tx_flags & + SKBTX_HW_TSTAMP_USE_CYCLES) + timestamp = + __le64_to_cpu(entry->desc_wb->counter); + else + timestamp = + __le64_to_cpu(entry->desc_wb->timestamp); memset(&hwtstamps, 0, sizeof(hwtstamps)); hwtstamps.hwtstamp = ns_to_ktime(timestamp); @@ -704,11 +711,9 @@ static int tsnep_rx_poll(struct tsnep_rx *rx, struct napi_struct *napi, skb_hwtstamps(skb); struct tsnep_rx_inline *rx_inline = (struct tsnep_rx_inline *)skb->data; - u64 timestamp = - __le64_to_cpu(rx_inline->timestamp); memset(hwtstamps, 0, sizeof(*hwtstamps)); - hwtstamps->hwtstamp = ns_to_ktime(timestamp); + hwtstamps->netdev_data = rx_inline; } skb_pull(skb, TSNEP_RX_INLINE_METADATA_SIZE); skb->protocol = eth_type_trans(skb, @@ -1010,6 +1015,21 @@ static int tsnep_netdev_set_mac_address(struct net_device *netdev, void *addr) return 0; } +static ktime_t tsnep_netdev_get_tstamp(struct net_device *netdev, + const struct skb_shared_hwtstamps *hwtstamps, + bool cycles) +{ + struct tsnep_rx_inline *rx_inline = hwtstamps->netdev_data; + u64 timestamp; + + if (cycles) + timestamp = __le64_to_cpu(rx_inline->counter); + else + timestamp = __le64_to_cpu(rx_inline->timestamp); + + return ns_to_ktime(timestamp); +} + static const struct net_device_ops tsnep_netdev_ops = { .ndo_open = tsnep_netdev_open, .ndo_stop = tsnep_netdev_close, @@ -1019,6 +1039,7 @@ static const struct net_device_ops tsnep_netdev_ops = { .ndo_get_stats64 = tsnep_netdev_get_stats64, .ndo_set_mac_address = tsnep_netdev_set_mac_address, + .ndo_get_tstamp = tsnep_netdev_get_tstamp, .ndo_setup_tc = tsnep_tc_setup, }; diff --git a/drivers/net/ethernet/engleder/tsnep_ptp.c b/drivers/net/ethernet/engleder/tsnep_ptp.c index eaad453d487e..54fbf0126815 100644 --- a/drivers/net/ethernet/engleder/tsnep_ptp.c +++ b/drivers/net/ethernet/engleder/tsnep_ptp.c @@ -175,6 +175,33 @@ static int tsnep_ptp_settime64(struct ptp_clock_info *ptp, return 0; } +static int tsnep_ptp_getcyclesx64(struct ptp_clock_info *ptp, + struct timespec64 *ts, + struct ptp_system_timestamp *sts) +{ + struct tsnep_adapter *adapter = container_of(ptp, struct tsnep_adapter, + ptp_clock_info); + u32 high_before; + u32 low; + u32 high; + u64 counter; + + /* read high dword twice to detect overrun */ + high = ioread32(adapter->addr + ECM_COUNTER_HIGH); + do { + ptp_read_system_prets(sts); + low = ioread32(adapter->addr + ECM_COUNTER_LOW); + ptp_read_system_postts(sts); + high_before = high; + high = ioread32(adapter->addr + ECM_COUNTER_HIGH); + } while (high != high_before); + counter = (((u64)high) << 32) | ((u64)low); + + *ts = ns_to_timespec64(counter); + + return 0; +} + int tsnep_ptp_init(struct tsnep_adapter *adapter) { int retval = 0; @@ -192,6 +219,7 @@ int tsnep_ptp_init(struct tsnep_adapter *adapter) adapter->ptp_clock_info.adjtime = tsnep_ptp_adjtime; adapter->ptp_clock_info.gettimex64 = tsnep_ptp_gettimex64; adapter->ptp_clock_info.settime64 = tsnep_ptp_settime64; + adapter->ptp_clock_info.getcyclesx64 = tsnep_ptp_getcyclesx64; spin_lock_init(&adapter->ptp_lock);