netdev.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Kory Maincent <kory.maincent@bootlin.com>
To: Florian Fainelli <florian.fainelli@broadcom.com>,
	 Broadcom internal kernel review list
	<bcm-kernel-feedback-list@broadcom.com>,
	 Andrew Lunn <andrew@lunn.ch>,
	Heiner Kallweit <hkallweit1@gmail.com>,
	 Russell King <linux@armlinux.org.uk>,
	 "David S. Miller" <davem@davemloft.net>,
	Eric Dumazet <edumazet@google.com>,
	 Jakub Kicinski <kuba@kernel.org>,
	Paolo Abeni <pabeni@redhat.com>,
	 Richard Cochran <richardcochran@gmail.com>,
	 Radu Pirea <radu-nicolae.pirea@oss.nxp.com>,
	 Jay Vosburgh <j.vosburgh@gmail.com>,
	Andy Gospodarek <andy@greyhouse.net>,
	 Nicolas Ferre <nicolas.ferre@microchip.com>,
	 Claudiu Beznea <claudiu.beznea@tuxon.dev>,
	 Willem de Bruijn <willemdebruijn.kernel@gmail.com>,
	 Jonathan Corbet <corbet@lwn.net>,
	 Horatiu Vultur <horatiu.vultur@microchip.com>,
	UNGLinuxDriver@microchip.com,  Simon Horman <horms@kernel.org>,
	Vladimir Oltean <vladimir.oltean@nxp.com>
Cc: Thomas Petazzoni <thomas.petazzoni@bootlin.com>,
	netdev@vger.kernel.org,  linux-kernel@vger.kernel.org,
	linux-doc@vger.kernel.org,
	 Maxime Chevallier <maxime.chevallier@bootlin.com>,
	 Rahul Rameshbabu <rrameshbabu@nvidia.com>,
	 Kory Maincent <kory.maincent@bootlin.com>
Subject: [PATCH net-next v9 09/13] net: Add the possibility to support a selected hwtstamp in netdevice
Date: Mon, 26 Feb 2024 14:40:00 +0100	[thread overview]
Message-ID: <20240226-feature_ptp_netnext-v9-9-455611549f21@bootlin.com> (raw)
In-Reply-To: <20240226-feature_ptp_netnext-v9-0-455611549f21@bootlin.com>

Introduce the description of a hwtstamp provider which is define with a
ptp_clock pointer and a qualifier value.

Add a hwtstamp provider description within the netdev structure to be able
to select the hwtstamp we want too use. By default we use the old API that
does not support hwtstamp selectability which mean the hwtstamp ptp_clock
pointer is unset.

Signed-off-by: Kory Maincent <kory.maincent@bootlin.com>
---

Change in v8:
- New patch
---
 drivers/net/phy/phy_device.c    |  7 +++++++
 include/linux/net_tstamp.h      |  6 ++++++
 include/linux/netdevice.h       |  5 +++++
 include/uapi/linux/net_tstamp.h | 11 +++++++++++
 net/core/dev_ioctl.c            | 39 +++++++++++++++++++++++++++++++++++++--
 net/core/timestamping.c         | 37 ++++++++++++++++++++++++++++++++-----
 6 files changed, 98 insertions(+), 7 deletions(-)

diff --git a/drivers/net/phy/phy_device.c b/drivers/net/phy/phy_device.c
index 2eefee970851..2532843e3c13 100644
--- a/drivers/net/phy/phy_device.c
+++ b/drivers/net/phy/phy_device.c
@@ -31,6 +31,7 @@
 #include <linux/phy_led_triggers.h>
 #include <linux/pse-pd/pse.h>
 #include <linux/property.h>
+#include <linux/ptp_clock_kernel.h>
 #include <linux/rtnetlink.h>
 #include <linux/sfp.h>
 #include <linux/skbuff.h>
@@ -1936,6 +1937,12 @@ void phy_detach(struct phy_device *phydev)
 
 	phy_suspend(phydev);
 	if (dev) {
+		/* Disable timestamp if selected */
+		if (ptp_clock_phydev(dev->hwtstamp.ptp) == phydev) {
+			dev->hwtstamp.ptp = NULL;
+			dev->hwtstamp.qualifier = HWTSTAMP_PROVIDER_QUALIFIER_PRECISE;
+		}
+
 		phydev->attached_dev->phydev = NULL;
 		phydev->attached_dev = NULL;
 	}
diff --git a/include/linux/net_tstamp.h b/include/linux/net_tstamp.h
index 662074b08c94..263dfcf12000 100644
--- a/include/linux/net_tstamp.h
+++ b/include/linux/net_tstamp.h
@@ -19,6 +19,11 @@ enum hwtstamp_source {
 	HWTSTAMP_SOURCE_PHYLIB,
 };
 
+struct hwtstamp_provider {
+	struct ptp_clock *ptp;
+	enum hwtstamp_provider_qualifier qualifier;
+};
+
 /**
  * struct kernel_hwtstamp_config - Kernel copy of struct hwtstamp_config
  *
@@ -43,6 +48,7 @@ struct kernel_hwtstamp_config {
 	struct ifreq *ifr;
 	bool copied_to_user;
 	enum hwtstamp_source source;
+	enum hwtstamp_provider_qualifier qualifier;
 };
 
 static inline void hwtstamp_config_to_kernel(struct kernel_hwtstamp_config *kernel_cfg,
diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h
index b67727c0dc58..43e3050a99af 100644
--- a/include/linux/netdevice.h
+++ b/include/linux/netdevice.h
@@ -47,6 +47,7 @@
 #include <uapi/linux/if_bonding.h>
 #include <uapi/linux/pkt_cls.h>
 #include <uapi/linux/netdev.h>
+#include <linux/net_tstamp.h>
 #include <linux/hashtable.h>
 #include <linux/rbtree.h>
 #include <net/net_trackers.h>
@@ -2107,6 +2108,8 @@ enum netdev_reg_state {
  *	@dpll_pin: Pointer to the SyncE source pin of a DPLL subsystem,
  *		   where the clock is recovered.
  *
+ *	@hwtstamp: Tracks which PTP performs hardware packet time stamping.
+ *
  *	FIXME: cleanup struct net_device such that network protocol info
  *	moves out.
  */
@@ -2478,6 +2481,8 @@ struct net_device {
 	/** @page_pools: page pools created for this netdevice */
 	struct hlist_head	page_pools;
 #endif
+
+	struct hwtstamp_provider	hwtstamp;
 };
 #define to_net_dev(d) container_of(d, struct net_device, dev)
 
diff --git a/include/uapi/linux/net_tstamp.h b/include/uapi/linux/net_tstamp.h
index a2c66b3d7f0f..a9ed48ee8fc7 100644
--- a/include/uapi/linux/net_tstamp.h
+++ b/include/uapi/linux/net_tstamp.h
@@ -13,6 +13,17 @@
 #include <linux/types.h>
 #include <linux/socket.h>   /* for SO_TIMESTAMPING */
 
+/*
+ * Possible type of htstamp provider. Mainly "precise" the default one
+ * is for IEEE 1588 quality and "approx" is for NICs DMA point.
+ */
+enum hwtstamp_provider_qualifier {
+	HWTSTAMP_PROVIDER_QUALIFIER_PRECISE,
+	HWTSTAMP_PROVIDER_QUALIFIER_APPROX,
+
+	HWTSTAMP_PROVIDER_QUALIFIER_CNT,
+};
+
 /* SO_TIMESTAMPING flags */
 enum {
 	SOF_TIMESTAMPING_TX_HARDWARE = (1<<0),
diff --git a/net/core/dev_ioctl.c b/net/core/dev_ioctl.c
index 3342834597cd..cd093c2aad67 100644
--- a/net/core/dev_ioctl.c
+++ b/net/core/dev_ioctl.c
@@ -6,6 +6,7 @@
 #include <linux/rtnetlink.h>
 #include <linux/net_tstamp.h>
 #include <linux/phylib_stubs.h>
+#include <linux/ptp_clock_kernel.h>
 #include <linux/wireless.h>
 #include <linux/if_bridge.h>
 #include <net/dsa_stubs.h>
@@ -270,6 +271,20 @@ static int dev_eth_ioctl(struct net_device *dev,
 int dev_get_hwtstamp_phylib(struct net_device *dev,
 			    struct kernel_hwtstamp_config *cfg)
 {
+	cfg->qualifier = dev->hwtstamp.qualifier;
+
+	if (dev->hwtstamp.ptp) {
+		struct ptp_clock *ptp = dev->hwtstamp.ptp;
+
+		if (ptp_clock_from_phylib(ptp))
+			return phy_hwtstamp_get(ptp_clock_phydev(ptp), cfg);
+
+		if (ptp_clock_from_netdev(ptp))
+			return dev->netdev_ops->ndo_hwtstamp_get(dev, cfg);
+
+		return -EOPNOTSUPP;
+	}
+
 	if (phy_is_default_hwtstamp(dev->phydev))
 		return phy_hwtstamp_get(dev->phydev, cfg);
 
@@ -327,11 +342,31 @@ int dev_set_hwtstamp_phylib(struct net_device *dev,
 			    struct netlink_ext_ack *extack)
 {
 	const struct net_device_ops *ops = dev->netdev_ops;
-	bool phy_ts = phy_is_default_hwtstamp(dev->phydev);
 	struct kernel_hwtstamp_config old_cfg = {};
+	struct phy_device *phydev;
 	bool changed = false;
+	bool phy_ts;
 	int err;
 
+	cfg->qualifier = dev->hwtstamp.qualifier;
+
+	if (dev->hwtstamp.ptp) {
+		struct ptp_clock *ptp = dev->hwtstamp.ptp;
+
+		if (ptp_clock_from_phylib(ptp)) {
+			phy_ts = true;
+			phydev = ptp_clock_phydev(ptp);
+		} else if (ptp_clock_from_netdev(ptp)) {
+			phy_ts = false;
+		} else {
+			return -EOPNOTSUPP;
+		}
+	} else {
+		phy_ts = phy_is_default_hwtstamp(dev->phydev);
+		if (phy_ts)
+			phydev = dev->phydev;
+	}
+
 	cfg->source = phy_ts ? HWTSTAMP_SOURCE_PHYLIB : HWTSTAMP_SOURCE_NETDEV;
 
 	if (phy_ts && (dev->priv_flags & IFF_SEE_ALL_HWTSTAMP_REQUESTS)) {
@@ -353,7 +388,7 @@ int dev_set_hwtstamp_phylib(struct net_device *dev,
 		changed = kernel_hwtstamp_config_changed(&old_cfg, cfg);
 
 	if (phy_ts) {
-		err = phy_hwtstamp_set(dev->phydev, cfg, extack);
+		err = phy_hwtstamp_set(phydev, cfg, extack);
 		if (err) {
 			if (changed)
 				ops->ndo_hwtstamp_set(dev, &old_cfg, NULL);
diff --git a/net/core/timestamping.c b/net/core/timestamping.c
index 3717fb152ecc..a7b256ac3490 100644
--- a/net/core/timestamping.c
+++ b/net/core/timestamping.c
@@ -9,6 +9,7 @@
 #include <linux/ptp_classify.h>
 #include <linux/skbuff.h>
 #include <linux/export.h>
+#include <linux/ptp_clock_kernel.h>
 
 static unsigned int classify(const struct sk_buff *skb)
 {
@@ -22,18 +23,31 @@ static unsigned int classify(const struct sk_buff *skb)
 void skb_clone_tx_timestamp(struct sk_buff *skb)
 {
 	struct mii_timestamper *mii_ts;
+	struct phy_device *phydev;
 	struct sk_buff *clone;
 	unsigned int type;
 
-	if (!skb->sk || !skb->dev ||
-	    !phy_is_default_hwtstamp(skb->dev->phydev))
+	if (!skb->sk || !skb->dev)
 		return;
 
+	if (skb->dev->hwtstamp.ptp) {
+		if (!ptp_clock_from_phylib(skb->dev->hwtstamp.ptp))
+			return;
+
+		phydev = ptp_clock_phydev(skb->dev->hwtstamp.ptp);
+
+	} else {
+		if (!phy_is_default_hwtstamp(phydev))
+			return;
+
+		phydev = skb->dev->phydev;
+	}
+
 	type = classify(skb);
 	if (type == PTP_CLASS_NONE)
 		return;
 
-	mii_ts = skb->dev->phydev->mii_ts;
+	mii_ts = phydev->mii_ts;
 	if (likely(mii_ts->txtstamp)) {
 		clone = skb_clone_sk(skb);
 		if (!clone)
@@ -46,11 +60,24 @@ EXPORT_SYMBOL_GPL(skb_clone_tx_timestamp);
 bool skb_defer_rx_timestamp(struct sk_buff *skb)
 {
 	struct mii_timestamper *mii_ts;
+	struct phy_device *phydev;
 	unsigned int type;
 
-	if (!skb->dev || !phy_is_default_hwtstamp(skb->dev->phydev))
+	if (!skb->dev)
 		return false;
 
+	if (skb->dev->hwtstamp.ptp) {
+		if (!ptp_clock_from_phylib(skb->dev->hwtstamp.ptp))
+			return false;
+
+		phydev = ptp_clock_phydev(skb->dev->hwtstamp.ptp);
+	} else {
+		if (!phy_is_default_hwtstamp(phydev))
+			return false;
+
+		phydev = skb->dev->phydev;
+	}
+
 	if (skb_headroom(skb) < ETH_HLEN)
 		return false;
 
@@ -63,7 +90,7 @@ bool skb_defer_rx_timestamp(struct sk_buff *skb)
 	if (type == PTP_CLASS_NONE)
 		return false;
 
-	mii_ts = skb->dev->phydev->mii_ts;
+	mii_ts = phydev->mii_ts;
 	if (likely(mii_ts->rxtstamp))
 		return mii_ts->rxtstamp(mii_ts, skb, type);
 

-- 
2.25.1


  parent reply	other threads:[~2024-02-26 13:40 UTC|newest]

Thread overview: 33+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2024-02-26 13:39 [PATCH net-next v9 00/13] net: Make timestamping selectable Kory Maincent
2024-02-26 13:39 ` [PATCH net-next v9 01/13] net_tstamp: Add TIMESTAMPING SOFTWARE and HARDWARE mask Kory Maincent
2024-02-26 13:39 ` [PATCH net-next v9 02/13] net: Make dev_get_hwtstamp_phylib accessible Kory Maincent
2024-03-05  2:40   ` Jakub Kicinski
2024-03-05  9:56     ` Köry Maincent
2024-03-05 10:02       ` Köry Maincent
2024-03-05 15:05         ` Jakub Kicinski
2024-02-26 13:39 ` [PATCH net-next v9 03/13] net: Make net_hwtstamp_validate accessible Kory Maincent
2024-02-26 13:39 ` [PATCH net-next v9 04/13] net: Change the API of PHY default timestamp to MAC Kory Maincent
2024-02-26 13:39 ` [PATCH net-next v9 05/13] net: net_tstamp: Add unspec field to hwtstamp_source enumeration Kory Maincent
2024-02-26 13:39 ` [PATCH net-next v9 06/13] net: Add struct kernel_ethtool_ts_info Kory Maincent
2024-02-26 16:47   ` Alexandra Winter
2024-02-28  3:27   ` Jakub Kicinski
2024-02-29  9:17     ` Köry Maincent
2024-02-26 13:39 ` [PATCH net-next v9 07/13] ptp: Move from simple ida to xarray Kory Maincent
2024-03-05  2:47   ` Jakub Kicinski
2024-03-05  9:02     ` Köry Maincent
2024-03-05 15:03       ` Jakub Kicinski
2024-02-26 13:39 ` [PATCH net-next v9 08/13] ptp: Add phc source and helpers to register specific PTP clock or get information Kory Maincent
2024-03-05  2:57   ` Jakub Kicinski
2024-03-05  8:36     ` Russell King (Oracle)
2024-03-05 10:10       ` Köry Maincent
2024-03-05 14:59         ` Jakub Kicinski
2024-03-05 15:35           ` Köry Maincent
2024-03-05 16:39             ` Jakub Kicinski
2024-02-26 13:40 ` Kory Maincent [this message]
2024-02-26 13:40 ` [PATCH net-next v9 10/13] net: netdevsim: ptp_mock: Convert to netdev_ptp_clock_register Kory Maincent
2024-02-26 13:40 ` [PATCH net-next v9 11/13] net: macb: " Kory Maincent
2024-02-26 13:40 ` [PATCH net-next v9 12/13] net: ethtool: tsinfo: Add support for hwtstamp provider and get/set hwtstamp config Kory Maincent
2024-03-05  3:27   ` Jakub Kicinski
2024-03-05 16:52     ` Köry Maincent
2024-03-05 18:04       ` Jakub Kicinski
2024-02-26 13:40 ` [PATCH net-next v9 13/13] netlink: specs: tsinfo: Enhance netlink attributes and add a set command Kory Maincent

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20240226-feature_ptp_netnext-v9-9-455611549f21@bootlin.com \
    --to=kory.maincent@bootlin.com \
    --cc=UNGLinuxDriver@microchip.com \
    --cc=andrew@lunn.ch \
    --cc=andy@greyhouse.net \
    --cc=bcm-kernel-feedback-list@broadcom.com \
    --cc=claudiu.beznea@tuxon.dev \
    --cc=corbet@lwn.net \
    --cc=davem@davemloft.net \
    --cc=edumazet@google.com \
    --cc=florian.fainelli@broadcom.com \
    --cc=hkallweit1@gmail.com \
    --cc=horatiu.vultur@microchip.com \
    --cc=horms@kernel.org \
    --cc=j.vosburgh@gmail.com \
    --cc=kuba@kernel.org \
    --cc=linux-doc@vger.kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux@armlinux.org.uk \
    --cc=maxime.chevallier@bootlin.com \
    --cc=netdev@vger.kernel.org \
    --cc=nicolas.ferre@microchip.com \
    --cc=pabeni@redhat.com \
    --cc=radu-nicolae.pirea@oss.nxp.com \
    --cc=richardcochran@gmail.com \
    --cc=rrameshbabu@nvidia.com \
    --cc=thomas.petazzoni@bootlin.com \
    --cc=vladimir.oltean@nxp.com \
    --cc=willemdebruijn.kernel@gmail.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).