From patchwork Fri May 7 08:57:51 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Yangbo Lu X-Patchwork-Id: 12244129 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 X-Spam-Level: X-Spam-Status: No, score=-16.8 required=3.0 tests=BAYES_00, HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER,INCLUDES_PATCH, MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS,URIBL_BLOCKED,USER_AGENT_GIT autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id B7031C433B4 for ; Fri, 7 May 2021 08:47:52 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 5FC9A613D9 for ; Fri, 7 May 2021 08:47:52 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S236438AbhEGIsv (ORCPT ); Fri, 7 May 2021 04:48:51 -0400 Received: from inva020.nxp.com ([92.121.34.13]:59670 "EHLO inva020.nxp.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S236422AbhEGIsq (ORCPT ); Fri, 7 May 2021 04:48:46 -0400 Received: from inva020.nxp.com (localhost [127.0.0.1]) by inva020.eu-rdc02.nxp.com (Postfix) with ESMTP id 484B81A19CC; Fri, 7 May 2021 10:47:46 +0200 (CEST) Received: from invc005.ap-rdc01.nxp.com (invc005.ap-rdc01.nxp.com [165.114.16.14]) by inva020.eu-rdc02.nxp.com (Postfix) with ESMTP id 2B3AE1A19C3; Fri, 7 May 2021 10:47:43 +0200 (CEST) Received: from localhost.localdomain (mega.ap.freescale.net [10.192.208.232]) by invc005.ap-rdc01.nxp.com (Postfix) with ESMTP id 53074402CF; Fri, 7 May 2021 10:47:39 +0200 (CEST) From: Yangbo Lu To: netdev@vger.kernel.org Cc: Yangbo Lu , "David S . Miller" , Richard Cochran , Claudiu Manoil , Jakub Kicinski Subject: [net-next 1/6] ptp: add ptp virtual clock driver framework Date: Fri, 7 May 2021 16:57:51 +0800 Message-Id: <20210507085756.20427-2-yangbo.lu@nxp.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20210507085756.20427-1-yangbo.lu@nxp.com> References: <20210507085756.20427-1-yangbo.lu@nxp.com> X-Virus-Scanned: ClamAV using ClamSMTP Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org X-Patchwork-Delegate: kuba@kernel.org This patch is to add ptp virtual clock driver framework. The main purpose is to support PTP multiple domains over multiple PTP virtual clocks with only single physical clock. What has the patch exported, - ptp_vclock_cc structure for specifying cyclecounter information that ptp virtual clocks will use. When registering ptp clock for physical clock, the ptp virtual clock will be valid to register if the pointer of ptp_vclock_cc structure is provided in ptp_clock_info of physical clock. - ptp_vclock_register/ptp_vclock_unregister APIs for ptp virtual clock register/unregister for specified domain number. They are private for ptp driver. - ptp_clock_domain_tstamp API to convert hardware time stamp to domain time stamp. - ptp_get_pclock_info API for device driver to get ptp_clock_info pointer of physical clock from cyclecounter pointer of ptp virtual clock. Signed-off-by: Yangbo Lu Reported-by: kernel test robot Reported-by: kernel test robot --- MAINTAINERS | 6 ++ drivers/ptp/Makefile | 2 +- drivers/ptp/ptp_private.h | 25 +++++ drivers/ptp/ptp_vclock.c | 176 +++++++++++++++++++++++++++++++ include/linux/ptp_clock_kernel.h | 51 +++++++++ 5 files changed, 259 insertions(+), 1 deletion(-) create mode 100644 drivers/ptp/ptp_vclock.c diff --git a/MAINTAINERS b/MAINTAINERS index 4796ccf9f871..9f9280b29e47 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -14733,6 +14733,12 @@ F: drivers/net/phy/dp83640* F: drivers/ptp/* F: include/linux/ptp_cl* +PTP VIRTUAL CLOCK SUPPORT +M: Yangbo Lu +L: netdev@vger.kernel.org +S: Maintained +F: drivers/ptp/ptp_vclock.c + PTRACE SUPPORT M: Oleg Nesterov S: Maintained diff --git a/drivers/ptp/Makefile b/drivers/ptp/Makefile index db5aef3bddc6..3c75d7de7793 100644 --- a/drivers/ptp/Makefile +++ b/drivers/ptp/Makefile @@ -3,7 +3,7 @@ # Makefile for PTP 1588 clock support. # -ptp-y := ptp_clock.o ptp_chardev.o ptp_sysfs.o +ptp-y := ptp_clock.o ptp_chardev.o ptp_sysfs.o ptp_vclock.o obj-$(CONFIG_PTP_1588_CLOCK) += ptp.o obj-$(CONFIG_PTP_1588_CLOCK_DTE) += ptp_dte.o obj-$(CONFIG_PTP_1588_CLOCK_INES) += ptp_ines.o diff --git a/drivers/ptp/ptp_private.h b/drivers/ptp/ptp_private.h index 6b97155148f1..9ff0afc57a7f 100644 --- a/drivers/ptp/ptp_private.h +++ b/drivers/ptp/ptp_private.h @@ -48,6 +48,29 @@ struct ptp_clock { struct kthread_delayed_work aux_work; }; +#define cc_to_vclock(d) container_of((d), struct ptp_vclock, cc) +#define dw_to_vclock(d) container_of((d), struct ptp_vclock, refresh_work) +#define info_to_vclock(d) container_of((d), struct ptp_vclock, info) + +struct ptp_vclock { + struct ptp_clock *pclock; + struct ptp_clock_info info; + struct ptp_clock *clock; + struct cyclecounter cc; + struct timecounter tc; + spinlock_t lock; /* protects tc/cc */ + struct delayed_work refresh_work; + unsigned long refresh_interval; + u32 mult; + u32 mult_num; + u32 mult_dem; +}; + +struct domain_tstamp { + u64 tstamp; + u8 domain; +}; + /* * The function queue_cnt() is safe for readers to call without * holding q->lock. Readers use this function to verify that the queue @@ -89,4 +112,6 @@ extern const struct attribute_group *ptp_groups[]; int ptp_populate_pin_groups(struct ptp_clock *ptp); void ptp_cleanup_pin_groups(struct ptp_clock *ptp); +struct ptp_vclock *ptp_vclock_register(struct ptp_clock *pclock, u8 domain); +void ptp_vclock_unregister(struct ptp_vclock *vclock); #endif diff --git a/drivers/ptp/ptp_vclock.c b/drivers/ptp/ptp_vclock.c new file mode 100644 index 000000000000..765acc0f7576 --- /dev/null +++ b/drivers/ptp/ptp_vclock.c @@ -0,0 +1,176 @@ +// SPDX-License-Identifier: GPL-2.0-or-later +/* + * PTP virtual clock driver + * + * Copyright 2021 NXP + */ +#include +#include "ptp_private.h" + +static int ptp_vclock_adjfine(struct ptp_clock_info *ptp, long scaled_ppm) +{ + struct ptp_vclock *vclock = info_to_vclock(ptp); + unsigned long flags; + s64 mult_adj; + + mult_adj = (s64)scaled_ppm * vclock->mult_num; + mult_adj = div_s64(mult_adj, vclock->mult_dem); + + spin_lock_irqsave(&vclock->lock, flags); + timecounter_read(&vclock->tc); + vclock->cc.mult = vclock->mult + mult_adj; + spin_unlock_irqrestore(&vclock->lock, flags); + + return 0; +} + +static int ptp_vclock_adjtime(struct ptp_clock_info *ptp, s64 delta) +{ + struct ptp_vclock *vclock = info_to_vclock(ptp); + unsigned long flags; + + spin_lock_irqsave(&vclock->lock, flags); + timecounter_adjtime(&vclock->tc, delta); + spin_unlock_irqrestore(&vclock->lock, flags); + + return 0; +} + +static int ptp_vclock_gettime(struct ptp_clock_info *ptp, + struct timespec64 *ts) +{ + struct ptp_vclock *vclock = info_to_vclock(ptp); + unsigned long flags; + u64 ns; + + spin_lock_irqsave(&vclock->lock, flags); + ns = timecounter_read(&vclock->tc); + spin_unlock_irqrestore(&vclock->lock, flags); + *ts = ns_to_timespec64(ns); + + return 0; +} + +static int ptp_vclock_settime(struct ptp_clock_info *ptp, + const struct timespec64 *ts) +{ + struct ptp_vclock *vclock = info_to_vclock(ptp); + u64 ns = timespec64_to_ns(ts); + unsigned long flags; + + spin_lock_irqsave(&vclock->lock, flags); + timecounter_init(&vclock->tc, &vclock->cc, ns); + spin_unlock_irqrestore(&vclock->lock, flags); + + return 0; +} + +static const struct ptp_clock_info ptp_vclock_info = { + .owner = THIS_MODULE, + .name = "ptp vclock", + .adjfine = ptp_vclock_adjfine, + .adjtime = ptp_vclock_adjtime, + .gettime64 = ptp_vclock_gettime, + .settime64 = ptp_vclock_settime, + .max_adj = 32000000, +}; + +static void ptp_vclock_refresh(struct work_struct *work) +{ + struct delayed_work *dw = to_delayed_work(work); + struct ptp_vclock *vclock = dw_to_vclock(dw); + struct timespec64 ts; + + ptp_vclock_gettime(&vclock->info, &ts); + schedule_delayed_work(&vclock->refresh_work, vclock->refresh_interval); +} + +static int ptp_clock_find_domain_tstamp(struct device *dev, void *data) +{ + struct ptp_clock *ptp = dev_get_drvdata(dev); + struct ptp_clock_info *info = ptp->info; + struct domain_tstamp *domain_ts = data; + struct ptp_vclock *vclock; + unsigned long flags; + + if (!info->is_vclock) + return 0; + + /* Convert to domain tstamp if there is a domain matched */ + if (info->domain == domain_ts->domain) { + vclock = info_to_vclock(info); + spin_lock_irqsave(&vclock->lock, flags); + domain_ts->tstamp = timecounter_cyc2time(&vclock->tc, domain_ts->tstamp); + spin_unlock_irqrestore(&vclock->lock, flags); + /* For break. Not error. */ + return -EINVAL; + } + + return 0; +} + +void ptp_clock_domain_tstamp(struct device *dev, u64 *tstamp, u8 domain) +{ + struct domain_tstamp domain_ts; + + domain_ts.tstamp = *tstamp; + domain_ts.domain = domain; + + device_for_each_child(dev, &domain_ts, ptp_clock_find_domain_tstamp); + *tstamp = domain_ts.tstamp; +} +EXPORT_SYMBOL(ptp_clock_domain_tstamp); + +struct ptp_clock_info *ptp_get_pclock_info(const struct cyclecounter *cc) +{ + struct ptp_vclock *vclock = cc_to_vclock(cc); + + return vclock->pclock->info; +} +EXPORT_SYMBOL(ptp_get_pclock_info); + +struct ptp_vclock *ptp_vclock_register(struct ptp_clock *pclock, u8 domain) +{ + struct ptp_vclock_cc *vclock_cc = pclock->info->vclock_cc; + struct ptp_vclock *vclock; + + vclock = kzalloc(sizeof(*vclock), GFP_KERNEL); + if (!vclock) + return NULL; + + vclock->pclock = pclock; + + vclock->info = ptp_vclock_info; + vclock->info.vclock_cc = vclock_cc; + vclock->info.is_vclock = true; + vclock->info.domain = domain; + + vclock->cc = vclock_cc->cc; + vclock->mult = vclock_cc->cc.mult; + vclock->refresh_interval = vclock_cc->refresh_interval; + vclock->mult_num = vclock_cc->mult_num; + vclock->mult_dem = vclock_cc->mult_dem; + + spin_lock_init(&vclock->lock); + + vclock->clock = ptp_clock_register(&vclock->info, pclock->dev.parent); + if (IS_ERR_OR_NULL(vclock->clock)) { + kfree(vclock); + return NULL; + } + + timecounter_init(&vclock->tc, &vclock->cc, + ktime_to_ns(ktime_get_real())); + + INIT_DELAYED_WORK(&vclock->refresh_work, ptp_vclock_refresh); + schedule_delayed_work(&vclock->refresh_work, vclock->refresh_interval); + + return vclock; +} + +void ptp_vclock_unregister(struct ptp_vclock *vclock) +{ + cancel_delayed_work_sync(&vclock->refresh_work); + ptp_clock_unregister(vclock->clock); + kfree(vclock); +} diff --git a/include/linux/ptp_clock_kernel.h b/include/linux/ptp_clock_kernel.h index 0d47fd33b228..b2823af9b150 100644 --- a/include/linux/ptp_clock_kernel.h +++ b/include/linux/ptp_clock_kernel.h @@ -48,6 +48,32 @@ struct ptp_system_timestamp { struct timespec64 post_ts; }; +/** + * struct ptp_vclock_cc - ptp virtual clock cycle counter info + * + * @cc: cyclecounter structure + * @refresh_interval: time interval to refresh time counter, to avoid 64-bit + * overflow during delta conversion. For example, with + * cc.mult value 2^28, there are 36 bits left of cycle + * counter. With 1 ns counter resolution, the overflow time + * is 2^36 ns which is 68.7 s. The refresh_interval may be + * (60 * HZ) less than 68.7 s. + * @mult_num: parameter for cc.mult adjustment calculation, see below + * @mult_dem: parameter for cc.mult adjustment calculation, see below + * + * scaled_ppm to adjustment(mult_adj) of cc.mult + * + * mult_adj = mult * (ppb / 10^9) + * = mult * (scaled_ppm * 1000 / 2^16) / 10^9 + * = scaled_ppm * mult_num / mult_dem + */ +struct ptp_vclock_cc { + struct cyclecounter cc; + unsigned long refresh_interval; + u32 mult_num; + u32 mult_dem; +}; + /** * struct ptp_clock_info - describes a PTP hardware clock * @@ -157,6 +183,11 @@ struct ptp_clock_info { int (*verify)(struct ptp_clock_info *ptp, unsigned int pin, enum ptp_pin_function func, unsigned int chan); long (*do_aux_work)(struct ptp_clock_info *ptp); + + /* For virtual clock */ + struct ptp_vclock_cc *vclock_cc; + u8 domain; + bool is_vclock; }; struct ptp_clock; @@ -286,6 +317,21 @@ int ptp_schedule_worker(struct ptp_clock *ptp, unsigned long delay); */ void ptp_cancel_worker_sync(struct ptp_clock *ptp); +/** + * ptp_get_pclock_info() - get ptp_clock_info pointer of physical clock + * + * @cc: cyclecounter pointer of ptp virtual clock. + */ +struct ptp_clock_info *ptp_get_pclock_info(const struct cyclecounter *cc); + +/** + * ptp_clock_domain_tstamp() - convert to domain time stamp + * + * @dev: device pointer of current ptp clock. + * @tstamp: time stamp pointer to hardware time stamp + * @domain: domain number to convert + */ +void ptp_clock_domain_tstamp(struct device *dev, u64 *tstamp, u8 domain); #else static inline struct ptp_clock *ptp_clock_register(struct ptp_clock_info *info, struct device *parent) @@ -306,6 +352,11 @@ static inline int ptp_schedule_worker(struct ptp_clock *ptp, static inline void ptp_cancel_worker_sync(struct ptp_clock *ptp) { } +static inline struct ptp_clock_info *ptp_get_pclock_info(const struct cyclecounter *cc); +{ return NULL; } + +void ptp_clock_domain_tstamp(struct device *dev, u64 *tstamp, u8 domain) +{ } #endif static inline void ptp_read_system_prets(struct ptp_system_timestamp *sts) From patchwork Fri May 7 08:57:52 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Yangbo Lu X-Patchwork-Id: 12244149 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 X-Spam-Level: X-Spam-Status: No, score=-13.9 required=3.0 tests=BAYES_00, HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER,INCLUDES_PATCH, MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS,UNWANTED_LANGUAGE_BODY, URIBL_BLOCKED,USER_AGENT_GIT autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 4C777C433ED for ; Fri, 7 May 2021 08:47:54 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 0C5FB613D9 for ; Fri, 7 May 2021 08:47:54 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S236439AbhEGIsw (ORCPT ); Fri, 7 May 2021 04:48:52 -0400 Received: from inva020.nxp.com ([92.121.34.13]:59710 "EHLO inva020.nxp.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S230302AbhEGIsr (ORCPT ); Fri, 7 May 2021 04:48:47 -0400 Received: from inva020.nxp.com (localhost [127.0.0.1]) by inva020.eu-rdc02.nxp.com (Postfix) with ESMTP id 57FD61A19D1; Fri, 7 May 2021 10:47:47 +0200 (CEST) Received: from invc005.ap-rdc01.nxp.com (invc005.ap-rdc01.nxp.com [165.114.16.14]) by inva020.eu-rdc02.nxp.com (Postfix) with ESMTP id 771531A09DC; Fri, 7 May 2021 10:47:44 +0200 (CEST) Received: from localhost.localdomain (mega.ap.freescale.net [10.192.208.232]) by invc005.ap-rdc01.nxp.com (Postfix) with ESMTP id 4261340307; Fri, 7 May 2021 10:47:40 +0200 (CEST) From: Yangbo Lu To: netdev@vger.kernel.org Cc: Yangbo Lu , "David S . Miller" , Richard Cochran , Claudiu Manoil , Jakub Kicinski Subject: [net-next 2/6] ptp: support virtual clock and domain via sysfs Date: Fri, 7 May 2021 16:57:52 +0800 Message-Id: <20210507085756.20427-3-yangbo.lu@nxp.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20210507085756.20427-1-yangbo.lu@nxp.com> References: <20210507085756.20427-1-yangbo.lu@nxp.com> X-Virus-Scanned: ClamAV using ClamSMTP Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org X-Patchwork-Delegate: kuba@kernel.org Add support for virtual clock and domain via sysfs. Attributes new_vclock_domain/delete_vclock_domain are to create/remove ptp virtual clock. Attribute domain is to change domain value of the ptp clock. Signed-off-by: Yangbo Lu --- Documentation/ABI/testing/sysfs-ptp | 25 ++++++ drivers/ptp/ptp_sysfs.c | 122 ++++++++++++++++++++++++++++ 2 files changed, 147 insertions(+) diff --git a/Documentation/ABI/testing/sysfs-ptp b/Documentation/ABI/testing/sysfs-ptp index 2363ad810ddb..9c419c5554b5 100644 --- a/Documentation/ABI/testing/sysfs-ptp +++ b/Documentation/ABI/testing/sysfs-ptp @@ -25,6 +25,23 @@ Description: MAC based ones. The string does not necessarily have to be any kind of unique id. +What: /sys/class/ptp/ptpN/delete_vclock_domain +Date: May 2021 +Contact: Yangbo Lu +Description: + This write-only file removes PTP virtual clock for the + specified domain. Write the u8 domain value into this + file to remove the PTP virtual clock. + +What: /sys/class/ptp/ptpN/domain +Date: May 2021 +Contact: Yangbo Lu +Description: + This file contains the domain value that the PTP clock + serves. Time stamps of PTP messages of this domain are + provided by this PTP clock. Write a new u8 value into + this file to change the domain. + What: /sys/class/ptp/ptpN/max_adjustment Date: September 2010 Contact: Richard Cochran @@ -101,6 +118,14 @@ Description: the form of three integers: channel index, seconds, and nanoseconds. +What: /sys/class/ptp/ptpN/new_vclock_domain +Date: May 2021 +Contact: Yangbo Lu +Description: + This write-only file creates PTP virtual clock for a + specified domain. Write the u8 domain value into this + file to create the PTP virtual clock. + What: /sys/class/ptp/ptpN/period Date: September 2010 Contact: Richard Cochran diff --git a/drivers/ptp/ptp_sysfs.c b/drivers/ptp/ptp_sysfs.c index be076a91e20e..d8e7e05bd52d 100644 --- a/drivers/ptp/ptp_sysfs.c +++ b/drivers/ptp/ptp_sysfs.c @@ -121,6 +121,119 @@ static ssize_t period_store(struct device *dev, } static DEVICE_ATTR(period, 0220, NULL, period_store); +static int check_domain_avail(struct device *dev, void *data) +{ + struct ptp_clock *ptp = dev_get_drvdata(dev); + struct ptp_clock_info *info = ptp->info; + u8 *domain = data; + + if (info->domain == *domain) + return -EINVAL; + + return 0; +} + +static int delete_vclock_domain(struct device *dev, void *data) +{ + struct ptp_clock *ptp = dev_get_drvdata(dev); + struct ptp_clock_info *info = ptp->info; + struct ptp_vclock *vclock = info_to_vclock(info); + u8 *domain = data; + + if (!info->is_vclock) + return 0; + + if (info->domain == *domain) { + ptp_vclock_unregister(vclock); + /* For break. Not error. */ + return -EINVAL; + } + + return 0; +} + +static ssize_t domain_show(struct device *dev, + struct device_attribute *attr, char *page) +{ + struct ptp_clock *ptp = dev_get_drvdata(dev); + + return snprintf(page, PAGE_SIZE-1, "%d\n", ptp->info->domain); +} + +static ssize_t domain_store(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t count) +{ + struct ptp_clock *ptp = dev_get_drvdata(dev); + struct ptp_clock_info *info = ptp->info; + int err = -EINVAL; + u8 domain; + + if (kstrtou8(buf, 0, &domain)) + goto out; + + if (device_for_each_child(dev->parent, &domain, check_domain_avail)) { + dev_err(dev, "the domain value already in used\n"); + goto out; + } + + info->domain = domain; + + return count; +out: + return err; +} +static DEVICE_ATTR_RW(domain); + +static ssize_t new_vclock_domain_store(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t count) +{ + struct ptp_clock *ptp = dev_get_drvdata(dev); + struct ptp_vclock *vclock; + int err = -EINVAL; + u8 domain; + + if (kstrtou8(buf, 0, &domain)) + goto out; + + if (device_for_each_child(dev->parent, &domain, check_domain_avail)) { + dev_err(dev, "the domain value already in used\n"); + goto out; + } + + vclock = ptp_vclock_register(ptp, domain); + if (!vclock) + goto out; + + return count; +out: + return err; +} +static DEVICE_ATTR_WO(new_vclock_domain); + +static ssize_t delete_vclock_domain_store(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t count) +{ + int err = -EINVAL; + u8 domain; + + if (kstrtou8(buf, 0, &domain)) + goto out; + + if (!device_for_each_child(dev->parent, &domain, + delete_vclock_domain)) { + dev_err(dev, "no such vclock domain in used\n"); + goto out; + } + + return count; +out: + return err; +} +static DEVICE_ATTR_WO(delete_vclock_domain); + static ssize_t pps_enable_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) @@ -161,6 +274,9 @@ static struct attribute *ptp_attrs[] = { &dev_attr_extts_enable.attr, &dev_attr_fifo.attr, &dev_attr_period.attr, + &dev_attr_domain.attr, + &dev_attr_new_vclock_domain.attr, + &dev_attr_delete_vclock_domain.attr, &dev_attr_pps_enable.attr, NULL }; @@ -183,6 +299,12 @@ static umode_t ptp_is_attribute_visible(struct kobject *kobj, } else if (attr == &dev_attr_pps_enable.attr) { if (!info->pps) mode = 0; + } else if (attr == &dev_attr_new_vclock_domain.attr) { + if (info->is_vclock || !info->vclock_cc) + mode = 0; + } else if (attr == &dev_attr_delete_vclock_domain.attr) { + if (info->is_vclock || !info->vclock_cc) + mode = 0; } return mode; From patchwork Fri May 7 08:57:53 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Yangbo Lu X-Patchwork-Id: 12244151 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 X-Spam-Level: X-Spam-Status: No, score=-16.8 required=3.0 tests=BAYES_00, HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER,INCLUDES_PATCH, MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS,URIBL_BLOCKED,USER_AGENT_GIT autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 2523BC43460 for ; Fri, 7 May 2021 08:47:55 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id F0AE1613D9 for ; Fri, 7 May 2021 08:47:54 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S236447AbhEGIsx (ORCPT ); Fri, 7 May 2021 04:48:53 -0400 Received: from inva021.nxp.com ([92.121.34.21]:44708 "EHLO inva021.nxp.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S236424AbhEGIsu (ORCPT ); Fri, 7 May 2021 04:48:50 -0400 Received: from inva021.nxp.com (localhost [127.0.0.1]) by inva021.eu-rdc02.nxp.com (Postfix) with ESMTP id 35E3A203797; Fri, 7 May 2021 10:47:48 +0200 (CEST) Received: from invc005.ap-rdc01.nxp.com (invc005.ap-rdc01.nxp.com [165.114.16.14]) by inva021.eu-rdc02.nxp.com (Postfix) with ESMTP id 7EEDE200143; Fri, 7 May 2021 10:47:45 +0200 (CEST) Received: from localhost.localdomain (mega.ap.freescale.net [10.192.208.232]) by invc005.ap-rdc01.nxp.com (Postfix) with ESMTP id 9664640314; Fri, 7 May 2021 10:47:41 +0200 (CEST) From: Yangbo Lu To: netdev@vger.kernel.org Cc: Yangbo Lu , "David S . Miller" , Richard Cochran , Claudiu Manoil , Jakub Kicinski Subject: [net-next 3/6] ptp_qoriq: export ptp clock reading function for cyclecounter Date: Fri, 7 May 2021 16:57:53 +0800 Message-Id: <20210507085756.20427-4-yangbo.lu@nxp.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20210507085756.20427-1-yangbo.lu@nxp.com> References: <20210507085756.20427-1-yangbo.lu@nxp.com> X-Virus-Scanned: ClamAV using ClamSMTP Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org X-Patchwork-Delegate: kuba@kernel.org Export ptp clock reading function for cyclecounter to read cycles. Signed-off-by: Yangbo Lu --- drivers/ptp/ptp_qoriq.c | 15 +++++++++++++++ include/linux/fsl/ptp_qoriq.h | 1 + 2 files changed, 16 insertions(+) diff --git a/drivers/ptp/ptp_qoriq.c b/drivers/ptp/ptp_qoriq.c index 08f4cf0ad9e3..4617055a3307 100644 --- a/drivers/ptp/ptp_qoriq.c +++ b/drivers/ptp/ptp_qoriq.c @@ -311,6 +311,21 @@ int ptp_qoriq_enable(struct ptp_clock_info *ptp, } EXPORT_SYMBOL_GPL(ptp_qoriq_enable); +u64 ptp_qoriq_clock_read(const struct cyclecounter *cc) +{ + struct ptp_clock_info *ptp = ptp_get_pclock_info(cc); + struct ptp_qoriq *ptp_qoriq = container_of(ptp, struct ptp_qoriq, caps); + unsigned long flags; + u64 ns; + + spin_lock_irqsave(&ptp_qoriq->lock, flags); + ns = tmr_cnt_read(ptp_qoriq); + spin_unlock_irqrestore(&ptp_qoriq->lock, flags); + + return ns; +} +EXPORT_SYMBOL_GPL(ptp_qoriq_clock_read); + static const struct ptp_clock_info ptp_qoriq_caps = { .owner = THIS_MODULE, .name = "qoriq ptp clock", diff --git a/include/linux/fsl/ptp_qoriq.h b/include/linux/fsl/ptp_qoriq.h index 01acebe37fab..9a2ecd696c7e 100644 --- a/include/linux/fsl/ptp_qoriq.h +++ b/include/linux/fsl/ptp_qoriq.h @@ -193,6 +193,7 @@ int ptp_qoriq_settime(struct ptp_clock_info *ptp, const struct timespec64 *ts); int ptp_qoriq_enable(struct ptp_clock_info *ptp, struct ptp_clock_request *rq, int on); +u64 ptp_qoriq_clock_read(const struct cyclecounter *cc); int extts_clean_up(struct ptp_qoriq *ptp_qoriq, int index, bool update_event); #ifdef CONFIG_DEBUG_FS void ptp_qoriq_create_debugfs(struct ptp_qoriq *ptp_qoriq); From patchwork Fri May 7 08:57:54 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Yangbo Lu X-Patchwork-Id: 12244155 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 X-Spam-Level: X-Spam-Status: No, score=-16.8 required=3.0 tests=BAYES_00, HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER,INCLUDES_PATCH, MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS,URIBL_BLOCKED,USER_AGENT_GIT autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 03CFEC433B4 for ; Fri, 7 May 2021 08:48:01 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id C55B3613CE for ; Fri, 7 May 2021 08:48:00 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S236448AbhEGIs6 (ORCPT ); Fri, 7 May 2021 04:48:58 -0400 Received: from inva020.nxp.com ([92.121.34.13]:59752 "EHLO inva020.nxp.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S236426AbhEGIsu (ORCPT ); Fri, 7 May 2021 04:48:50 -0400 Received: from inva020.nxp.com (localhost [127.0.0.1]) by inva020.eu-rdc02.nxp.com (Postfix) with ESMTP id F3AB41A19C3; Fri, 7 May 2021 10:47:48 +0200 (CEST) Received: from invc005.ap-rdc01.nxp.com (invc005.ap-rdc01.nxp.com [165.114.16.14]) by inva020.eu-rdc02.nxp.com (Postfix) with ESMTP id 4F2FF1A19CD; Fri, 7 May 2021 10:47:46 +0200 (CEST) Received: from localhost.localdomain (mega.ap.freescale.net [10.192.208.232]) by invc005.ap-rdc01.nxp.com (Postfix) with ESMTP id A395740326; Fri, 7 May 2021 10:47:42 +0200 (CEST) From: Yangbo Lu To: netdev@vger.kernel.org Cc: Yangbo Lu , "David S . Miller" , Richard Cochran , Claudiu Manoil , Jakub Kicinski Subject: [net-next 4/6] enetc_ptp: support ptp virtual clock Date: Fri, 7 May 2021 16:57:54 +0800 Message-Id: <20210507085756.20427-5-yangbo.lu@nxp.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20210507085756.20427-1-yangbo.lu@nxp.com> References: <20210507085756.20427-1-yangbo.lu@nxp.com> X-Virus-Scanned: ClamAV using ClamSMTP Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org X-Patchwork-Delegate: kuba@kernel.org Add support for ptp virtual clock. Signed-off-by: Yangbo Lu Reported-by: kernel test robot --- drivers/net/ethernet/freescale/enetc/enetc_ptp.c | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/drivers/net/ethernet/freescale/enetc/enetc_ptp.c b/drivers/net/ethernet/freescale/enetc/enetc_ptp.c index bc594892507a..52de736df800 100644 --- a/drivers/net/ethernet/freescale/enetc/enetc_ptp.c +++ b/drivers/net/ethernet/freescale/enetc/enetc_ptp.c @@ -10,6 +10,16 @@ int enetc_phc_index = -1; EXPORT_SYMBOL(enetc_phc_index); +struct ptp_vclock_cc ptp_qoriq_vclock_cc = { + .cc.read = ptp_qoriq_clock_read, + .cc.mask = CYCLECOUNTER_MASK(64), + .cc.shift = 28, + .cc.mult = (1 << 28), + .refresh_interval = (HZ * 60), + .mult_num = (1 << 6), + .mult_dem = 15625, +}; + static struct ptp_clock_info enetc_ptp_caps = { .owner = THIS_MODULE, .name = "ENETC PTP clock", @@ -24,6 +34,7 @@ static struct ptp_clock_info enetc_ptp_caps = { .gettime64 = ptp_qoriq_gettime, .settime64 = ptp_qoriq_settime, .enable = ptp_qoriq_enable, + .vclock_cc = &ptp_qoriq_vclock_cc, }; static int enetc_ptp_probe(struct pci_dev *pdev, From patchwork Fri May 7 08:57:55 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Yangbo Lu X-Patchwork-Id: 12244153 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 X-Spam-Level: X-Spam-Status: No, score=-16.8 required=3.0 tests=BAYES_00, HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER,INCLUDES_PATCH, MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS,URIBL_BLOCKED,USER_AGENT_GIT autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id B293CC433B4 for ; Fri, 7 May 2021 08:47:56 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 7F49B613D8 for ; Fri, 7 May 2021 08:47:56 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S236457AbhEGIsy (ORCPT ); Fri, 7 May 2021 04:48:54 -0400 Received: from inva020.nxp.com ([92.121.34.13]:59788 "EHLO inva020.nxp.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S236434AbhEGIsu (ORCPT ); Fri, 7 May 2021 04:48:50 -0400 Received: from inva020.nxp.com (localhost [127.0.0.1]) by inva020.eu-rdc02.nxp.com (Postfix) with ESMTP id 275F31A09FD; Fri, 7 May 2021 10:47:50 +0200 (CEST) Received: from invc005.ap-rdc01.nxp.com (invc005.ap-rdc01.nxp.com [165.114.16.14]) by inva020.eu-rdc02.nxp.com (Postfix) with ESMTP id 66DED1A19D2; Fri, 7 May 2021 10:47:47 +0200 (CEST) Received: from localhost.localdomain (mega.ap.freescale.net [10.192.208.232]) by invc005.ap-rdc01.nxp.com (Postfix) with ESMTP id C9284402E6; Fri, 7 May 2021 10:47:43 +0200 (CEST) From: Yangbo Lu To: netdev@vger.kernel.org Cc: Yangbo Lu , "David S . Miller" , Richard Cochran , Claudiu Manoil , Jakub Kicinski Subject: [net-next 5/6] enetc: store ptp device pointer Date: Fri, 7 May 2021 16:57:55 +0800 Message-Id: <20210507085756.20427-6-yangbo.lu@nxp.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20210507085756.20427-1-yangbo.lu@nxp.com> References: <20210507085756.20427-1-yangbo.lu@nxp.com> X-Virus-Scanned: ClamAV using ClamSMTP Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org X-Patchwork-Delegate: kuba@kernel.org Store ptp device pointer which will be used for ptp domain timestamp conversion. Signed-off-by: Yangbo Lu --- drivers/net/ethernet/freescale/enetc/enetc.h | 1 + drivers/net/ethernet/freescale/enetc/enetc_pf.c | 5 +++++ drivers/net/ethernet/freescale/enetc/enetc_vf.c | 5 +++++ 3 files changed, 11 insertions(+) diff --git a/drivers/net/ethernet/freescale/enetc/enetc.h b/drivers/net/ethernet/freescale/enetc/enetc.h index 08b283347d9c..03e1ee1f6615 100644 --- a/drivers/net/ethernet/freescale/enetc/enetc.h +++ b/drivers/net/ethernet/freescale/enetc/enetc.h @@ -351,6 +351,7 @@ struct enetc_ndev_priv { struct work_struct tx_onestep_tstamp; struct sk_buff_head tx_skbs; + struct device *ptp_dev; }; /* Messaging */ diff --git a/drivers/net/ethernet/freescale/enetc/enetc_pf.c b/drivers/net/ethernet/freescale/enetc/enetc_pf.c index 31274325159a..71029b26e92e 100644 --- a/drivers/net/ethernet/freescale/enetc/enetc_pf.c +++ b/drivers/net/ethernet/freescale/enetc/enetc_pf.c @@ -1201,6 +1201,7 @@ static int enetc_pf_probe(struct pci_dev *pdev, { struct device_node *node = pdev->dev.of_node; struct enetc_ndev_priv *priv; + struct pci_dev *ptp_pdev; struct net_device *ndev; struct enetc_si *si; struct enetc_pf *pf; @@ -1293,6 +1294,10 @@ static int enetc_pf_probe(struct pci_dev *pdev, goto err_alloc_msix; } + ptp_pdev = pci_get_device(PCI_VENDOR_ID_FREESCALE, ENETC_DEV_ID_PTP, NULL); + if (ptp_pdev) + priv->ptp_dev = &ptp_pdev->dev; + if (!of_get_phy_mode(node, &pf->if_mode)) { err = enetc_mdiobus_create(pf, node); if (err) diff --git a/drivers/net/ethernet/freescale/enetc/enetc_vf.c b/drivers/net/ethernet/freescale/enetc/enetc_vf.c index 03090ba7e226..17fea364b091 100644 --- a/drivers/net/ethernet/freescale/enetc/enetc_vf.c +++ b/drivers/net/ethernet/freescale/enetc/enetc_vf.c @@ -138,6 +138,7 @@ static int enetc_vf_probe(struct pci_dev *pdev, const struct pci_device_id *ent) { struct enetc_ndev_priv *priv; + struct pci_dev *ptp_pdev; struct net_device *ndev; struct enetc_si *si; int err; @@ -188,6 +189,10 @@ static int enetc_vf_probe(struct pci_dev *pdev, goto err_alloc_msix; } + ptp_pdev = pci_get_device(PCI_VENDOR_ID_FREESCALE, ENETC_DEV_ID_PTP, NULL); + if (ptp_pdev) + priv->ptp_dev = &ptp_pdev->dev; + err = register_netdev(ndev); if (err) goto err_reg_netdev; From patchwork Fri May 7 08:57:56 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Yangbo Lu X-Patchwork-Id: 12244157 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 X-Spam-Level: X-Spam-Status: No, score=-16.8 required=3.0 tests=BAYES_00, HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER,INCLUDES_PATCH, MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS,URIBL_BLOCKED,USER_AGENT_GIT autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 05CB5C43460 for ; Fri, 7 May 2021 08:48:02 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id D495E613D8 for ; Fri, 7 May 2021 08:48:01 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S236484AbhEGItA (ORCPT ); Fri, 7 May 2021 04:49:00 -0400 Received: from inva020.nxp.com ([92.121.34.13]:59820 "EHLO inva020.nxp.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S236425AbhEGIsv (ORCPT ); Fri, 7 May 2021 04:48:51 -0400 Received: from inva020.nxp.com (localhost [127.0.0.1]) by inva020.eu-rdc02.nxp.com (Postfix) with ESMTP id 3A4FA1A19BA; Fri, 7 May 2021 10:47:51 +0200 (CEST) Received: from invc005.ap-rdc01.nxp.com (invc005.ap-rdc01.nxp.com [165.114.16.14]) by inva020.eu-rdc02.nxp.com (Postfix) with ESMTP id 890DA1A19BB; Fri, 7 May 2021 10:47:48 +0200 (CEST) Received: from localhost.localdomain (mega.ap.freescale.net [10.192.208.232]) by invc005.ap-rdc01.nxp.com (Postfix) with ESMTP id E00294029F; Fri, 7 May 2021 10:47:44 +0200 (CEST) From: Yangbo Lu To: netdev@vger.kernel.org Cc: Yangbo Lu , "David S . Miller" , Richard Cochran , Claudiu Manoil , Jakub Kicinski Subject: [net-next 6/6] enetc: support PTP domain timestamp conversion Date: Fri, 7 May 2021 16:57:56 +0800 Message-Id: <20210507085756.20427-7-yangbo.lu@nxp.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20210507085756.20427-1-yangbo.lu@nxp.com> References: <20210507085756.20427-1-yangbo.lu@nxp.com> X-Virus-Scanned: ClamAV using ClamSMTP Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org X-Patchwork-Delegate: kuba@kernel.org Support timestamp conversion to specified PTP domain in PTP packet. Signed-off-by: Yangbo Lu --- drivers/net/ethernet/freescale/enetc/enetc.c | 37 ++++++++++++++++++-- 1 file changed, 34 insertions(+), 3 deletions(-) diff --git a/drivers/net/ethernet/freescale/enetc/enetc.c b/drivers/net/ethernet/freescale/enetc/enetc.c index 3ca93adb9662..e7fb2fae98e0 100644 --- a/drivers/net/ethernet/freescale/enetc/enetc.c +++ b/drivers/net/ethernet/freescale/enetc/enetc.c @@ -7,6 +7,7 @@ #include #include #include +#include #include static int enetc_num_stack_tx_queues(struct enetc_ndev_priv *priv) @@ -472,13 +473,36 @@ static void enetc_get_tx_tstamp(struct enetc_hw *hw, union enetc_tx_bd *txbd, *tstamp = (u64)hi << 32 | tstamp_lo; } -static void enetc_tstamp_tx(struct sk_buff *skb, u64 tstamp) +static int enetc_ptp_parse_domain(struct sk_buff *skb, u8 *domain) +{ + unsigned int ptp_class; + struct ptp_header *hdr; + + ptp_class = ptp_classify_raw(skb); + if (ptp_class == PTP_CLASS_NONE) + return -EINVAL; + + hdr = ptp_parse_header(skb, ptp_class); + if (!hdr) + return -EINVAL; + + *domain = hdr->domain_number; + return 0; +} + +static void enetc_tstamp_tx(struct enetc_ndev_priv *priv, struct sk_buff *skb, + u64 tstamp) { struct skb_shared_hwtstamps shhwtstamps; + u64 ts = tstamp; + u8 domain; if (skb_shinfo(skb)->tx_flags & SKBTX_IN_PROGRESS) { + if (!enetc_ptp_parse_domain(skb, &domain)) + ptp_clock_domain_tstamp(priv->ptp_dev, &ts, domain); + memset(&shhwtstamps, 0, sizeof(shhwtstamps)); - shhwtstamps.hwtstamp = ns_to_ktime(tstamp); + shhwtstamps.hwtstamp = ns_to_ktime(ts); skb_txtime_consumed(skb); skb_tstamp_tx(skb, &shhwtstamps); } @@ -575,7 +599,7 @@ static bool enetc_clean_tx_ring(struct enetc_bdr *tx_ring, int napi_budget) */ schedule_work(&priv->tx_onestep_tstamp); } else if (unlikely(do_twostep_tstamp)) { - enetc_tstamp_tx(skb, tstamp); + enetc_tstamp_tx(priv, skb, tstamp); do_twostep_tstamp = false; } napi_consume_skb(skb, napi_budget); @@ -698,6 +722,7 @@ static void enetc_get_rx_tstamp(struct net_device *ndev, struct enetc_hw *hw = &priv->si->hw; u32 lo, hi, tstamp_lo; u64 tstamp; + u8 domain; if (le16_to_cpu(rxbd->r.flags) & ENETC_RXBD_FLAG_TSTMP) { lo = enetc_rd_reg_hot(hw->reg + ENETC_SICTR0); @@ -708,6 +733,12 @@ static void enetc_get_rx_tstamp(struct net_device *ndev, hi -= 1; tstamp = (u64)hi << 32 | tstamp_lo; + + skb_reset_mac_header(skb); + + if (!enetc_ptp_parse_domain(skb, &domain)) + ptp_clock_domain_tstamp(priv->ptp_dev, &tstamp, domain); + memset(shhwtstamps, 0, sizeof(*shhwtstamps)); shhwtstamps->hwtstamp = ns_to_ktime(tstamp); }