Skip to contentSkip to conversation

Peer to Peer One-Step time stamping

PATCH Superseded Richard Cochran 4 participants 16 messages May 31, 2019 – Jul 9, 2019

Subsystems (8)

v5 of 9 Superseded Latest is v9 →

lore
Share & tools
lore

Richard Cochran

author maintainer
#0 lore raw

v5 cover Peer to Peer One-Step time stamping

This series adds support for PTP (IEEE 1588) P2P one-step time stamping along with a driver for a hardware device that supports this.

If the hardware supports p2p one-step, it subtracts the ingress time stamp value from the Pdelay_Request correction field. The user space software stack then simply copies the correction field into the Pdelay_Response, and on transmission the hardware adds the egress time stamp into the correction field.

This new functionality extends CONFIG_NETWORK_PHY_TIMESTAMPING to cover MII snooping devices, but it still depends on phylib, just as that option does. Expanding beyond phylib is not within the scope of the this series.

User space support is available in the current linuxptp master branch.

- Patch 1 adds the new option.
- Patches 2-5 add support for MII time stamping in non-PHY devices.
- Patch 6 adds a driver implementing the new option.

Thanks,
Richard

Changed in v5:
~~~~~~~~~~~~~~

- Fixed build failure in macvlan.
- Fixed latent bug with its gcc warning in the driver.

Changed in v4:
~~~~~~~~~~~~~~

- Correct error paths and PTR_ERR return values in the framework.
- Expanded KernelDoc comments WRT PHY locking.
- Pick up Andrew's review tag.

Changed in v3:
~~~~~~~~~~~~~~

- Simplify the device tree binding and document the time stamping phandle by itself.

Changed in v2:
~~~~~~~~~~~~~~

- Per the v1 review, changed the modeling of MII time stamping devices. They are no longer a kind of mdio device.

Richard Cochran (6):
net: Introduce peer to peer one step PTP time stamping.
net: Introduce a new MII time stamping interface.
net: Add a layer for non-PHY MII time stamping drivers.
dt-bindings: ptp: Introduce MII time stamping devices.
net: mdio: of: Register discovered MII time stampers.
ptp: Add a driver for InES time stamping IP core.

 Documentation/devicetree/bindings/ptp/ptp-ines.txt |  35 +
 .../devicetree/bindings/ptp/timestamper.txt        |  41 +
 drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c   |   1 +
 drivers/net/macvlan.c                              |   4 +-
 drivers/net/phy/Makefile                           |   2 +
 drivers/net/phy/dp83640.c                          |  47 +-
 drivers/net/phy/mii_timestamper.c                  | 121 +++
 drivers/net/phy/phy.c                              |   4 +-
 drivers/net/phy/phy_device.c                       |   5 +
 drivers/of/of_mdio.c                               |  30 +-
 drivers/ptp/Kconfig                                |  10 +
 drivers/ptp/Makefile                               |   1 +
 drivers/ptp/ptp_ines.c                             | 859 +++++++++++++++++++++
 include/linux/mii_timestamper.h                    | 120 +++
 include/linux/phy.h                                |  25 +-
 include/uapi/linux/net_tstamp.h                    |   8 +
 net/8021q/vlan_dev.c                               |   4 +-
 net/Kconfig                                        |   7 +-
 net/core/dev_ioctl.c                               |   1 +
 net/core/ethtool.c                                 |   4 +-
 net/core/timestamping.c                            |  20 +-
 21 files changed, 1289 insertions(+), 60 deletions(-)
 create mode 100644 Documentation/devicetree/bindings/ptp/ptp-ines.txt
 create mode 100644 Documentation/devicetree/bindings/ptp/timestamper.txt
 create mode 100644 drivers/net/phy/mii_timestamper.c
 create mode 100644 drivers/ptp/ptp_ines.c
 create mode 100644 include/linux/mii_timestamper.h
Signature · 1 line
2.11.0
author maintainer
#1 lore raw

PATCH v5 1/6 net: Introduce peer to peer one step PTP time stamping.

The 1588 standard defines one step operation for both Sync and PDelay_Resp messages. Up until now, hardware with P2P one step has been rare, and kernel support was lacking. This patch adds support of the mode in anticipation of new hardware developments.

---
 drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c | 1 +
 include/uapi/linux/net_tstamp.h                  | 8 ++++++++
 net/core/dev_ioctl.c                             | 1 +
 3 files changed, 10 insertions(+)
drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c +1 -0
index 03ac10b1cd1e..44a378f26bbd 100644
@@ -15380,6 +15380,7 @@ int bnx2x_configure_ptp_filters(struct bnx2x *bp)
 		REG_WR(bp, rule, BNX2X_PTP_TX_ON_RULE_MASK);
 		break;
 	case HWTSTAMP_TX_ONESTEP_SYNC:
+	case HWTSTAMP_TX_ONESTEP_P2P:
 		BNX2X_ERR("One-step timestamping is not supported\n");
 		return -ERANGE;
 	}
include/uapi/linux/net_tstamp.h +8 -0
index e5b39721c6e4..f96e650d0af9 100644
@@ -90,6 +90,14 @@ enum hwtstamp_tx_types {
 	 * queue.
 	 */
 	HWTSTAMP_TX_ONESTEP_SYNC,
+
+	/*
+	 * Same as HWTSTAMP_TX_ONESTEP_SYNC, but also enables time
+	 * stamp insertion directly into PDelay_Resp packets. In this
+	 * case, neither transmitted Sync nor PDelay_Resp packets will
+	 * receive a time stamp via the socket error queue.
+	 */
+	HWTSTAMP_TX_ONESTEP_P2P,
 };
 
 /* possible values for hwtstamp_config->rx_filter */
net/core/dev_ioctl.c +1 -0
index 5163d900bb4f..dbaebbe573f0 100644
@@ -187,6 +187,7 @@ static int net_hwtstamp_validate(struct ifreq *ifr)
 	case HWTSTAMP_TX_OFF:
 	case HWTSTAMP_TX_ON:
 	case HWTSTAMP_TX_ONESTEP_SYNC:
+	case HWTSTAMP_TX_ONESTEP_P2P:
 		tx_type_valid = 1;
 		break;
 	}
Signature · 1 line
2.11.0
author maintainer
#2 lore raw

PATCH v5 2/6 net: Introduce a new MII time stamping interface.

In reply to Richard Cochran

Currently the stack supports time stamping in PHY devices. However, there are newer, non-PHY devices that can snoop an MII bus and provide time stamps. In order to support such devices, this patch introduces a new interface to be used by both PHY and non-PHY devices.

In addition, the one and only user of the old PHY time stamping API is converted to the new interface.

---
 drivers/net/macvlan.c           |  4 +--
 drivers/net/phy/dp83640.c       | 47 +++++++++++++++++++++++-----------
 drivers/net/phy/phy.c           |  4 +--
 drivers/net/phy/phy_device.c    |  2 ++
 include/linux/mii_timestamper.h | 56 +++++++++++++++++++++++++++++++++++++++++
 include/linux/phy.h             | 25 ++----------------
 net/8021q/vlan_dev.c            |  4 +--
 net/core/ethtool.c              |  4 +--
 net/core/timestamping.c         | 20 +++++++--------
 9 files changed, 110 insertions(+), 56 deletions(-)
 create mode 100644 include/linux/mii_timestamper.h
drivers/net/macvlan.c +2 -2
index 0ccabde8e9c9..8f7868d31612 100644
@@ -1056,8 +1056,8 @@ static int macvlan_ethtool_get_ts_info(struct net_device *dev,
 	const struct ethtool_ops *ops = real_dev->ethtool_ops;
 	struct phy_device *phydev = real_dev->phydev;
 
-	if (phydev && phydev->drv && phydev->drv->ts_info) {
-		 return phydev->drv->ts_info(phydev, info);
+	if (phydev && phydev->mii_ts && phydev->mii_ts->ts_info) {
+		return phydev->mii_ts->ts_info(phydev->mii_ts, info);
 	} else if (ops->get_ts_info) {
 		return ops->get_ts_info(real_dev, info);
 	} else {
drivers/net/phy/dp83640.c +32 -15

120 lines not on this page · raw message

drivers/net/phy/phy.c +2 -2
index 84671d868a80..1137bef6a752 100644
@@ -470,8 +470,8 @@ int phy_mii_ioctl(struct phy_device *phydev, struct ifreq *ifr, int cmd)
 		return 0;
 
 	case SIOCSHWTSTAMP:
-		if (phydev->drv && phydev->drv->hwtstamp)
-			return phydev->drv->hwtstamp(phydev, ifr);
+		if (phydev->mii_ts && phydev->mii_ts->hwtstamp)
+			return phydev->mii_ts->hwtstamp(phydev->mii_ts, ifr);
 		/* fall through */
 
 	default:
drivers/net/phy/phy_device.c +2 -0
index 2c879ba01f35..055087654b2c 100644
@@ -915,6 +915,8 @@ static void phy_link_change(struct phy_device *phydev, bool up, bool do_carrier)
 			netif_carrier_off(netdev);
 	}
 	phydev->adjust_link(netdev);
+	if (phydev->mii_ts && phydev->mii_ts->link_state)
+		phydev->mii_ts->link_state(phydev->mii_ts, phydev);
 }
 
 /**
include/linux/mii_timestamper.h new file +56 -0

56 lines not on this page · raw message

include/linux/phy.h +2 -23
index dc4b51060ebc..ad63820a89d2 100644
@@ -22,6 +22,7 @@
 #include <linux/linkmode.h>
 #include <linux/mdio.h>
 #include <linux/mii.h>
+#include <linux/mii_timestamper.h>
 #include <linux/module.h>
 #include <linux/timer.h>
 #include <linux/workqueue.h>
@@ -443,6 +444,7 @@ struct phy_device {
 
 	struct phylink *phylink;
 	struct net_device *attached_dev;
+	struct mii_timestamper *mii_ts;
 
 	u8 mdix;
 	u8 mdix_ctrl;
@@ -548,29 +550,6 @@ struct phy_driver {
 	 */
 	int (*match_phy_device)(struct phy_device *phydev);
 
-	/* Handles ethtool queries for hardware time stamping. */
-	int (*ts_info)(struct phy_device *phydev, struct ethtool_ts_info *ti);
-
-	/* Handles SIOCSHWTSTAMP ioctl for hardware time stamping. */
-	int  (*hwtstamp)(struct phy_device *phydev, struct ifreq *ifr);
-
-	/*
-	 * Requests a Rx timestamp for 'skb'. If the skb is accepted,
-	 * the phy driver promises to deliver it using netif_rx() as
-	 * soon as a timestamp becomes available. One of the
-	 * PTP_CLASS_ values is passed in 'type'. The function must
-	 * return true if the skb is accepted for delivery.
-	 */
-	bool (*rxtstamp)(struct phy_device *dev, struct sk_buff *skb, int type);
-
-	/*
-	 * Requests a Tx timestamp for 'skb'. The phy driver promises
-	 * to deliver it using skb_complete_tx_timestamp() as soon as a
-	 * timestamp becomes available. One of the PTP_CLASS_ values
-	 * is passed in 'type'.
-	 */
-	void (*txtstamp)(struct phy_device *dev, struct sk_buff *skb, int type);
-
 	/* Some devices (e.g. qnap TS-119P II) require PHY register changes to
 	 * enable Wake on LAN, so set_wol is provided to be called in the
 	 * ethernet driver's set_wol function. */
net/8021q/vlan_dev.c +2 -2
index c546c4228075..12b832d32c59 100644
@@ -682,8 +682,8 @@ static int vlan_ethtool_get_ts_info(struct net_device *dev,
 	const struct ethtool_ops *ops = vlan->real_dev->ethtool_ops;
 	struct phy_device *phydev = vlan->real_dev->phydev;
 
-	if (phydev && phydev->drv && phydev->drv->ts_info) {
-		 return phydev->drv->ts_info(phydev, info);
+	if (phydev && phydev->mii_ts && phydev->mii_ts->ts_info) {
+		return phydev->mii_ts->ts_info(phydev->mii_ts, info);
 	} else if (ops->get_ts_info) {
 		return ops->get_ts_info(vlan->real_dev, info);
 	} else {
net/core/ethtool.c +2 -2
index 4a593853cbf2..e6cb3c987677 100644
@@ -2168,8 +2168,8 @@ static int ethtool_get_ts_info(struct net_device *dev, void __user *useraddr)
 	memset(&info, 0, sizeof(info));
 	info.cmd = ETHTOOL_GET_TS_INFO;
 
-	if (phydev && phydev->drv && phydev->drv->ts_info) {
-		err = phydev->drv->ts_info(phydev, &info);
+	if (phydev && phydev->mii_ts && phydev->mii_ts->ts_info) {
+		err = phydev->mii_ts->ts_info(phydev->mii_ts, &info);
 	} else if (ops->get_ts_info) {
 		err = ops->get_ts_info(dev, &info);
 	} else {
net/core/timestamping.c +10 -10
index 42689d5c468c..95c45c4dc0f9 100644
@@ -26,7 +26,7 @@
 static unsigned int classify(const struct sk_buff *skb)
 {
 	if (likely(skb->dev && skb->dev->phydev &&
-		   skb->dev->phydev->drv))
+		   skb->dev->phydev->mii_ts))
 		return ptp_classify_raw(skb);
 	else
 		return PTP_CLASS_NONE;
@@ -34,7 +34,7 @@ static unsigned int classify(const struct sk_buff *skb)
 
 void skb_clone_tx_timestamp(struct sk_buff *skb)
 {
-	struct phy_device *phydev;
+	struct mii_timestamper *mii_ts;
 	struct sk_buff *clone;
 	unsigned int type;
 
@@ -45,22 +45,22 @@ void skb_clone_tx_timestamp(struct sk_buff *skb)
 	if (type == PTP_CLASS_NONE)
 		return;
 
-	phydev = skb->dev->phydev;
-	if (likely(phydev->drv->txtstamp)) {
+	mii_ts = skb->dev->phydev->mii_ts;
+	if (likely(mii_ts->txtstamp)) {
 		clone = skb_clone_sk(skb);
 		if (!clone)
 			return;
-		phydev->drv->txtstamp(phydev, clone, type);
+		mii_ts->txtstamp(mii_ts, clone, type);
 	}
 }
 EXPORT_SYMBOL_GPL(skb_clone_tx_timestamp);
 
 bool skb_defer_rx_timestamp(struct sk_buff *skb)
 {
-	struct phy_device *phydev;
+	struct mii_timestamper *mii_ts;
 	unsigned int type;
 
-	if (!skb->dev || !skb->dev->phydev || !skb->dev->phydev->drv)
+	if (!skb->dev || !skb->dev->phydev || !skb->dev->phydev->mii_ts)
 		return false;
 
 	if (skb_headroom(skb) < ETH_HLEN)
@@ -75,9 +75,9 @@ bool skb_defer_rx_timestamp(struct sk_buff *skb)
 	if (type == PTP_CLASS_NONE)
 		return false;
 
-	phydev = skb->dev->phydev;
-	if (likely(phydev->drv->rxtstamp))
-		return phydev->drv->rxtstamp(phydev, skb, type);
+	mii_ts = skb->dev->phydev->mii_ts;
+	if (likely(mii_ts->rxtstamp))
+		return mii_ts->rxtstamp(mii_ts, skb, type);
 
 	return false;
 }
Signature · 1 line
2.11.0
author maintainer
#3 lore raw

PATCH v5 3/6 net: Add a layer for non-PHY MII time stamping drivers.

In reply to Richard Cochran

While PHY time stamping drivers can simply attach their interface directly to the PHY instance, stand alone drivers require support in order to manage their services. Non-PHY MII time stamping drivers have a control interface over another bus like I2C, SPI, UART, or via a memory mapped peripheral. The controller device will be associated with one or more time stamping channels, each of which sits snoops in on a MII bus.

This patch provides a glue layer that will enable time stamping channels to find their controlling device.

---
 drivers/net/phy/Makefile          |   2 +
 drivers/net/phy/mii_timestamper.c | 121 ++++++++++++++++++++++++++++++++++++++
 include/linux/mii_timestamper.h   |  64 ++++++++++++++++++++
 net/Kconfig                       |   7 ++-
 4 files changed, 191 insertions(+), 3 deletions(-)
 create mode 100644 drivers/net/phy/mii_timestamper.c
drivers/net/phy/Makefile +2 -0
index bac339e09042..4f7db9e23456 100644
@@ -42,6 +42,8 @@ obj-$(CONFIG_MDIO_SUN4I)	+= mdio-sun4i.o
 obj-$(CONFIG_MDIO_THUNDER)	+= mdio-thunder.o
 obj-$(CONFIG_MDIO_XGENE)	+= mdio-xgene.o
 
+obj-$(CONFIG_NETWORK_PHY_TIMESTAMPING) += mii_timestamper.o
+
 obj-$(CONFIG_SFP)		+= sfp.o
 sfp-obj-$(CONFIG_SFP)		+= sfp-bus.o
 obj-y				+= $(sfp-obj-y) $(sfp-obj-m)
drivers/net/phy/mii_timestamper.c new file +121 -0

121 lines not on this page · raw message

include/linux/mii_timestamper.h +64 -0

86 lines not on this page · raw message

net/Kconfig +4 -3
index d122f53c6fa2..203e6f5dafa7 100644
@@ -110,9 +110,10 @@ config NETWORK_PHY_TIMESTAMPING
 	bool "Timestamping in PHY devices"
 	select NET_PTP_CLASSIFY
 	help
-	  This allows timestamping of network packets by PHYs with
-	  hardware timestamping capabilities. This option adds some
-	  overhead in the transmit and receive paths.
+	  This allows timestamping of network packets by PHYs (or
+	  other MII bus snooping devices) with hardware timestamping
+	  capabilities. This option adds some overhead in the transmit
+	  and receive paths.
 
 	  If you are unsure how to answer this question, answer N.
 
Signature · 1 line
2.11.0
author maintainer
#4 lore raw

PATCH v5 4/6 dt-bindings: ptp: Introduce MII time stamping devices.

In reply to Richard Cochran

This patch add a new binding that allows non-PHY MII time stamping devices to find their buses. The new documentation covers both the generic binding and one upcoming user.

---
 Documentation/devicetree/bindings/ptp/ptp-ines.txt | 35 ++++++++++++++++++
 .../devicetree/bindings/ptp/timestamper.txt        | 41 ++++++++++++++++++++++
 2 files changed, 76 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/ptp/ptp-ines.txt
 create mode 100644 Documentation/devicetree/bindings/ptp/timestamper.txt
Documentation/devicetree/bindings/ptp/ptp-ines.txt new file +35 -0
new file mode 100644
index 000000000000..4dee9eb89455
@@ -0,0 +1,35 @@
+ZHAW InES PTP time stamping IP core
+
+The IP core needs two different kinds of nodes.  The control node
+lives somewhere in the memory map and specifies the address of the
+control registers.  There can be up to three port handles placed as
+attributes of PHY nodes.  These associate a particular MII bus with a
+port index within the IP core.
+
+Required properties of the control node:
+
+- compatible:		"ines,ptp-ctrl"
+- reg:			physical address and size of the register bank
+
+Required format of the port handle within the PHY node:
+
+- timestamper:		provides control node reference and
+			the port channel within the IP core
+
+Example:
+
+	tstamper: timestamper@60000000 {
+		compatible = "ines,ptp-ctrl";
+		reg = <0x60000000 0x80>;
+	};
+
+	ethernet@80000000 {
+		...
+		mdio {
+			...
+			phy@3 {
+				...
+				timestamper = <&tstamper 0>;
+			};
+		};
+	};
Documentation/devicetree/bindings/ptp/timestamper.txt new file +41 -0

41 lines not on this page · raw message

Signature · 1 line
2.11.0
maintainer
#5 lore raw

Re: [PATCH V5 net-next 4/6] dt-bindings: ptp: Introduce MII time stamping devices.

Quoted 20 lines · Richard Cochran

This patch add a new binding that allows non-PHY MII time stamping devices to find their buses. The new documentation covers both the generic binding and one upcoming user.

---
 Documentation/devicetree/bindings/ptp/ptp-ines.txt | 35 ++++++++++++++++++
 .../devicetree/bindings/ptp/timestamper.txt        | 41 ++++++++++++++++++++++
 2 files changed, 76 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/ptp/ptp-ines.txt
 create mode 100644 Documentation/devicetree/bindings/ptp/timestamper.txt
Documentation/devicetree/bindings/ptp/ptp-ines.txt new file +1 -0
new file mode 100644
index 000000000000..4dee9eb89455
@@ -0,0 +1,35 @@
+ZHAW InES PTP time stamping IP core

Documentation/devicetree/bindings/ptp/ptp-ines.txt line 11

Quoted 10 lines
Documentation/devicetree/bindings/ptp/ptp-ines.txt new file +10 -0
+
+The IP core needs two different kinds of nodes.  The control node
+lives somewhere in the memory map and specifies the address of the
+control registers.  There can be up to three port handles placed as
+attributes of PHY nodes.  These associate a particular MII bus with a
+port index within the IP core.
+
+Required properties of the control node:
+
+- compatible:		"ines,ptp-ctrl"

This is an IP block that gets integrated into SoCs? It's not very specific given that there could be different versions of the IP block and SoC vendors can integrate various versions of the IP block in their own unique (i.e. buggy) way.

Quoted 9 lines
Documentation/devicetree/bindings/ptp/ptp-ines.txt new file +9 -0
+- reg:			physical address and size of the register bank
+
+Required format of the port handle within the PHY node:
+
+- timestamper:		provides control node reference and
+			the port channel within the IP core
+
+Example:
+

Documentation/devicetree/bindings/ptp/ptp-ines.txt line 30

Quoted 10 lines
Documentation/devicetree/bindings/ptp/ptp-ines.txt new file +10 -0
+	tstamper: timestamper@60000000 {
+		compatible = "ines,ptp-ctrl";
+		reg = <0x60000000 0x80>;
+	};
+
+	ethernet@80000000 {
+		...
+		mdio {
+			...
+			phy@3 {

ethernet-phy is the correct node name.

Quoted 21 lines
Documentation/devicetree/bindings/ptp/ptp-ines.txt new file +5 -0
+				...
+				timestamper = <&tstamper 0>;
+			};
+		};
+	};
Documentation/devicetree/bindings/ptp/timestamper.txt new file +10 -0
new file mode 100644
index 000000000000..88ea0bc7d662
@@ -0,0 +1,41 @@
+Time stamps from MII bus snooping devices
+
+This binding supports non-PHY devices that snoop the MII bus and
+provide time stamps.  In contrast to PHY time stamping drivers (which
+can simply attach their interface directly to the PHY instance), stand
+alone MII time stamping drivers use this binding to specify the
+connection between the snooping device and a given network interface.
+
+Non-PHY MII time stamping drivers typically talk to the control
+interface over another bus like I2C, SPI, UART, or via a memory mapped

Documentation/devicetree/bindings/ptp/timestamper.txt line 20

Quoted 10 lines
Documentation/devicetree/bindings/ptp/timestamper.txt new file +10 -0
+peripheral.  This controller device is associated with one or more
+time stamping channels, each of which snoops on a MII bus.
+
+The "timestamper" property lives in a phy node and links a time
+stamping channel from the controller device to that phy's MII bus.
+
+Example:
+
+	tstamper: timestamper@10000000 {
+		compatible = "bigcorp,ts-ctrl";

Would be better to use a real example here.

Quoted 24 lines
Documentation/devicetree/bindings/ptp/timestamper.txt new file +21 -0
+	};
+
+	ethernet@20000000 {
+		mdio {
+			phy@1 {
+				timestamper = <&tstamper 0>;
+			};
+		};
+	};
+
+	ethernet@30000000 {
+		mdio {
+			phy@2 {
+				timestamper = <&tstamper 1>;
+			};
+		};
+	};
+
+In this example, time stamps from the MII bus attached to phy@1 will
+appear on time stamp channel 0 (zero), and those from phy@2 appear on
+channel 1.
Signature · 1 line
2.11.0
author maintainer
#6 lore raw

Re: [PATCH V5 net-next 4/6] dt-bindings: ptp: Introduce MII time stamping devices.

Quoted 5 lines · Rob Herring

Documentation/devicetree/bindings/ptp/ptp-ines.txt line 11

Quoted 3 lines
Documentation/devicetree/bindings/ptp/ptp-ines.txt new file +3 -0
+Required properties of the control node:
+
+- compatible:		"ines,ptp-ctrl"

This is an IP block that gets integrated into SoCs?

It is an IP block implemented in an FPGA (like the zync or the socfpga).

Quoted 4 lines

It's not very
specific given that there could be different versions of the IP block and SoC vendors can integrate various versions of the IP block in their own unique (i.e. buggy) way.

There is a version register where both the interface and FPGA are versioned. The driver doesn't presently do anything with that field, but if newer interfaces appear, then the driver can deal with that without any DT help.

Thanks,
Richard

author maintainer
#7 lore raw

PATCH v5 5/6 net: mdio: of: Register discovered MII time stampers.

In reply to Richard Cochran

When parsing a PHY node, register its time stamper, if any, and attach the instance to the PHY device.

---
 drivers/net/phy/phy_device.c |  3 +++
 drivers/of/of_mdio.c         | 30 +++++++++++++++++++++++++++++-
 2 files changed, 32 insertions(+), 1 deletion(-)
drivers/net/phy/phy_device.c +3 -0
index 055087654b2c..aa06ef33df79 100644
@@ -877,6 +877,9 @@ EXPORT_SYMBOL(phy_device_register);
  */
 void phy_device_remove(struct phy_device *phydev)
 {
+	if (phydev->mii_ts)
+		unregister_mii_timestamper(phydev->mii_ts);
+
 	device_del(&phydev->mdio.dev);
 
 	/* Assert the reset signal */
drivers/of/of_mdio.c +29 -1
index fcf25e32b1ed..98f2516ec3ba 100644
@@ -43,14 +43,37 @@ static int of_get_phy_id(struct device_node *device, u32 *phy_id)
 	return -EINVAL;
 }
 
+struct mii_timestamper *of_find_mii_timestamper(struct device_node *node)
+{
+	struct of_phandle_args arg;
+	int err;
+
+	err = of_parse_phandle_with_fixed_args(node, "timestamper", 1, 0, &arg);
+
+	if (err == -ENOENT)
+		return NULL;
+	else if (err)
+		return ERR_PTR(err);
+
+	if (arg.args_count != 1)
+		return ERR_PTR(-EINVAL);
+
+	return register_mii_timestamper(arg.np, arg.args[0]);
+}
+
 static int of_mdiobus_register_phy(struct mii_bus *mdio,
 				    struct device_node *child, u32 addr)
 {
+	struct mii_timestamper *mii_ts;
 	struct phy_device *phy;
 	bool is_c45;
 	int rc;
 	u32 phy_id;
 
+	mii_ts = of_find_mii_timestamper(child);
+	if (IS_ERR(mii_ts))
+		return PTR_ERR(mii_ts);
+
 	is_c45 = of_device_is_compatible(child,
 					 "ethernet-phy-ieee802.3-c45");
 
@@ -58,11 +81,14 @@ static int of_mdiobus_register_phy(struct mii_bus *mdio,
 		phy = phy_device_create(mdio, addr, phy_id, 0, NULL);
 	else
 		phy = get_phy_device(mdio, addr, is_c45);
-	if (IS_ERR(phy))
+	if (IS_ERR(phy)) {
+		unregister_mii_timestamper(mii_ts);
 		return PTR_ERR(phy);
+	}
 
 	rc = of_irq_get(child, 0);
 	if (rc == -EPROBE_DEFER) {
+		unregister_mii_timestamper(mii_ts);
 		phy_device_free(phy);
 		return rc;
 	}
@@ -91,10 +117,12 @@ static int of_mdiobus_register_phy(struct mii_bus *mdio,
 	 * register it */
 	rc = phy_device_register(phy);
 	if (rc) {
+		unregister_mii_timestamper(mii_ts);
 		phy_device_free(phy);
 		of_node_put(child);
 		return rc;
 	}
+	phy->mii_ts = mii_ts;
 
 	dev_dbg(&mdio->dev, "registered phy %pOFn at address %i\n",
 		child, addr);
Signature · 1 line
2.11.0
#8 lore raw

Re: [PATCH V5 net-next 5/6] net: mdio: of: Register discovered MII time stampers.

I love your patch! Perhaps something to improve:

Hi Richard,

I love your patch! Perhaps something to improve:

[auto build test WARNING on net-next/master]

url: https://github.com/0day-ci/linux/commits/Richard-Cochran/Peer-to-Peer-One-Step-time-stamping/20190531-200348
reproduce:

        # apt-get install sparse
        # sparse version: v0.6.1-rc1-7-g2b96cd8-dirty
        make ARCH=x86_64 allmodconfig
        make C=1 CF='-fdiagnostic-prefix -D__CHECK_ENDIAN__'

If you fix the issue, kindly add following tag

sparse warnings: (new ones prefixed by >>)

>> drivers/of/of_mdio.c:46:24: sparse: sparse: symbol 'of_find_mii_timestamper' was not declared. Should it be static?

Please review and possibly fold the followup patch.

---
0-DAY kernel test infrastructure Open Source Technology Center
https://lists.01.org/pipermail/kbuild-all Intel Corporation

#9 lore raw

[RFC PATCH] net: mdio: of: of_find_mii_timestamper() can be static

In reply to Richard Cochran
Fixes: 500a41a402da ("net: mdio: of: Register discovered MII time stampers.")
Fixes 500a41a402da ("net: mdio: of: Register discovered MII time stampers.")
---
 of_mdio.c |    2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/of/of_mdio.c +1 -1
index 255f47d..1251d73 100644
@@ -43,7 +43,7 @@ static int of_get_phy_id(struct device_node *device, u32 *phy_id)
 	return -EINVAL;
 }
 
-struct mii_timestamper *of_find_mii_timestamper(struct device_node *node)
+static struct mii_timestamper *of_find_mii_timestamper(struct device_node *node)
 {
 	struct of_phandle_args arg;
 	int err;
author maintainer
#10 lore raw

PATCH v5 6/6 ptp: Add a driver for InES time stamping IP core.

In reply to Richard Cochran

The InES at the ZHAW offers a PTP time stamping IP core. The FPGA logic recognizes and time stamps PTP frames on the MII bus. This patch adds a driver for the core along with a device tree binding to allow hooking the driver to MII buses.

---
 drivers/ptp/Kconfig    |  10 +
 drivers/ptp/Makefile   |   1 +
 drivers/ptp/ptp_ines.c | 859 +++++++++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 870 insertions(+)
 create mode 100644 drivers/ptp/ptp_ines.c
drivers/ptp/Kconfig +10 -0
index 9b8fee5178e8..9824ea0467c8 100644
@@ -89,6 +89,16 @@ config DP83640_PHY
 	  In order for this to work, your MAC driver must also
 	  implement the skb_tx_timestamp() function.
 
+config PTP_1588_CLOCK_INES
+	tristate "ZHAW InES PTP time stamping IP core"
+	depends on NETWORK_PHY_TIMESTAMPING
+	depends on PHYLIB
+	depends on PTP_1588_CLOCK
+	help
+	  This driver adds support for using the ZHAW InES 1588 IP
+	  core.  This clock is only useful if the MII bus of your MAC
+	  is wired up to the core.
+
 config PTP_1588_CLOCK_PCH
 	tristate "Intel PCH EG20T as PTP clock"
 	depends on X86_32 || COMPILE_TEST
drivers/ptp/Makefile +1 -0
index 677d1d178a3e..3cdd33f93d35 100644
@@ -6,6 +6,7 @@
 ptp-y					:= ptp_clock.o ptp_chardev.o ptp_sysfs.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
 obj-$(CONFIG_PTP_1588_CLOCK_IXP46X)	+= ptp_ixp46x.o
 obj-$(CONFIG_PTP_1588_CLOCK_PCH)	+= ptp_pch.o
 obj-$(CONFIG_PTP_1588_CLOCK_KVM)	+= ptp_kvm.o
drivers/ptp/ptp_ines.c new file +859 -0

859 lines not on this page · raw message

Signature · 1 line
2.11.0
#11 lore raw

Re: [PATCH V5 net-next 6/6] ptp: Add a driver for InES time stamping IP core.

I love your patch! Perhaps something to improve:

Hi Richard,

I love your patch! Perhaps something to improve:

[auto build test WARNING on net-next/master]

url: https://github.com/0day-ci/linux/commits/Richard-Cochran/Peer-to-Peer-One-Step-time-stamping/20190531-200348
reproduce:

        # apt-get install sparse
        # sparse version: v0.6.1-rc1-7-g2b96cd8-dirty
        make ARCH=x86_64 allmodconfig
        make C=1 CF='-fdiagnostic-prefix -D__CHECK_ENDIAN__'

If you fix the issue, kindly add following tag

sparse warnings: (new ones prefixed by >>)

>> drivers/ptp/ptp_ines.c:490:13: sparse: sparse: restricted __be64 degrades to integer
>> drivers/ptp/ptp_ines.c:495:28: sparse: sparse: cast to restricted __be16
>> drivers/ptp/ptp_ines.c:495:28: sparse: sparse: cast to restricted __be16
>> drivers/ptp/ptp_ines.c:495:28: sparse: sparse: cast to restricted __be16
>> drivers/ptp/ptp_ines.c:495:28: sparse: sparse: cast to restricted __be16
   drivers/ptp/ptp_ines.c:496:17: sparse: sparse: cast to restricted __be16
   drivers/ptp/ptp_ines.c:496:17: sparse: sparse: cast to restricted __be16
   drivers/ptp/ptp_ines.c:496:17: sparse: sparse: cast to restricted __be16
   drivers/ptp/ptp_ines.c:496:17: sparse: sparse: cast to restricted __be16
   drivers/ptp/ptp_ines.c:500:26: sparse: sparse: cast to restricted __be16
   drivers/ptp/ptp_ines.c:500:26: sparse: sparse: cast to restricted __be16
   drivers/ptp/ptp_ines.c:500:26: sparse: sparse: cast to restricted __be16
   drivers/ptp/ptp_ines.c:500:26: sparse: sparse: cast to restricted __be16
   drivers/ptp/ptp_ines.c:501:17: sparse: sparse: cast to restricted __be16
   drivers/ptp/ptp_ines.c:501:17: sparse: sparse: cast to restricted __be16
   drivers/ptp/ptp_ines.c:501:17: sparse: sparse: cast to restricted __be16
   drivers/ptp/ptp_ines.c:501:17: sparse: sparse: cast to restricted __be16
>> drivers/ptp/ptp_ines.c:543:28: sparse: sparse: incorrect type in argument 1 (different address spaces) @@    expected void const volatile [noderef] <asn:2> *addr @@    got ref] <asn:2> *addr @@
>> drivers/ptp/ptp_ines.c:543:28: sparse:    expected void const volatile [noderef] <asn:2> *addr
>> drivers/ptp/ptp_ines.c:543:28: sparse:    got unsigned int *
   drivers/ptp/ptp_ines.c:547:30: sparse: sparse: incorrect type in argument 1 (different address spaces) @@    expected void const volatile [noderef] <asn:2> *addr @@    got ref] <asn:2> *addr @@
   drivers/ptp/ptp_ines.c:547:30: sparse:    expected void const volatile [noderef] <asn:2> *addr
   drivers/ptp/ptp_ines.c:547:30: sparse:    got unsigned int *
   drivers/ptp/ptp_ines.c:557:31: sparse: sparse: incorrect type in argument 1 (different address spaces) @@    expected void const volatile [noderef] <asn:2> *addr @@    got ref] <asn:2> *addr @@
   drivers/ptp/ptp_ines.c:557:31: sparse:    expected void const volatile [noderef] <asn:2> *addr
   drivers/ptp/ptp_ines.c:557:31: sparse:    got unsigned int *
   drivers/ptp/ptp_ines.c:561:31: sparse: sparse: incorrect type in argument 1 (different address spaces) @@    expected void const volatile [noderef] <asn:2> *addr @@    got ref] <asn:2> *addr @@
   drivers/ptp/ptp_ines.c:561:31: sparse:    expected void const volatile [noderef] <asn:2> *addr
   drivers/ptp/ptp_ines.c:561:31: sparse:    got unsigned int *
   drivers/ptp/ptp_ines.c:562:31: sparse: sparse: incorrect type in argument 1 (different address spaces) @@    expected void const volatile [noderef] <asn:2> *addr @@    got ref] <asn:2> *addr @@
   drivers/ptp/ptp_ines.c:562:31: sparse:    expected void const volatile [noderef] <asn:2> *addr
   drivers/ptp/ptp_ines.c:562:31: sparse:    got unsigned int *
   drivers/ptp/ptp_ines.c:579:16: sparse: sparse: incorrect type in argument 1 (different address spaces) @@    expected void const volatile [noderef] <asn:2> *addr @@    got ref] <asn:2> *addr @@
   drivers/ptp/ptp_ines.c:579:16: sparse:    expected void const volatile [noderef] <asn:2> *addr
   drivers/ptp/ptp_ines.c:579:16: sparse:    got unsigned int *
   drivers/ptp/ptp_ines.c:583:24: sparse: sparse: incorrect type in argument 1 (different address spaces) @@    expected void const volatile [noderef] <asn:2> *addr @@    got ref] <asn:2> *addr @@
   drivers/ptp/ptp_ines.c:583:24: sparse:    expected void const volatile [noderef] <asn:2> *addr
   drivers/ptp/ptp_ines.c:583:24: sparse:    got unsigned int *
   drivers/ptp/ptp_ines.c:626:16: sparse: sparse: incorrect type in argument 1 (different address spaces) @@    expected void const volatile [noderef] <asn:2> *addr @@    got ref] <asn:2> *addr @@
   drivers/ptp/ptp_ines.c:626:16: sparse:    expected void const volatile [noderef] <asn:2> *addr
   drivers/ptp/ptp_ines.c:626:16: sparse:    got unsigned int *
   drivers/ptp/ptp_ines.c:630:24: sparse: sparse: incorrect type in argument 1 (different address spaces) @@    expected void const volatile [noderef] <asn:2> *addr @@    got ref] <asn:2> *addr @@
   drivers/ptp/ptp_ines.c:630:24: sparse:    expected void const volatile [noderef] <asn:2> *addr
   drivers/ptp/ptp_ines.c:630:24: sparse:    got unsigned int *
>> drivers/ptp/ptp_ines.c:208:21: sparse: sparse: incorrect type in assignment (different address spaces) @@    expected struct ines_global_registers *regs @@    got  ines_global_registers *regs @@
>> drivers/ptp/ptp_ines.c:208:21: sparse:    expected struct ines_global_registers *regs
>> drivers/ptp/ptp_ines.c:208:21: sparse:    got void [noderef] <asn:2> *base
>> drivers/ptp/ptp_ines.c:225:9: sparse: sparse: incorrect type in argument 2 (different address spaces) @@    expected void volatile [noderef] <asn:2> *addr @@    got ref] <asn:2> *addr @@
>> drivers/ptp/ptp_ines.c:225:9: sparse:    expected void volatile [noderef] <asn:2> *addr
   drivers/ptp/ptp_ines.c:225:9: sparse:    got unsigned int *
   drivers/ptp/ptp_ines.c:226:9: sparse: sparse: incorrect type in argument 2 (different address spaces) @@    expected void volatile [noderef] <asn:2> *addr @@    got ref] <asn:2> *addr @@
   drivers/ptp/ptp_ines.c:226:9: sparse:    expected void volatile [noderef] <asn:2> *addr
   drivers/ptp/ptp_ines.c:226:9: sparse:    got unsigned int *
   drivers/ptp/ptp_ines.c:228:9: sparse: sparse: incorrect type in argument 1 (different address spaces) @@    expected void const volatile [noderef] <asn:2> *addr @@    got ref] <asn:2> *addr @@
   drivers/ptp/ptp_ines.c:228:9: sparse:    expected void const volatile [noderef] <asn:2> *addr
   drivers/ptp/ptp_ines.c:228:9: sparse:    got unsigned int *
   drivers/ptp/ptp_ines.c:229:9: sparse: sparse: incorrect type in argument 1 (different address spaces) @@    expected void const volatile [noderef] <asn:2> *addr @@    got ref] <asn:2> *addr @@
   drivers/ptp/ptp_ines.c:229:9: sparse:    expected void const volatile [noderef] <asn:2> *addr
   drivers/ptp/ptp_ines.c:229:9: sparse:    got unsigned int *
   drivers/ptp/ptp_ines.c:230:9: sparse: sparse: incorrect type in argument 1 (different address spaces) @@    expected void const volatile [noderef] <asn:2> *addr @@    got ref] <asn:2> *addr @@
   drivers/ptp/ptp_ines.c:230:9: sparse:    expected void const volatile [noderef] <asn:2> *addr
   drivers/ptp/ptp_ines.c:230:9: sparse:    got unsigned int *
   drivers/ptp/ptp_ines.c:231:9: sparse: sparse: incorrect type in argument 1 (different address spaces) @@    expected void const volatile [noderef] <asn:2> *addr @@    got ref] <asn:2> *addr @@
   drivers/ptp/ptp_ines.c:231:9: sparse:    expected void const volatile [noderef] <asn:2> *addr
   drivers/ptp/ptp_ines.c:231:9: sparse:    got unsigned int *
   drivers/ptp/ptp_ines.c:235:17: sparse: sparse: incorrect type in argument 2 (different address spaces) @@    expected void volatile [noderef] <asn:2> *addr @@    got ref] <asn:2> *addr @@
   drivers/ptp/ptp_ines.c:235:17: sparse:    expected void volatile [noderef] <asn:2> *addr
   drivers/ptp/ptp_ines.c:235:17: sparse:    got unsigned int *
   drivers/ptp/ptp_ines.c:313:28: sparse: sparse: incorrect type in argument 1 (different address spaces) @@    expected void const volatile [noderef] <asn:2> *addr @@    got ref] <asn:2> *addr @@
   drivers/ptp/ptp_ines.c:313:28: sparse:    expected void const volatile [noderef] <asn:2> *addr
   drivers/ptp/ptp_ines.c:313:28: sparse:    got unsigned int *
   drivers/ptp/ptp_ines.c:318:30: sparse: sparse: incorrect type in argument 1 (different address spaces) @@    expected void const volatile [noderef] <asn:2> *addr @@    got ref] <asn:2> *addr @@
   drivers/ptp/ptp_ines.c:318:30: sparse:    expected void const volatile [noderef] <asn:2> *addr
   drivers/ptp/ptp_ines.c:318:30: sparse:    got unsigned int *
   drivers/ptp/ptp_ines.c:326:30: sparse: sparse: incorrect type in argument 1 (different address spaces) @@    expected void const volatile [noderef] <asn:2> *addr @@    got ref] <asn:2> *addr @@
   drivers/ptp/ptp_ines.c:326:30: sparse:    expected void const volatile [noderef] <asn:2> *addr
   drivers/ptp/ptp_ines.c:326:30: sparse:    got unsigned int *
   drivers/ptp/ptp_ines.c:330:30: sparse: sparse: incorrect type in argument 1 (different address spaces) @@    expected void const volatile [noderef] <asn:2> *addr @@    got ref] <asn:2> *addr @@
   drivers/ptp/ptp_ines.c:330:30: sparse:    expected void const volatile [noderef] <asn:2> *addr
   drivers/ptp/ptp_ines.c:330:30: sparse:    got unsigned int *
   drivers/ptp/ptp_ines.c:331:30: sparse: sparse: incorrect type in argument 1 (different address spaces) @@    expected void const volatile [noderef] <asn:2> *addr @@    got ref] <asn:2> *addr @@
   drivers/ptp/ptp_ines.c:331:30: sparse:    expected void const volatile [noderef] <asn:2> *addr
   drivers/ptp/ptp_ines.c:331:30: sparse:    got unsigned int *
   drivers/ptp/ptp_ines.c:401:21: sparse: sparse: incorrect type in argument 1 (different address spaces) @@    expected void const volatile [noderef] <asn:2> *addr @@    got ref] <asn:2> *addr @@
   drivers/ptp/ptp_ines.c:401:21: sparse:    expected void const volatile [noderef] <asn:2> *addr
   drivers/ptp/ptp_ines.c:401:21: sparse:    got unsigned int *
   drivers/ptp/ptp_ines.c:405:9: sparse: sparse: incorrect type in argument 2 (different address spaces) @@    expected void volatile [noderef] <asn:2> *addr @@    got ref] <asn:2> *addr @@
   drivers/ptp/ptp_ines.c:405:9: sparse:    expected void volatile [noderef] <asn:2> *addr
   drivers/ptp/ptp_ines.c:405:9: sparse:    got unsigned int *
   drivers/ptp/ptp_ines.c:406:9: sparse: sparse: incorrect type in argument 2 (different address spaces) @@    expected void volatile [noderef] <asn:2> *addr @@    got ref] <asn:2> *addr @@
   drivers/ptp/ptp_ines.c:406:9: sparse:    expected void volatile [noderef] <asn:2> *addr
   drivers/ptp/ptp_ines.c:406:9: sparse:    got unsigned int *
   drivers/ptp/ptp_ines.c:407:9: sparse: sparse: incorrect type in argument 2 (different address spaces) @@    expected void volatile [noderef] <asn:2> *addr @@    got ref] <asn:2> *addr @@
   drivers/ptp/ptp_ines.c:407:9: sparse:    expected void volatile [noderef] <asn:2> *addr
   drivers/ptp/ptp_ines.c:407:9: sparse:    got unsigned int *
   drivers/ptp/ptp_ines.c:440:21: sparse: sparse: incorrect type in argument 1 (different address spaces) @@    expected void const volatile [noderef] <asn:2> *addr @@    got ref] <asn:2> *addr @@
   drivers/ptp/ptp_ines.c:440:21: sparse:    expected void const volatile [noderef] <asn:2> *addr
   drivers/ptp/ptp_ines.c:440:21: sparse:    got unsigned int *
   drivers/ptp/ptp_ines.c:444:9: sparse: sparse: incorrect type in argument 2 (different address spaces) @@    expected void volatile [noderef] <asn:2> *addr @@    got ref] <asn:2> *addr @@
   drivers/ptp/ptp_ines.c:444:9: sparse:    expected void volatile [noderef] <asn:2> *addr
   drivers/ptp/ptp_ines.c:444:9: sparse:    got unsigned int *
   drivers/ptp/ptp_ines.c:643:21: sparse: sparse: incorrect type in argument 1 (different address spaces) @@    expected void const volatile [noderef] <asn:2> *addr @@    got ref] <asn:2> *addr @@
   drivers/ptp/ptp_ines.c:643:21: sparse:    expected void const volatile [noderef] <asn:2> *addr
   drivers/ptp/ptp_ines.c:643:21: sparse:    got unsigned int *
>> drivers/ptp/ptp_ines.c:756:24: sparse: sparse: symbol 'ines_ptp_probe_channel' was not declared. Should it be static?
>> drivers/ptp/ptp_ines.c:785:30: sparse: sparse: symbol 'ines_ctrl' was not declared. Should it be static?

Please review and possibly fold the followup patch.

vim +490 drivers/ptp/ptp_ines.c

416
417 static void ines_link_state(struct mii_timestamper *mii_ts,
418 struct phy_device *phydev)
419 {
420 struct ines_port *port = container_of(mii_ts, struct ines_port, mii_ts);
421 u32 port_conf, speed_conf;
422 unsigned long flags;
423
424 switch (phydev->speed) {
425 case SPEED_10:
426 speed_conf = PHY_SPEED_10 << PHY_SPEED_SHIFT;
427 break;
428 case SPEED_100:
429 speed_conf = PHY_SPEED_100 << PHY_SPEED_SHIFT;
430 break;
431 case SPEED_1000:
432 speed_conf = PHY_SPEED_1000 << PHY_SPEED_SHIFT;
433 break;
434 default:
435 pr_err("bad speed: %d\n", phydev->speed);
436 return;
437 }
438 spin_lock_irqsave(&port->lock, flags);
439

 > 440		port_conf = ines_read32(port, port_conf);
   441		port_conf &= ~(0x3 << PHY_SPEED_SHIFT);
   442		port_conf |= speed_conf;
   443	
   444		ines_write32(port, port_conf, port_conf);
   445	
   446		spin_unlock_irqrestore(&port->lock, flags);
   447	}
   448	
   449	static bool ines_match(struct sk_buff *skb, unsigned int ptp_class,
   450			       struct ines_timestamp *ts)
   451	{
   452		u8 *msgtype, *data = skb_mac_header(skb);
   453		unsigned int offset = 0;
   454		u16 *portn, *seqid;
   455		u64 *clkid;
   456	
   457		if (unlikely(ptp_class & PTP_CLASS_V1))
   458			return false;
   459	
   460		if (ptp_class & PTP_CLASS_VLAN)
   461			offset += VLAN_HLEN;
   462	
   463		switch (ptp_class & PTP_CLASS_PMASK) {
   464		case PTP_CLASS_IPV4:
   465			offset += ETH_HLEN + IPV4_HLEN(data + offset) + UDP_HLEN;
   466			break;
   467		case PTP_CLASS_IPV6:
   468			offset += ETH_HLEN + IP6_HLEN + UDP_HLEN;
   469			break;
   470		case PTP_CLASS_L2:
   471			offset += ETH_HLEN;
   472			break;
   473		default:
   474			return false;
   475		}
   476	
   477		if (skb->len + ETH_HLEN < offset + OFF_PTP_SEQUENCE_ID + sizeof(*seqid))
   478			return false;
   479	
   480		msgtype = data + offset;
   481		clkid = (u64 *)(data + offset + OFF_PTP_CLOCK_ID);
   482		portn = (u16 *)(data + offset + OFF_PTP_PORT_NUM);
   483		seqid = (u16 *)(data + offset + OFF_PTP_SEQUENCE_ID);
   484	
   485		if (tag_to_msgtype(ts->tag & 0x7) != (*msgtype & 0xf)) {
   486			pr_debug("msgtype mismatch ts %hhu != skb %hhu\n",
   487				 tag_to_msgtype(ts->tag & 0x7), *msgtype & 0xf);
   488			return false;
   489		}
 > 490		if (cpu_to_be64(ts->clkid) != *clkid) {
   491			pr_debug("clkid mismatch ts %llx != skb %llx\n",
   492				 cpu_to_be64(ts->clkid), *clkid);
   493			return false;
   494		}
 > 495		if (ts->portnum != ntohs(*portn)) {
 > 496			pr_debug("portn mismatch ts %hu != skb %hu\n",
   497				 ts->portnum, ntohs(*portn));
   498			return false;
   499		}
 > 500		if (ts->seqid != ntohs(*seqid)) {
   501			pr_debug("seqid mismatch ts %hu != skb %hu\n",
   502				 ts->seqid, ntohs(*seqid));
   503			return false;
   504		}
   505	
   506		return true;
   507	}
   508	
   509	static bool ines_rxtstamp(struct mii_timestamper *mii_ts,
   510				  struct sk_buff *skb, int type)
   511	{
   512		struct ines_port *port = container_of(mii_ts, struct ines_port, mii_ts);
   513		struct skb_shared_hwtstamps *ssh;
   514		u64 ns;
   515	
   516		if (!port->rxts_enabled)
   517			return false;
   518	
   519		ns = ines_find_rxts(port, skb, type);
   520		if (!ns)
   521			return false;
   522	
   523		ssh = skb_hwtstamps(skb);
   524		ssh->hwtstamp = ns_to_ktime(ns);
   525		netif_rx(skb);
   526	
   527		return true;
   528	}
   529	
   530	static int ines_rxfifo_read(struct ines_port *port)
   531	{
   532		u32 data_rd_pos, buf_stat, mask, ts_stat_rx;
   533		struct ines_timestamp *ts;
   534		unsigned int i;
   535	
   536		mask = RX_FIFO_NE_1 << port->index;
   537	
   538		for (i = 0; i < INES_FIFO_DEPTH; i++) {
   539			if (list_empty(&port->pool)) {
   540				pr_err("event pool is empty\n");
   541				return -1;
   542			}
 > 543			buf_stat = ines_read32(port->clock, buf_stat);
   544			if (!(buf_stat & mask))
   545				break;
   546	
   547			ts_stat_rx = ines_read32(port, ts_stat_rx);
   548			data_rd_pos = (ts_stat_rx >> DATA_READ_POS_SHIFT) &
   549				DATA_READ_POS_MASK;
   550			if (data_rd_pos) {
   551				pr_err("unexpected Rx read pos %u\n", data_rd_pos);
   552				break;
   553			}
   554	
   555			ts = list_first_entry(&port->pool, struct ines_timestamp, list);
   556			ts->tmo     = jiffies + HZ;
   557			ts->tag     = ines_read32(port, ts_rx);
   558			ts->sec     = ines_rxts64(port, 3);
   559			ts->nsec    = ines_rxts64(port, 2);
   560			ts->clkid   = ines_rxts64(port, 4);
   561			ts->portnum = ines_read32(port, ts_rx);
   562			ts->seqid   = ines_read32(port, ts_rx);
   563	
   564			ines_dump_ts("Rx", ts);
   565	
   566			list_del_init(&ts->list);
   567			list_add_tail(&ts->list, &port->events);
   568		}
   569	
   570		return 0;
   571	}
   572	
   573	static u64 ines_rxts64(struct ines_port *port, unsigned int words)
   574	{
   575		unsigned int i;
   576		u64 result;
   577		u16 word;
   578	
   579		word = ines_read32(port, ts_rx);
   580		result = word;
   581		words--;
   582		for (i = 0; i < words; i++) {
 > 583			word = ines_read32(port, ts_rx);
   584			result <<= 16;
   585			result |= word;
   586		}
   587		return result;
   588	}
   589	
   590	static bool ines_timestamp_expired(struct ines_timestamp *ts)
   591	{
   592		return time_after(jiffies, ts->tmo);
   593	}
   594	
   595	static int ines_ts_info(struct mii_timestamper *mii_ts,
   596				struct ethtool_ts_info *info)
   597	{
   598		info->so_timestamping =
   599			SOF_TIMESTAMPING_TX_HARDWARE |
   600			SOF_TIMESTAMPING_TX_SOFTWARE |
   601			SOF_TIMESTAMPING_RX_HARDWARE |
   602			SOF_TIMESTAMPING_RX_SOFTWARE |
   603			SOF_TIMESTAMPING_SOFTWARE |
   604			SOF_TIMESTAMPING_RAW_HARDWARE;
   605	
   606		info->phc_index = -1;
   607	
   608		info->tx_types =
   609			(1 << HWTSTAMP_TX_OFF) |
   610			(1 << HWTSTAMP_TX_ON) |
   611			(1 << HWTSTAMP_TX_ONESTEP_P2P);
   612	
   613		info->rx_filters =
   614			(1 << HWTSTAMP_FILTER_NONE) |
   615			(1 << HWTSTAMP_FILTER_PTP_V2_EVENT);
   616	
   617		return 0;
   618	}
   619	
   620	static u64 ines_txts64(struct ines_port *port, unsigned int words)
   621	{
   622		unsigned int i;
   623		u64 result;
   624		u16 word;
   625	
 > 626		word = ines_read32(port, ts_tx);

627 result = word;
628 words--;
629 for (i = 0; i < words; i++) {
630 word = ines_read32(port, ts_tx);
631 result <<= 16;
632 result |= word;
633 }
634 return result;
635 }
636

---
0-DAY kernel test infrastructure Open Source Technology Center
https://lists.01.org/pipermail/kbuild-all Intel Corporation

#12 lore raw

[RFC PATCH] ptp: ines_ptp_probe_channel() can be static

In reply to Richard Cochran
Fixes: 49268f31cc1f ("ptp: Add a driver for InES time stamping IP core.")
Fixes 49268f31cc1f ("ptp: Add a driver for InES time stamping IP core.")
---
 ptp_ines.c |    6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)
drivers/ptp/ptp_ines.c +3 -3
index 59cb3f1..52c1e85 100644
@@ -753,8 +753,8 @@ static u8 tag_to_msgtype(u8 tag)
 	return 0xf;
 }
 
-struct mii_timestamper *ines_ptp_probe_channel(struct device *device,
-					       unsigned int index)
+static struct mii_timestamper *ines_ptp_probe_channel(struct device *device,
+						      unsigned int index)
 {
 	struct device_node *node = device->of_node;
 	struct ines_port *port;
@@ -782,7 +782,7 @@ static void ines_ptp_release_channel(struct device *device,
 {
 }
 
-struct mii_timestamping_ctrl ines_ctrl = {
+static struct mii_timestamping_ctrl ines_ctrl = {
 	.probe_channel = ines_ptp_probe_channel,
 	.release_channel = ines_ptp_release_channel,
 };
maintainer
#13 lore raw
In reply to Richard Cochran

From: Richard Cochran <[email protected]>
Date: Thu, 30 May 2019 22:56:20 -0700

Quoted 2 lines

This series adds support for PTP (IEEE 1588) P2P one-step time stamping along with a driver for a hardware device that supports this.

...

Series applied, will push out after build testing :-)

Thanks.

maintainer
#14 lore raw

From: David Miller <[email protected]>
Date: Fri, 31 May 2019 14:54:56 -0700 (PDT)

Quoted 8 lines

From: Richard Cochran <[email protected]>
Date: Thu, 30 May 2019 22:56:20 -0700

Quoted 2 lines

This series adds support for PTP (IEEE 1588) P2P one-step time stamping along with a driver for a hardware device that supports this.

...

Series applied, will push out after build testing :-)

This also does not build.

Please do an allmodconfig build and save me from having to do this another time.

Thank you.

====================
ERROR: "register_mii_tstamp_controller" [drivers/ptp/ptp_ines.ko] undefined!
ERROR: "unregister_mii_tstamp_controller" [drivers/ptp/ptp_ines.ko] undefined!
ERROR: "unregister_mii_timestamper" [drivers/of/of_mdio.ko] undefined!
ERROR: "register_mii_timestamper" [drivers/of/of_mdio.ko] undefined!
ERROR: "unregister_mii_timestamper" [drivers/net/phy/libphy.ko] undefined! make[1]: *** [scripts/Makefile.modpost:91: __modpost] Error 1
make: *** [Makefile:1290: modules] Error 2
====================

author maintainer
#15 lore raw
Quoted 4 lines · David Miller

This also does not build.

Please do an allmodconfig build and save me from having to do this another time.

(Dons paper bag over head.)

I have a good excuse... it was the bay area fog that made me do it!

Sorry,
Richard