netdev.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH v3 net-next 00/17] PTP support for the SJA1105 DSA driver
@ 2019-06-04 17:07 Vladimir Oltean
  2019-06-04 17:07 ` [PATCH v3 net-next 01/17] net: dsa: Keep a pointer to the skb clone for TX timestamping Vladimir Oltean
                   ` (17 more replies)
  0 siblings, 18 replies; 40+ messages in thread
From: Vladimir Oltean @ 2019-06-04 17:07 UTC (permalink / raw)
  To: f.fainelli, vivien.didelot, andrew, davem, richardcochran,
	john.stultz, tglx, sboyd
  Cc: linux-kernel, netdev, Vladimir Oltean

This patchset adds the following:

 - A timecounter/cyclecounter based PHC for the free-running
   timestamping clock of this switch.

 - A state machine implemented in the DSA tagger for SJA1105, which
   keeps track of metadata follow-up Ethernet frames (the switch's way
   of transmitting RX timestamps).

Clock manipulations on the actual hardware PTP clock will have to be
implemented anyway, for the TTEthernet block and the time-based ingress
policer.

This depends upon the "FDB updates for SJA1105 DSA driver" series at:
https://patchwork.ozlabs.org/project/netdev/list/?series=111354&state=*

v2 patchset can be found at:
https://lkml.org/lkml/2019/6/2/146

Changes from v2:

- Broke previous 09/10 patch (timestamping) into multiple smaller
  patches.

- Every patch in the series compiles.

v1 patchset can be found at:
https://lkml.org/lkml/2019/5/28/1093

Changes from v1:

- Removed the addition of the DSA .can_timestamp callback.

- Waiting for meta frames is done completely inside the tagger, and all
  frames emitted on RX are already partially timestamped.

- Added a global data structure for the tagger common to all ports.

- Made PTP work with ports in standalone mode, by limiting use of the
  DMAC-mangling "incl_srcpt" mode only when ports are bridged, aka when
  the DSA master is already promiscuous and can receive anything.
  Also changed meta frames to be sent at the 01-80-C2-00-00-0E DMAC.

- Made some progress w.r.t. observed negative path delay.  Apparently it
  only appears when the delay mechanism is the delay request-response
  (end-to-end) one. If peer delay is used (-P), the path delay is
  positive and appears reasonable for an 1000Base-T link (485 ns in
  steady state).

  SJA1105 as PTP slave (OC) with E2E path delay:

ptp4l[55.600]: master offset          8 s2 freq  +83677 path delay     -2390
ptp4l[56.600]: master offset         17 s2 freq  +83688 path delay     -2391
ptp4l[57.601]: master offset          6 s2 freq  +83682 path delay     -2391
ptp4l[58.601]: master offset         -1 s2 freq  +83677 path delay     -2391

  SJA1105 as PTP slave (OC) with P2P path delay:

ptp4l[48.343]: master offset          5 s2 freq  +83715 path delay       484
ptp4l[48.468]: master offset         -3 s2 freq  +83705 path delay       485
ptp4l[48.593]: master offset          0 s2 freq  +83708 path delay       485
ptp4l[48.718]: master offset          1 s2 freq  +83710 path delay       485
ptp4l[48.844]: master offset          1 s2 freq  +83710 path delay       485
ptp4l[48.969]: master offset         -5 s2 freq  +83702 path delay       485
ptp4l[49.094]: master offset          3 s2 freq  +83712 path delay       485
ptp4l[49.219]: master offset          4 s2 freq  +83714 path delay       485
ptp4l[49.344]: master offset         -5 s2 freq  +83702 path delay       485
ptp4l[49.469]: master offset          3 s2 freq  +83713 path delay       487

Vladimir Oltean (17):
  net: dsa: Keep a pointer to the skb clone for TX timestamping
  net: dsa: Add teardown callback for drivers
  net: dsa: tag_8021q: Create helper function for removing VLAN header
  net: dsa: sja1105: Move sja1105_change_tpid into
    sja1105_vlan_filtering
  net: dsa: sja1105: Reverse TPID and TPID2
  net: dsa: sja1105: Limit use of incl_srcpt to bridge+vlan mode
  net: dsa: sja1105: Add support for the PTP clock
  net: dsa: sja1105: Move sja1105_is_link_local to include/linux
  net: dsa: sja1105: Add logic for TX timestamping
  net: dsa: sja1105: Build a minimal understanding of meta frames
  net: dsa: sja1105: Add support for the AVB Parameters Table
  net: dsa: sja1105: Make sja1105_is_link_local not match meta frames
  net: dsa: sja1105: Receive and decode meta frames
  net: dsa: sja1105: Add a global sja1105_tagger_data structure
  net: dsa: sja1105: Increase priority of CPU-trapped frames
  net: dsa: sja1105: Add a state machine for RX timestamping
  net: dsa: sja1105: Expose PTP timestamping ioctls to userspace

 drivers/net/dsa/sja1105/Kconfig               |   7 +
 drivers/net/dsa/sja1105/Makefile              |   1 +
 drivers/net/dsa/sja1105/sja1105.h             |  29 ++
 .../net/dsa/sja1105/sja1105_dynamic_config.c  |   2 +
 drivers/net/dsa/sja1105/sja1105_main.c        | 319 ++++++++++++--
 drivers/net/dsa/sja1105/sja1105_ptp.c         | 392 ++++++++++++++++++
 drivers/net/dsa/sja1105/sja1105_ptp.h         |  64 +++
 drivers/net/dsa/sja1105/sja1105_spi.c         |  33 ++
 .../net/dsa/sja1105/sja1105_static_config.c   |  59 +++
 .../net/dsa/sja1105/sja1105_static_config.h   |  10 +
 include/linux/dsa/8021q.h                     |   7 +
 include/linux/dsa/sja1105.h                   |  51 +++
 include/net/dsa.h                             |   1 +
 net/dsa/dsa2.c                                |   3 +
 net/dsa/slave.c                               |   3 +
 net/dsa/tag_8021q.c                           |  15 +
 net/dsa/tag_sja1105.c                         | 203 ++++++++-
 17 files changed, 1152 insertions(+), 47 deletions(-)
 create mode 100644 drivers/net/dsa/sja1105/sja1105_ptp.c
 create mode 100644 drivers/net/dsa/sja1105/sja1105_ptp.h

-- 
2.17.1


^ permalink raw reply	[flat|nested] 40+ messages in thread

* [PATCH v3 net-next 01/17] net: dsa: Keep a pointer to the skb clone for TX timestamping
  2019-06-04 17:07 [PATCH v3 net-next 00/17] PTP support for the SJA1105 DSA driver Vladimir Oltean
@ 2019-06-04 17:07 ` Vladimir Oltean
  2019-06-04 20:31   ` Florian Fainelli
  2019-06-04 17:07 ` [PATCH v3 net-next 02/17] net: dsa: Add teardown callback for drivers Vladimir Oltean
                   ` (16 subsequent siblings)
  17 siblings, 1 reply; 40+ messages in thread
From: Vladimir Oltean @ 2019-06-04 17:07 UTC (permalink / raw)
  To: f.fainelli, vivien.didelot, andrew, davem, richardcochran,
	john.stultz, tglx, sboyd
  Cc: linux-kernel, netdev, Vladimir Oltean

For drivers that use deferred_xmit for PTP frames (such as sja1105),
there is no need to perform matching between PTP frames and their egress
timestamps, since the sending process can be serialized.

In that case, it makes sense to have the pointer to the skb clone that
DSA made directly in the skb->cb. It will be used for pushing the egress
timestamp back in the application socket's error queue.

Signed-off-by: Vladimir Oltean <olteanv@gmail.com>
---
Changes in v3:

None.

Changes in v2:

Patch is new. Forgot to send in v1.

 net/dsa/slave.c | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/net/dsa/slave.c b/net/dsa/slave.c
index 1e2ae9d59b88..59d7c9e0270f 100644
--- a/net/dsa/slave.c
+++ b/net/dsa/slave.c
@@ -427,6 +427,8 @@ static void dsa_skb_tx_timestamp(struct dsa_slave_priv *p,
 	if (!clone)
 		return;
 
+	DSA_SKB_CB(skb)->clone = clone;
+
 	if (ds->ops->port_txtstamp(ds, p->dp->index, clone, type))
 		return;
 
@@ -464,6 +466,7 @@ static netdev_tx_t dsa_slave_xmit(struct sk_buff *skb, struct net_device *dev)
 	u64_stats_update_end(&s->syncp);
 
 	DSA_SKB_CB(skb)->deferred_xmit = false;
+	DSA_SKB_CB(skb)->clone = NULL;
 
 	/* Identify PTP protocol packets, clone them, and pass them to the
 	 * switch driver
-- 
2.17.1


^ permalink raw reply related	[flat|nested] 40+ messages in thread

* [PATCH v3 net-next 02/17] net: dsa: Add teardown callback for drivers
  2019-06-04 17:07 [PATCH v3 net-next 00/17] PTP support for the SJA1105 DSA driver Vladimir Oltean
  2019-06-04 17:07 ` [PATCH v3 net-next 01/17] net: dsa: Keep a pointer to the skb clone for TX timestamping Vladimir Oltean
@ 2019-06-04 17:07 ` Vladimir Oltean
  2019-06-04 18:15   ` Andrew Lunn
  2019-06-04 20:32   ` Florian Fainelli
  2019-06-04 17:07 ` [PATCH v3 net-next 03/17] net: dsa: tag_8021q: Create helper function for removing VLAN header Vladimir Oltean
                   ` (15 subsequent siblings)
  17 siblings, 2 replies; 40+ messages in thread
From: Vladimir Oltean @ 2019-06-04 17:07 UTC (permalink / raw)
  To: f.fainelli, vivien.didelot, andrew, davem, richardcochran,
	john.stultz, tglx, sboyd
  Cc: linux-kernel, netdev, Vladimir Oltean

This is helpful for e.g. draining per-driver (not per-port) tagger
queues.

Signed-off-by: Vladimir Oltean <olteanv@gmail.com>
---
Changes in v3:

Moved after dsa_switch_unregister_notifier, which is symmetrical to
where the setup callback is.

Changes in v2:

Patch is new.

 include/net/dsa.h | 1 +
 net/dsa/dsa2.c    | 3 +++
 2 files changed, 4 insertions(+)

diff --git a/include/net/dsa.h b/include/net/dsa.h
index a7f36219904f..4033e0677be4 100644
--- a/include/net/dsa.h
+++ b/include/net/dsa.h
@@ -361,6 +361,7 @@ struct dsa_switch_ops {
 						  int port);
 
 	int	(*setup)(struct dsa_switch *ds);
+	void	(*teardown)(struct dsa_switch *ds);
 	u32	(*get_phy_flags)(struct dsa_switch *ds, int port);
 
 	/*
diff --git a/net/dsa/dsa2.c b/net/dsa/dsa2.c
index b70befe8a3c8..d98e0e8ee8aa 100644
--- a/net/dsa/dsa2.c
+++ b/net/dsa/dsa2.c
@@ -412,6 +412,9 @@ static void dsa_switch_teardown(struct dsa_switch *ds)
 
 	dsa_switch_unregister_notifier(ds);
 
+	if (ds->ops->teardown)
+		ds->ops->teardown(ds);
+
 	if (ds->devlink) {
 		devlink_unregister(ds->devlink);
 		devlink_free(ds->devlink);
-- 
2.17.1


^ permalink raw reply related	[flat|nested] 40+ messages in thread

* [PATCH v3 net-next 03/17] net: dsa: tag_8021q: Create helper function for removing VLAN header
  2019-06-04 17:07 [PATCH v3 net-next 00/17] PTP support for the SJA1105 DSA driver Vladimir Oltean
  2019-06-04 17:07 ` [PATCH v3 net-next 01/17] net: dsa: Keep a pointer to the skb clone for TX timestamping Vladimir Oltean
  2019-06-04 17:07 ` [PATCH v3 net-next 02/17] net: dsa: Add teardown callback for drivers Vladimir Oltean
@ 2019-06-04 17:07 ` Vladimir Oltean
  2019-06-04 17:07 ` [PATCH v3 net-next 04/17] net: dsa: sja1105: Move sja1105_change_tpid into sja1105_vlan_filtering Vladimir Oltean
                   ` (14 subsequent siblings)
  17 siblings, 0 replies; 40+ messages in thread
From: Vladimir Oltean @ 2019-06-04 17:07 UTC (permalink / raw)
  To: f.fainelli, vivien.didelot, andrew, davem, richardcochran,
	john.stultz, tglx, sboyd
  Cc: linux-kernel, netdev, Vladimir Oltean

This removes the existing implementation from tag_sja1105, which was
partially incorrect (it was not changing the MAC header offset, thereby
leaving it to point 4 bytes earlier than it should have).

This overwrites the VLAN tag by moving the Ethernet source and
destination MACs 4 bytes to the right. Then skb->data (assumed to be
pointing immediately after the EtherType) is temporarily pushed to the
beginning of the new Ethernet header, the new Ethernet header offset and
length are recorded, then skb->data is moved back to where it was.

Signed-off-by: Vladimir Oltean <olteanv@gmail.com>
---
Changes in v3:

None.

Changes in v2:

Patch is new.

 include/linux/dsa/8021q.h |  7 +++++++
 net/dsa/tag_8021q.c       | 15 +++++++++++++++
 net/dsa/tag_sja1105.c     |  3 +--
 3 files changed, 23 insertions(+), 2 deletions(-)

diff --git a/include/linux/dsa/8021q.h b/include/linux/dsa/8021q.h
index 3911e0586478..463378812f18 100644
--- a/include/linux/dsa/8021q.h
+++ b/include/linux/dsa/8021q.h
@@ -31,6 +31,8 @@ int dsa_8021q_rx_switch_id(u16 vid);
 
 int dsa_8021q_rx_source_port(u16 vid);
 
+struct sk_buff *dsa_8021q_remove_header(struct sk_buff *skb);
+
 #else
 
 int dsa_port_setup_8021q_tagging(struct dsa_switch *ds, int index,
@@ -71,6 +73,11 @@ int dsa_8021q_rx_source_port(u16 vid)
 	return 0;
 }
 
+struct sk_buff *dsa_8021q_remove_header(struct sk_buff *skb)
+{
+	return NULL;
+}
+
 #endif /* IS_ENABLED(CONFIG_NET_DSA_TAG_8021Q) */
 
 #endif /* _NET_DSA_8021Q_H */
diff --git a/net/dsa/tag_8021q.c b/net/dsa/tag_8021q.c
index 65a35e976d7b..0ce680ef8e83 100644
--- a/net/dsa/tag_8021q.c
+++ b/net/dsa/tag_8021q.c
@@ -261,6 +261,21 @@ struct sk_buff *dsa_8021q_rcv(struct sk_buff *skb, struct net_device *netdev,
 }
 EXPORT_SYMBOL_GPL(dsa_8021q_rcv);
 
+struct sk_buff *dsa_8021q_remove_header(struct sk_buff *skb)
+{
+	u8 *from = skb_mac_header(skb);
+	u8 *dest = from + VLAN_HLEN;
+
+	memmove(dest, from, ETH_HLEN - VLAN_HLEN);
+	skb_push(skb, ETH_HLEN);
+	skb_reset_mac_header(skb);
+	skb_reset_mac_len(skb);
+	skb_pull(skb, ETH_HLEN);
+
+	return skb;
+}
+EXPORT_SYMBOL_GPL(dsa_8021q_remove_header);
+
 static const struct dsa_device_ops dsa_8021q_netdev_ops = {
 	.name		= "8021q",
 	.proto		= DSA_TAG_PROTO_8021Q,
diff --git a/net/dsa/tag_sja1105.c b/net/dsa/tag_sja1105.c
index d43737e6c3fb..535d8a1aabe1 100644
--- a/net/dsa/tag_sja1105.c
+++ b/net/dsa/tag_sja1105.c
@@ -106,8 +106,7 @@ static struct sk_buff *sja1105_rcv(struct sk_buff *skb,
 	 * it there, see dsa_switch_rcv: skb_push(skb, ETH_HLEN).
 	 */
 	if (is_tagged)
-		memmove(skb->data - ETH_HLEN, skb->data - ETH_HLEN - VLAN_HLEN,
-			ETH_HLEN - VLAN_HLEN);
+		skb = dsa_8021q_remove_header(skb);
 
 	return skb;
 }
-- 
2.17.1


^ permalink raw reply related	[flat|nested] 40+ messages in thread

* [PATCH v3 net-next 04/17] net: dsa: sja1105: Move sja1105_change_tpid into sja1105_vlan_filtering
  2019-06-04 17:07 [PATCH v3 net-next 00/17] PTP support for the SJA1105 DSA driver Vladimir Oltean
                   ` (2 preceding siblings ...)
  2019-06-04 17:07 ` [PATCH v3 net-next 03/17] net: dsa: tag_8021q: Create helper function for removing VLAN header Vladimir Oltean
@ 2019-06-04 17:07 ` Vladimir Oltean
  2019-06-04 20:58   ` Florian Fainelli
  2019-06-04 17:07 ` [PATCH v3 net-next 05/17] net: dsa: sja1105: Reverse TPID and TPID2 Vladimir Oltean
                   ` (13 subsequent siblings)
  17 siblings, 1 reply; 40+ messages in thread
From: Vladimir Oltean @ 2019-06-04 17:07 UTC (permalink / raw)
  To: f.fainelli, vivien.didelot, andrew, davem, richardcochran,
	john.stultz, tglx, sboyd
  Cc: linux-kernel, netdev, Vladimir Oltean

This is a cosmetic patch, pre-cursor to making another change to the
General Parameters Table (incl_srcpt) which does not logically pertain
to the sja1105_change_tpid function name, but not putting it there would
otherwise create a need of resetting the switch twice.

So simply move the existing code into the .port_vlan_filtering callback,
where the incl_srcpt change will be added as well.

Signed-off-by: Vladimir Oltean <olteanv@gmail.com>
---
Changes in v3:

None.

Changes in v2:

Patch is new.

 drivers/net/dsa/sja1105/sja1105_main.c | 42 +++++++++++++-------------
 1 file changed, 21 insertions(+), 21 deletions(-)

diff --git a/drivers/net/dsa/sja1105/sja1105_main.c b/drivers/net/dsa/sja1105/sja1105_main.c
index b151a8fafb9e..909497aa4b6f 100644
--- a/drivers/net/dsa/sja1105/sja1105_main.c
+++ b/drivers/net/dsa/sja1105/sja1105_main.c
@@ -1289,23 +1289,6 @@ static int sja1105_static_config_reload(struct sja1105_private *priv)
 	return rc;
 }
 
-/* The TPID setting belongs to the General Parameters table,
- * which can only be partially reconfigured at runtime (and not the TPID).
- * So a switch reset is required.
- */
-static int sja1105_change_tpid(struct sja1105_private *priv,
-			       u16 tpid, u16 tpid2)
-{
-	struct sja1105_general_params_entry *general_params;
-	struct sja1105_table *table;
-
-	table = &priv->static_config.tables[BLK_IDX_GENERAL_PARAMS];
-	general_params = table->entries;
-	general_params->tpid = tpid;
-	general_params->tpid2 = tpid2;
-	return sja1105_static_config_reload(priv);
-}
-
 static int sja1105_pvid_apply(struct sja1105_private *priv, int port, u16 pvid)
 {
 	struct sja1105_mac_config_entry *mac;
@@ -1424,17 +1407,34 @@ static int sja1105_vlan_prepare(struct dsa_switch *ds, int port,
 	return 0;
 }
 
+/* The TPID setting belongs to the General Parameters table,
+ * which can only be partially reconfigured at runtime (and not the TPID).
+ * So a switch reset is required.
+ */
 static int sja1105_vlan_filtering(struct dsa_switch *ds, int port, bool enabled)
 {
+	struct sja1105_general_params_entry *general_params;
 	struct sja1105_private *priv = ds->priv;
+	struct sja1105_table *table;
+	u16 tpid, tpid2;
 	int rc;
 
-	if (enabled)
+	if (enabled) {
 		/* Enable VLAN filtering. */
-		rc = sja1105_change_tpid(priv, ETH_P_8021Q, ETH_P_8021AD);
-	else
+		tpid  = ETH_P_8021Q;
+		tpid2 = ETH_P_8021AD;
+	} else {
 		/* Disable VLAN filtering. */
-		rc = sja1105_change_tpid(priv, ETH_P_SJA1105, ETH_P_SJA1105);
+		tpid  = ETH_P_SJA1105;
+		tpid2 = ETH_P_SJA1105;
+	}
+
+	table = &priv->static_config.tables[BLK_IDX_GENERAL_PARAMS];
+	general_params = table->entries;
+	general_params->tpid = tpid;
+	general_params->tpid2 = tpid2;
+
+	rc = sja1105_static_config_reload(priv);
 	if (rc)
 		dev_err(ds->dev, "Failed to change VLAN Ethertype\n");
 
-- 
2.17.1


^ permalink raw reply related	[flat|nested] 40+ messages in thread

* [PATCH v3 net-next 05/17] net: dsa: sja1105: Reverse TPID and TPID2
  2019-06-04 17:07 [PATCH v3 net-next 00/17] PTP support for the SJA1105 DSA driver Vladimir Oltean
                   ` (3 preceding siblings ...)
  2019-06-04 17:07 ` [PATCH v3 net-next 04/17] net: dsa: sja1105: Move sja1105_change_tpid into sja1105_vlan_filtering Vladimir Oltean
@ 2019-06-04 17:07 ` Vladimir Oltean
  2019-06-04 20:33   ` Florian Fainelli
  2019-06-04 17:07 ` [PATCH v3 net-next 06/17] net: dsa: sja1105: Limit use of incl_srcpt to bridge+vlan mode Vladimir Oltean
                   ` (12 subsequent siblings)
  17 siblings, 1 reply; 40+ messages in thread
From: Vladimir Oltean @ 2019-06-04 17:07 UTC (permalink / raw)
  To: f.fainelli, vivien.didelot, andrew, davem, richardcochran,
	john.stultz, tglx, sboyd
  Cc: linux-kernel, netdev, Vladimir Oltean

From reading the P/Q/R/S user manual, it appears that TPID is used by
the switch for detecting S-tags and TPID2 for C-tags.  Their meaning is
not clear from the E/T manual.

Signed-off-by: Vladimir Oltean <olteanv@gmail.com>
---
Changes in v3:

Patch is new.

 drivers/net/dsa/sja1105/sja1105_main.c | 6 ++++--
 1 file changed, 4 insertions(+), 2 deletions(-)

diff --git a/drivers/net/dsa/sja1105/sja1105_main.c b/drivers/net/dsa/sja1105/sja1105_main.c
index 909497aa4b6f..0f34e713c408 100644
--- a/drivers/net/dsa/sja1105/sja1105_main.c
+++ b/drivers/net/dsa/sja1105/sja1105_main.c
@@ -1421,8 +1421,8 @@ static int sja1105_vlan_filtering(struct dsa_switch *ds, int port, bool enabled)
 
 	if (enabled) {
 		/* Enable VLAN filtering. */
-		tpid  = ETH_P_8021Q;
-		tpid2 = ETH_P_8021AD;
+		tpid  = ETH_P_8021AD;
+		tpid2 = ETH_P_8021Q;
 	} else {
 		/* Disable VLAN filtering. */
 		tpid  = ETH_P_SJA1105;
@@ -1431,7 +1431,9 @@ static int sja1105_vlan_filtering(struct dsa_switch *ds, int port, bool enabled)
 
 	table = &priv->static_config.tables[BLK_IDX_GENERAL_PARAMS];
 	general_params = table->entries;
+	/* EtherType used to identify outer tagged (S-tag) VLAN traffic */
 	general_params->tpid = tpid;
+	/* EtherType used to identify inner tagged (C-tag) VLAN traffic */
 	general_params->tpid2 = tpid2;
 
 	rc = sja1105_static_config_reload(priv);
-- 
2.17.1


^ permalink raw reply related	[flat|nested] 40+ messages in thread

* [PATCH v3 net-next 06/17] net: dsa: sja1105: Limit use of incl_srcpt to bridge+vlan mode
  2019-06-04 17:07 [PATCH v3 net-next 00/17] PTP support for the SJA1105 DSA driver Vladimir Oltean
                   ` (4 preceding siblings ...)
  2019-06-04 17:07 ` [PATCH v3 net-next 05/17] net: dsa: sja1105: Reverse TPID and TPID2 Vladimir Oltean
@ 2019-06-04 17:07 ` Vladimir Oltean
  2019-06-04 20:35   ` Florian Fainelli
  2019-06-04 17:07 ` [PATCH v3 net-next 07/17] net: dsa: sja1105: Add support for the PTP clock Vladimir Oltean
                   ` (11 subsequent siblings)
  17 siblings, 1 reply; 40+ messages in thread
From: Vladimir Oltean @ 2019-06-04 17:07 UTC (permalink / raw)
  To: f.fainelli, vivien.didelot, andrew, davem, richardcochran,
	john.stultz, tglx, sboyd
  Cc: linux-kernel, netdev, Vladimir Oltean

The incl_srcpt setting makes the switch mangle the destination MACs of
multicast frames trapped to the CPU - a primitive tagging mechanism that
works even when we cannot use the 802.1Q software features.

The downside is that the two multicast MAC addresses that the switch
traps for L2 PTP (01-80-C2-00-00-0E and 01-1B-19-00-00-00) quickly turn
into a lot more, as the switch encodes the source port and switch id
into bytes 3 and 4 of the MAC. The resulting range of MAC addresses
would need to be installed manually into the DSA master port's multicast
MAC filter, and even then, most devices might not have a large enough
MAC filtering table.

As a result, only limit use of incl_srcpt to when it's strictly
necessary: when under a VLAN filtering bridge.  This fixes PTP in
non-bridged mode (standalone ports). Otherwise, PTP frames, as well as
metadata follow-up frames holding RX timestamps won't be received
because they will be blocked by the master port's MAC filter.
Linuxptp doesn't help, because it only requests the addition of the
unmodified PTP MACs to the multicast filter.
This issue is not seen in bridged mode because the master port is put in
promiscuous mode when the slave ports are enslaved to a bridge.
Therefore, there is no downside to having the incl_srcpt mechanism
active there.

Signed-off-by: Vladimir Oltean <olteanv@gmail.com>
---
Changes in v3:

None.

Changes in v2:

Patch is new.

 drivers/net/dsa/sja1105/sja1105_main.c |  9 +++++++--
 net/dsa/tag_sja1105.c                  | 20 +++++++++++---------
 2 files changed, 18 insertions(+), 11 deletions(-)

diff --git a/drivers/net/dsa/sja1105/sja1105_main.c b/drivers/net/dsa/sja1105/sja1105_main.c
index 0f34e713c408..a30b89455421 100644
--- a/drivers/net/dsa/sja1105/sja1105_main.c
+++ b/drivers/net/dsa/sja1105/sja1105_main.c
@@ -392,11 +392,11 @@ static int sja1105_init_general_params(struct sja1105_private *priv)
 		.hostprio = 0,
 		.mac_fltres1 = SJA1105_LINKLOCAL_FILTER_A,
 		.mac_flt1    = SJA1105_LINKLOCAL_FILTER_A_MASK,
-		.incl_srcpt1 = true,
+		.incl_srcpt1 = false,
 		.send_meta1  = false,
 		.mac_fltres0 = SJA1105_LINKLOCAL_FILTER_B,
 		.mac_flt0    = SJA1105_LINKLOCAL_FILTER_B_MASK,
-		.incl_srcpt0 = true,
+		.incl_srcpt0 = false,
 		.send_meta0  = false,
 		/* The destination for traffic matching mac_fltres1 and
 		 * mac_fltres0 on all ports except host_port. Such traffic
@@ -1435,6 +1435,11 @@ static int sja1105_vlan_filtering(struct dsa_switch *ds, int port, bool enabled)
 	general_params->tpid = tpid;
 	/* EtherType used to identify inner tagged (C-tag) VLAN traffic */
 	general_params->tpid2 = tpid2;
+	/* When VLAN filtering is on, we need to at least be able to
+	 * decode management traffic through the "backup plan".
+	 */
+	general_params->incl_srcpt1 = enabled;
+	general_params->incl_srcpt0 = enabled;
 
 	rc = sja1105_static_config_reload(priv);
 	if (rc)
diff --git a/net/dsa/tag_sja1105.c b/net/dsa/tag_sja1105.c
index 535d8a1aabe1..b35cf5c2d01c 100644
--- a/net/dsa/tag_sja1105.c
+++ b/net/dsa/tag_sja1105.c
@@ -66,8 +66,7 @@ static struct sk_buff *sja1105_rcv(struct sk_buff *skb,
 				   struct net_device *netdev,
 				   struct packet_type *pt)
 {
-	struct ethhdr *hdr = eth_hdr(skb);
-	u64 source_port, switch_id;
+	int source_port, switch_id;
 	struct sk_buff *nskb;
 	u16 tpid, vid, tci;
 	bool is_tagged;
@@ -75,12 +74,17 @@ static struct sk_buff *sja1105_rcv(struct sk_buff *skb,
 	nskb = dsa_8021q_rcv(skb, netdev, pt, &tpid, &tci);
 	is_tagged = (nskb && tpid == ETH_P_SJA1105);
 
-	skb->priority = (tci & VLAN_PRIO_MASK) >> VLAN_PRIO_SHIFT;
-	vid = tci & VLAN_VID_MASK;
-
 	skb->offload_fwd_mark = 1;
 
-	if (sja1105_is_link_local(skb)) {
+	if (is_tagged) {
+		/* Normal traffic path. */
+		vid = tci & VLAN_VID_MASK;
+		source_port = dsa_8021q_rx_source_port(vid);
+		switch_id = dsa_8021q_rx_switch_id(vid);
+		skb->priority = (tci & VLAN_PRIO_MASK) >> VLAN_PRIO_SHIFT;
+	} else if (sja1105_is_link_local(skb)) {
+		struct ethhdr *hdr = eth_hdr(skb);
+
 		/* Management traffic path. Switch embeds the switch ID and
 		 * port ID into bytes of the destination MAC, courtesy of
 		 * the incl_srcpt options.
@@ -91,9 +95,7 @@ static struct sk_buff *sja1105_rcv(struct sk_buff *skb,
 		hdr->h_dest[3] = 0;
 		hdr->h_dest[4] = 0;
 	} else {
-		/* Normal traffic path. */
-		source_port = dsa_8021q_rx_source_port(vid);
-		switch_id = dsa_8021q_rx_switch_id(vid);
+		return NULL;
 	}
 
 	skb->dev = dsa_master_find_slave(netdev, switch_id, source_port);
-- 
2.17.1


^ permalink raw reply related	[flat|nested] 40+ messages in thread

* [PATCH v3 net-next 07/17] net: dsa: sja1105: Add support for the PTP clock
  2019-06-04 17:07 [PATCH v3 net-next 00/17] PTP support for the SJA1105 DSA driver Vladimir Oltean
                   ` (5 preceding siblings ...)
  2019-06-04 17:07 ` [PATCH v3 net-next 06/17] net: dsa: sja1105: Limit use of incl_srcpt to bridge+vlan mode Vladimir Oltean
@ 2019-06-04 17:07 ` Vladimir Oltean
  2019-06-04 17:07 ` [PATCH v3 net-next 08/17] net: dsa: sja1105: Move sja1105_is_link_local to include/linux Vladimir Oltean
                   ` (10 subsequent siblings)
  17 siblings, 0 replies; 40+ messages in thread
From: Vladimir Oltean @ 2019-06-04 17:07 UTC (permalink / raw)
  To: f.fainelli, vivien.didelot, andrew, davem, richardcochran,
	john.stultz, tglx, sboyd
  Cc: linux-kernel, netdev, Vladimir Oltean

The design of this PHC driver is influenced by the switch's behavior
w.r.t. timestamping.  It exposes two PTP counters, one free-running
(PTPTSCLK) and the other offset- and frequency-corrected in hardware
through PTPCLKVAL, PTPCLKADD and PTPCLKRATE.  The MACs can sample either
of these for frame timestamps.

However, the user manual warns that taking timestamps based on the
corrected clock is less than useful, as the switch can deliver corrupted
timestamps in a variety of circumstances.

Therefore, this PHC uses the free-running PTPTSCLK together with a
timecounter/cyclecounter structure that translates it into a software
time domain.  Thus, the settime/adjtime and adjfine callbacks are
hardware no-ops.

The timestamps (introduced in a further patch) will also be translated
to the correct time domain before being handed over to the userspace PTP
stack.

The introduction of a second set of PHC operations that operate on the
hardware PTPCLKVAL/PTPCLKADD/PTPCLKRATE in the future is somewhat
unavoidable, as the TTEthernet core uses the corrected PTP time domain.
However, the free-running counter + timecounter structure combination
will suffice for now, as the resulting timestamps yield a sub-50 ns
synchronization offset in steady state using linuxptp.

For this patch, in absence of frame timestamping, the operations of the
switch PHC were tested by syncing it to the system time as a local slave
clock with:

phc2sys -s CLOCK_REALTIME -c swp2 -O 0 -m -S 0.01

Signed-off-by: Vladimir Oltean <olteanv@gmail.com>
---
Changes in v3:

None.

Changes in v2:

Now resetting the PTP clock each time the switch core itself gets reset.

 drivers/net/dsa/sja1105/Kconfig        |   7 +
 drivers/net/dsa/sja1105/Makefile       |   1 +
 drivers/net/dsa/sja1105/sja1105.h      |  18 ++
 drivers/net/dsa/sja1105/sja1105_main.c |   7 +
 drivers/net/dsa/sja1105/sja1105_ptp.c  | 286 +++++++++++++++++++++++++
 drivers/net/dsa/sja1105/sja1105_ptp.h  |  47 ++++
 drivers/net/dsa/sja1105/sja1105_spi.c  |  19 ++
 7 files changed, 385 insertions(+)
 create mode 100644 drivers/net/dsa/sja1105/sja1105_ptp.c
 create mode 100644 drivers/net/dsa/sja1105/sja1105_ptp.h

diff --git a/drivers/net/dsa/sja1105/Kconfig b/drivers/net/dsa/sja1105/Kconfig
index 1144fc5f61a8..049cea8240e4 100644
--- a/drivers/net/dsa/sja1105/Kconfig
+++ b/drivers/net/dsa/sja1105/Kconfig
@@ -16,3 +16,10 @@ tristate "NXP SJA1105 Ethernet switch family support"
 	    - SJA1105Q (Gen. 2, No SGMII, TT-Ethernet)
 	    - SJA1105R (Gen. 2, SGMII, No TT-Ethernet)
 	    - SJA1105S (Gen. 2, SGMII, TT-Ethernet)
+
+config NET_DSA_SJA1105_PTP
+tristate "Support for the PTP clock on the NXP SJA1105 Ethernet switch"
+	depends on NET_DSA_SJA1105
+	help
+	  This enables support for timestamping and PTP clock manipulations in
+	  the SJA1105 DSA driver.
diff --git a/drivers/net/dsa/sja1105/Makefile b/drivers/net/dsa/sja1105/Makefile
index 941848de8b46..946eea7d8480 100644
--- a/drivers/net/dsa/sja1105/Makefile
+++ b/drivers/net/dsa/sja1105/Makefile
@@ -1,5 +1,6 @@
 # SPDX-License-Identifier: GPL-2.0-only
 obj-$(CONFIG_NET_DSA_SJA1105) += sja1105.o
+obj-$(CONFIG_NET_DSA_SJA1105_PTP) += sja1105_ptp.o
 
 sja1105-objs := \
     sja1105_spi.o \
diff --git a/drivers/net/dsa/sja1105/sja1105.h b/drivers/net/dsa/sja1105/sja1105.h
index 61d00682de60..3c6296203c21 100644
--- a/drivers/net/dsa/sja1105/sja1105.h
+++ b/drivers/net/dsa/sja1105/sja1105.h
@@ -5,6 +5,8 @@
 #ifndef _SJA1105_H
 #define _SJA1105_H
 
+#include <linux/ptp_clock_kernel.h>
+#include <linux/timecounter.h>
 #include <linux/dsa/sja1105.h>
 #include <net/dsa.h>
 #include <linux/mutex.h>
@@ -27,6 +29,10 @@ struct sja1105_regs {
 	u64 rgu;
 	u64 config;
 	u64 rmii_pll1;
+	u64 ptp_control;
+	u64 ptpclk;
+	u64 ptpclkrate;
+	u64 ptptsclk;
 	u64 pad_mii_tx[SJA1105_NUM_PORTS];
 	u64 cgu_idiv[SJA1105_NUM_PORTS];
 	u64 rgmii_pad_mii_tx[SJA1105_NUM_PORTS];
@@ -53,6 +59,7 @@ struct sja1105_info {
 	const struct sja1105_dynamic_table_ops *dyn_ops;
 	const struct sja1105_table_ops *static_ops;
 	const struct sja1105_regs *regs;
+	int (*ptp_cmd)(const void *ctx, const void *data);
 	int (*reset_cmd)(const void *ctx, const void *data);
 	int (*setup_rgmii_delay)(const void *ctx, int port);
 	/* Prototypes from include/net/dsa.h */
@@ -72,6 +79,16 @@ struct sja1105_private {
 	struct spi_device *spidev;
 	struct dsa_switch *ds;
 	struct sja1105_port ports[SJA1105_NUM_PORTS];
+	struct ptp_clock_info ptp_caps;
+	struct ptp_clock *clock;
+	/* The cycle counter translates the PTP timestamps (based on
+	 * a free-running counter) into a software time domain.
+	 */
+	struct cyclecounter tstamp_cc;
+	struct timecounter tstamp_tc;
+	struct delayed_work refresh_work;
+	/* Serializes all operations on the cycle counter */
+	struct mutex ptp_lock;
 	/* Serializes transmission of management frames so that
 	 * the switch doesn't confuse them with one another.
 	 */
@@ -79,6 +96,7 @@ struct sja1105_private {
 };
 
 #include "sja1105_dynamic_config.h"
+#include "sja1105_ptp.h"
 
 struct sja1105_spi_message {
 	u64 access;
diff --git a/drivers/net/dsa/sja1105/sja1105_main.c b/drivers/net/dsa/sja1105/sja1105_main.c
index a30b89455421..5ed2adbf3505 100644
--- a/drivers/net/dsa/sja1105/sja1105_main.c
+++ b/drivers/net/dsa/sja1105/sja1105_main.c
@@ -1530,6 +1530,11 @@ static int sja1105_setup(struct dsa_switch *ds)
 		return rc;
 	}
 
+	rc = sja1105_ptp_clock_register(priv);
+	if (rc < 0) {
+		dev_err(ds->dev, "Failed to register PTP clock: %d\n", rc);
+		return rc;
+	}
 	/* Create and send configuration down to device */
 	rc = sja1105_static_config_load(priv, ports);
 	if (rc < 0) {
@@ -1681,6 +1686,7 @@ static const struct dsa_switch_ops sja1105_switch_ops = {
 	.get_strings		= sja1105_get_strings,
 	.get_ethtool_stats	= sja1105_get_ethtool_stats,
 	.get_sset_count		= sja1105_get_sset_count,
+	.get_ts_info		= sja1105_get_ts_info,
 	.port_fdb_dump		= sja1105_fdb_dump,
 	.port_fdb_add		= sja1105_fdb_add,
 	.port_fdb_del		= sja1105_fdb_del,
@@ -1805,6 +1811,7 @@ static int sja1105_remove(struct spi_device *spi)
 {
 	struct sja1105_private *priv = spi_get_drvdata(spi);
 
+	sja1105_ptp_clock_unregister(priv);
 	dsa_unregister_switch(priv->ds);
 	sja1105_static_config_free(&priv->static_config);
 	return 0;
diff --git a/drivers/net/dsa/sja1105/sja1105_ptp.c b/drivers/net/dsa/sja1105/sja1105_ptp.c
new file mode 100644
index 000000000000..5ffc985ad89a
--- /dev/null
+++ b/drivers/net/dsa/sja1105/sja1105_ptp.c
@@ -0,0 +1,286 @@
+// SPDX-License-Identifier: GPL-2.0
+/* Copyright (c) 2019, Vladimir Oltean <olteanv@gmail.com>
+ */
+#include "sja1105.h"
+
+/* The adjfine API clamps ppb between [-32,768,000, 32,768,000], and
+ * therefore scaled_ppm between [-2,147,483,648, 2,147,483,647].
+ * Set the maximum supported ppb to a round value smaller than the maximum.
+ *
+ * Percentually speaking, this is a +/- 0.032x adjustment of the
+ * free-running counter (0.968x to 1.032x).
+ */
+#define SJA1105_MAX_ADJ_PPB		32000000
+#define SJA1105_SIZE_PTP_CMD		4
+
+/* Timestamps are in units of 8 ns clock ticks (equivalent to a fixed
+ * 125 MHz clock) so the scale factor (MULT / SHIFT) needs to be 8.
+ * Furthermore, wisely pick SHIFT as 28 bits, which translates
+ * MULT into 2^31 (0x80000000).  This is the same value around which
+ * the hardware PTPCLKRATE is centered, so the same ppb conversion
+ * arithmetic can be reused.
+ */
+#define SJA1105_CC_SHIFT		28
+#define SJA1105_CC_MULT			(8 << SJA1105_CC_SHIFT)
+
+/* Having 33 bits of cycle counter left until a 64-bit overflow during delta
+ * conversion, we multiply this by the 8 ns counter resolution and arrive at
+ * a comfortable 68.71 second refresh interval until the delta would cause
+ * an integer overflow, in absence of any other readout.
+ * Approximate to 1 minute.
+ */
+#define SJA1105_REFRESH_INTERVAL	(HZ * 60)
+
+/*            This range is actually +/- SJA1105_MAX_ADJ_PPB
+ *            divided by 1000 (ppb -> ppm) and with a 16-bit
+ *            "fractional" part (actually fixed point).
+ *                                    |
+ *                                    v
+ * Convert scaled_ppm from the +/- ((10^6) << 16) range
+ * into the +/- (1 << 31) range.
+ *
+ * This forgoes a "ppb" numeric representation (up to NSEC_PER_SEC)
+ * and defines the scaling factor between scaled_ppm and the actual
+ * frequency adjustments (both cycle counter and hardware).
+ *
+ *   ptpclkrate = scaled_ppm * 2^31 / (10^6 * 2^16)
+ *   simplifies to
+ *   ptpclkrate = scaled_ppm * 2^9 / 5^6
+ */
+#define SJA1105_CC_MULT_NUM		(1 << 9)
+#define SJA1105_CC_MULT_DEM		15625
+
+#define ptp_to_sja1105(d) container_of((d), struct sja1105_private, ptp_caps)
+#define cc_to_sja1105(d) container_of((d), struct sja1105_private, tstamp_cc)
+#define dw_to_sja1105(d) container_of((d), struct sja1105_private, refresh_work)
+
+struct sja1105_ptp_cmd {
+	u64 resptp;       /* reset */
+};
+
+int sja1105_get_ts_info(struct dsa_switch *ds, int port,
+			struct ethtool_ts_info *info)
+{
+	struct sja1105_private *priv = ds->priv;
+
+	/* Called during cleanup */
+	if (!priv->clock)
+		return -ENODEV;
+
+	info->so_timestamping = SOF_TIMESTAMPING_TX_HARDWARE |
+				SOF_TIMESTAMPING_RX_HARDWARE |
+				SOF_TIMESTAMPING_RAW_HARDWARE;
+	info->tx_types = (1 << HWTSTAMP_TX_OFF);
+	info->rx_filters = (1 << HWTSTAMP_FILTER_NONE);
+	info->phc_index = ptp_clock_index(priv->clock);
+	return 0;
+}
+
+int sja1105et_ptp_cmd(const void *ctx, const void *data)
+{
+	const struct sja1105_ptp_cmd *cmd = data;
+	const struct sja1105_private *priv = ctx;
+	const struct sja1105_regs *regs = priv->info->regs;
+	const int size = SJA1105_SIZE_PTP_CMD;
+	u8 buf[SJA1105_SIZE_PTP_CMD] = {0};
+	/* No need to keep this as part of the structure */
+	u64 valid = 1;
+
+	sja1105_pack(buf, &valid,           31, 31, size);
+	sja1105_pack(buf, &cmd->resptp,      2,  2, size);
+
+	return sja1105_spi_send_packed_buf(priv, SPI_WRITE, regs->ptp_control,
+					   buf, SJA1105_SIZE_PTP_CMD);
+}
+
+int sja1105pqrs_ptp_cmd(const void *ctx, const void *data)
+{
+	const struct sja1105_ptp_cmd *cmd = data;
+	const struct sja1105_private *priv = ctx;
+	const struct sja1105_regs *regs = priv->info->regs;
+	const int size = SJA1105_SIZE_PTP_CMD;
+	u8 buf[SJA1105_SIZE_PTP_CMD] = {0};
+	/* No need to keep this as part of the structure */
+	u64 valid = 1;
+
+	sja1105_pack(buf, &valid,           31, 31, size);
+	sja1105_pack(buf, &cmd->resptp,      3,  3, size);
+
+	return sja1105_spi_send_packed_buf(priv, SPI_WRITE, regs->ptp_control,
+					   buf, SJA1105_SIZE_PTP_CMD);
+}
+
+int sja1105_ptp_reset(struct sja1105_private *priv)
+{
+	struct dsa_switch *ds = priv->ds;
+	struct sja1105_ptp_cmd cmd = {0};
+	int rc;
+
+	mutex_lock(&priv->ptp_lock);
+
+	cmd.resptp = 1;
+	dev_dbg(ds->dev, "Resetting PTP clock\n");
+	rc = priv->info->ptp_cmd(priv, &cmd);
+
+	timecounter_init(&priv->tstamp_tc, &priv->tstamp_cc,
+			 ktime_to_ns(ktime_get_real()));
+
+	mutex_unlock(&priv->ptp_lock);
+
+	return rc;
+}
+
+static int sja1105_ptp_gettime(struct ptp_clock_info *ptp,
+			       struct timespec64 *ts)
+{
+	struct sja1105_private *priv = ptp_to_sja1105(ptp);
+	u64 ns;
+
+	mutex_lock(&priv->ptp_lock);
+	ns = timecounter_read(&priv->tstamp_tc);
+	mutex_unlock(&priv->ptp_lock);
+
+	*ts = ns_to_timespec64(ns);
+
+	return 0;
+}
+
+static int sja1105_ptp_settime(struct ptp_clock_info *ptp,
+			       const struct timespec64 *ts)
+{
+	struct sja1105_private *priv = ptp_to_sja1105(ptp);
+	u64 ns = timespec64_to_ns(ts);
+
+	mutex_lock(&priv->ptp_lock);
+	timecounter_init(&priv->tstamp_tc, &priv->tstamp_cc, ns);
+	mutex_unlock(&priv->ptp_lock);
+
+	return 0;
+}
+
+static int sja1105_ptp_adjfine(struct ptp_clock_info *ptp, long scaled_ppm)
+{
+	struct sja1105_private *priv = ptp_to_sja1105(ptp);
+	s64 clkrate;
+
+	clkrate = (s64)scaled_ppm * SJA1105_CC_MULT_NUM;
+	clkrate = div_s64(clkrate, SJA1105_CC_MULT_DEM);
+
+	mutex_lock(&priv->ptp_lock);
+
+	/* Force a readout to update the timer *before* changing its frequency.
+	 *
+	 * This way, its corrected time curve can at all times be modeled
+	 * as a linear "A * x + B" function, where:
+	 *
+	 * - B are past frequency adjustments and offset shifts, all
+	 *   accumulated into the cycle_last variable.
+	 *
+	 * - A is the new frequency adjustments we're just about to set.
+	 *
+	 * Reading now makes B accumulate the correct amount of time,
+	 * corrected at the old rate, before changing it.
+	 *
+	 * Hardware timestamps then become simple points on the curve and
+	 * are approximated using the above function.  This is still better
+	 * than letting the switch take the timestamps using the hardware
+	 * rate-corrected clock (PTPCLKVAL) - the comparison in this case would
+	 * be that we're shifting the ruler at the same time as we're taking
+	 * measurements with it.
+	 *
+	 * The disadvantage is that it's possible to receive timestamps when
+	 * a frequency adjustment took place in the near past.
+	 * In this case they will be approximated using the new ppb value
+	 * instead of a compound function made of two segments (one at the old
+	 * and the other at the new rate) - introducing some inaccuracy.
+	 */
+	timecounter_read(&priv->tstamp_tc);
+
+	priv->tstamp_cc.mult = SJA1105_CC_MULT + clkrate;
+
+	mutex_unlock(&priv->ptp_lock);
+
+	return 0;
+}
+
+static int sja1105_ptp_adjtime(struct ptp_clock_info *ptp, s64 delta)
+{
+	struct sja1105_private *priv = ptp_to_sja1105(ptp);
+
+	mutex_lock(&priv->ptp_lock);
+	timecounter_adjtime(&priv->tstamp_tc, delta);
+	mutex_unlock(&priv->ptp_lock);
+
+	return 0;
+}
+
+static u64 sja1105_ptptsclk_read(const struct cyclecounter *cc)
+{
+	struct sja1105_private *priv = cc_to_sja1105(cc);
+	const struct sja1105_regs *regs = priv->info->regs;
+	u64 ptptsclk = 0;
+	int rc;
+
+	rc = sja1105_spi_send_int(priv, SPI_READ, regs->ptptsclk,
+				  &ptptsclk, 8);
+	if (rc < 0)
+		dev_err_ratelimited(priv->ds->dev,
+				    "failed to read ptp cycle counter: %d\n",
+				    rc);
+	return ptptsclk;
+}
+
+static void sja1105_ptp_overflow_check(struct work_struct *work)
+{
+	struct delayed_work *dw = to_delayed_work(work);
+	struct sja1105_private *priv = dw_to_sja1105(dw);
+	struct timespec64 ts;
+
+	sja1105_ptp_gettime(&priv->ptp_caps, &ts);
+
+	schedule_delayed_work(&priv->refresh_work, SJA1105_REFRESH_INTERVAL);
+}
+
+static const struct ptp_clock_info sja1105_ptp_caps = {
+	.owner		= THIS_MODULE,
+	.name		= "SJA1105 PHC",
+	.adjfine	= sja1105_ptp_adjfine,
+	.adjtime	= sja1105_ptp_adjtime,
+	.gettime64	= sja1105_ptp_gettime,
+	.settime64	= sja1105_ptp_settime,
+	.max_adj	= SJA1105_MAX_ADJ_PPB,
+};
+
+int sja1105_ptp_clock_register(struct sja1105_private *priv)
+{
+	struct dsa_switch *ds = priv->ds;
+
+	/* Set up the cycle counter */
+	priv->tstamp_cc = (struct cyclecounter) {
+		.read = sja1105_ptptsclk_read,
+		.mask = CYCLECOUNTER_MASK(64),
+		.shift = SJA1105_CC_SHIFT,
+		.mult = SJA1105_CC_MULT,
+	};
+	mutex_init(&priv->ptp_lock);
+	INIT_DELAYED_WORK(&priv->refresh_work, sja1105_ptp_overflow_check);
+
+	schedule_delayed_work(&priv->refresh_work, SJA1105_REFRESH_INTERVAL);
+
+	priv->ptp_caps = sja1105_ptp_caps;
+
+	priv->clock = ptp_clock_register(&priv->ptp_caps, ds->dev);
+	if (IS_ERR_OR_NULL(priv->clock))
+		return PTR_ERR(priv->clock);
+
+	return sja1105_ptp_reset(priv);
+}
+
+void sja1105_ptp_clock_unregister(struct sja1105_private *priv)
+{
+	if (IS_ERR_OR_NULL(priv->clock))
+		return;
+
+	ptp_clock_unregister(priv->clock);
+	priv->clock = NULL;
+}
diff --git a/drivers/net/dsa/sja1105/sja1105_ptp.h b/drivers/net/dsa/sja1105/sja1105_ptp.h
new file mode 100644
index 000000000000..137ffbb0a233
--- /dev/null
+++ b/drivers/net/dsa/sja1105/sja1105_ptp.h
@@ -0,0 +1,47 @@
+/* SPDX-License-Identifier: GPL-2.0
+ * Copyright (c) 2019, Vladimir Oltean <olteanv@gmail.com>
+ */
+#ifndef _SJA1105_PTP_H
+#define _SJA1105_PTP_H
+
+#if IS_ENABLED(CONFIG_NET_DSA_SJA1105_PTP)
+
+int sja1105_ptp_clock_register(struct sja1105_private *priv);
+
+void sja1105_ptp_clock_unregister(struct sja1105_private *priv);
+
+int sja1105et_ptp_cmd(const void *ctx, const void *data);
+
+int sja1105pqrs_ptp_cmd(const void *ctx, const void *data);
+
+int sja1105_get_ts_info(struct dsa_switch *ds, int port,
+			struct ethtool_ts_info *ts);
+
+int sja1105_ptp_reset(struct sja1105_private *priv);
+
+#else
+
+static inline int sja1105_ptp_clock_register(struct sja1105_private *priv)
+{
+	return 0;
+}
+
+static inline void sja1105_ptp_clock_unregister(struct sja1105_private *priv)
+{
+	return;
+}
+
+static inline int sja1105_ptp_reset(struct sja1105_private *priv)
+{
+	return 0;
+}
+
+#define sja1105et_ptp_cmd NULL
+
+#define sja1105pqrs_ptp_cmd NULL
+
+#define sja1105_get_ts_info NULL
+
+#endif /* IS_ENABLED(CONFIG_NET_DSA_SJA1105_PTP) */
+
+#endif /* _SJA1105_PTP_H */
diff --git a/drivers/net/dsa/sja1105/sja1105_spi.c b/drivers/net/dsa/sja1105/sja1105_spi.c
index b1344ed1697f..d226996881b8 100644
--- a/drivers/net/dsa/sja1105/sja1105_spi.c
+++ b/drivers/net/dsa/sja1105/sja1105_spi.c
@@ -478,7 +478,12 @@ int sja1105_static_config_upload(struct sja1105_private *priv)
 		dev_info(dev, "Succeeded after %d tried\n", RETRIES - retries);
 	}
 
+	rc = sja1105_ptp_reset(priv);
+	if (rc < 0)
+		dev_err(dev, "Failed to reset PTP clock: %d\n", rc);
+
 	dev_info(dev, "Reset switch and programmed static config\n");
+
 out:
 	kfree(config_buf);
 	return rc;
@@ -507,6 +512,10 @@ static struct sja1105_regs sja1105et_regs = {
 	.rgmii_tx_clk = {0x100016, 0x10001D, 0x100024, 0x10002B, 0x100032},
 	.rmii_ref_clk = {0x100015, 0x10001C, 0x100023, 0x10002A, 0x100031},
 	.rmii_ext_tx_clk = {0x100018, 0x10001F, 0x100026, 0x10002D, 0x100034},
+	.ptp_control = 0x17,
+	.ptpclk = 0x18, /* Spans 0x18 to 0x19 */
+	.ptpclkrate = 0x1A,
+	.ptptsclk = 0x1B, /* Spans 0x1B to 0x1C */
 };
 
 static struct sja1105_regs sja1105pqrs_regs = {
@@ -533,6 +542,10 @@ static struct sja1105_regs sja1105pqrs_regs = {
 	.rmii_ref_clk = {0x100015, 0x10001B, 0x100021, 0x100027, 0x10002D},
 	.rmii_ext_tx_clk = {0x100017, 0x10001D, 0x100023, 0x100029, 0x10002F},
 	.qlevel = {0x604, 0x614, 0x624, 0x634, 0x644},
+	.ptp_control = 0x18,
+	.ptpclk = 0x19,
+	.ptpclkrate = 0x1B,
+	.ptptsclk = 0x1C,
 };
 
 struct sja1105_info sja1105e_info = {
@@ -543,6 +556,7 @@ struct sja1105_info sja1105e_info = {
 	.reset_cmd		= sja1105et_reset_cmd,
 	.fdb_add_cmd		= sja1105et_fdb_add,
 	.fdb_del_cmd		= sja1105et_fdb_del,
+	.ptp_cmd		= sja1105et_ptp_cmd,
 	.regs			= &sja1105et_regs,
 	.name			= "SJA1105E",
 };
@@ -554,6 +568,7 @@ struct sja1105_info sja1105t_info = {
 	.reset_cmd		= sja1105et_reset_cmd,
 	.fdb_add_cmd		= sja1105et_fdb_add,
 	.fdb_del_cmd		= sja1105et_fdb_del,
+	.ptp_cmd		= sja1105et_ptp_cmd,
 	.regs			= &sja1105et_regs,
 	.name			= "SJA1105T",
 };
@@ -565,6 +580,7 @@ struct sja1105_info sja1105p_info = {
 	.reset_cmd		= sja1105pqrs_reset_cmd,
 	.fdb_add_cmd		= sja1105pqrs_fdb_add,
 	.fdb_del_cmd		= sja1105pqrs_fdb_del,
+	.ptp_cmd		= sja1105pqrs_ptp_cmd,
 	.regs			= &sja1105pqrs_regs,
 	.name			= "SJA1105P",
 };
@@ -576,6 +592,7 @@ struct sja1105_info sja1105q_info = {
 	.reset_cmd		= sja1105pqrs_reset_cmd,
 	.fdb_add_cmd		= sja1105pqrs_fdb_add,
 	.fdb_del_cmd		= sja1105pqrs_fdb_del,
+	.ptp_cmd		= sja1105pqrs_ptp_cmd,
 	.regs			= &sja1105pqrs_regs,
 	.name			= "SJA1105Q",
 };
@@ -587,6 +604,7 @@ struct sja1105_info sja1105r_info = {
 	.reset_cmd		= sja1105pqrs_reset_cmd,
 	.fdb_add_cmd		= sja1105pqrs_fdb_add,
 	.fdb_del_cmd		= sja1105pqrs_fdb_del,
+	.ptp_cmd		= sja1105pqrs_ptp_cmd,
 	.regs			= &sja1105pqrs_regs,
 	.name			= "SJA1105R",
 };
@@ -599,5 +617,6 @@ struct sja1105_info sja1105s_info = {
 	.reset_cmd		= sja1105pqrs_reset_cmd,
 	.fdb_add_cmd		= sja1105pqrs_fdb_add,
 	.fdb_del_cmd		= sja1105pqrs_fdb_del,
+	.ptp_cmd		= sja1105pqrs_ptp_cmd,
 	.name			= "SJA1105S",
 };
-- 
2.17.1


^ permalink raw reply related	[flat|nested] 40+ messages in thread

* [PATCH v3 net-next 08/17] net: dsa: sja1105: Move sja1105_is_link_local to include/linux
  2019-06-04 17:07 [PATCH v3 net-next 00/17] PTP support for the SJA1105 DSA driver Vladimir Oltean
                   ` (6 preceding siblings ...)
  2019-06-04 17:07 ` [PATCH v3 net-next 07/17] net: dsa: sja1105: Add support for the PTP clock Vladimir Oltean
@ 2019-06-04 17:07 ` Vladimir Oltean
  2019-06-04 20:35   ` Florian Fainelli
  2019-06-04 17:07 ` [PATCH v3 net-next 09/17] net: dsa: sja1105: Add logic for TX timestamping Vladimir Oltean
                   ` (9 subsequent siblings)
  17 siblings, 1 reply; 40+ messages in thread
From: Vladimir Oltean @ 2019-06-04 17:07 UTC (permalink / raw)
  To: f.fainelli, vivien.didelot, andrew, davem, richardcochran,
	john.stultz, tglx, sboyd
  Cc: linux-kernel, netdev, Vladimir Oltean

This function will be reused from the .port_rxtstamp callback to see if
the received SKB can be timestamped by the switch.

Signed-off-by: Vladimir Oltean <olteanv@gmail.com>
---
Changes in v3:

None.

Changes in v2:

Patch is new.

 include/linux/dsa/sja1105.h | 15 +++++++++++++++
 net/dsa/tag_sja1105.c       | 15 ---------------
 2 files changed, 15 insertions(+), 15 deletions(-)

diff --git a/include/linux/dsa/sja1105.h b/include/linux/dsa/sja1105.h
index e46e18c47d41..f3237afed35a 100644
--- a/include/linux/dsa/sja1105.h
+++ b/include/linux/dsa/sja1105.h
@@ -25,4 +25,19 @@ struct sja1105_port {
 	int mgmt_slot;
 };
 
+/* Similar to is_link_local_ether_addr(hdr->h_dest) but also covers PTP */
+static inline bool sja1105_is_link_local(const struct sk_buff *skb)
+{
+	const struct ethhdr *hdr = eth_hdr(skb);
+	u64 dmac = ether_addr_to_u64(hdr->h_dest);
+
+	if ((dmac & SJA1105_LINKLOCAL_FILTER_A_MASK) ==
+		    SJA1105_LINKLOCAL_FILTER_A)
+		return true;
+	if ((dmac & SJA1105_LINKLOCAL_FILTER_B_MASK) ==
+		    SJA1105_LINKLOCAL_FILTER_B)
+		return true;
+	return false;
+}
+
 #endif /* _NET_DSA_SJA1105_H */
diff --git a/net/dsa/tag_sja1105.c b/net/dsa/tag_sja1105.c
index b35cf5c2d01c..7a56a27a1fd2 100644
--- a/net/dsa/tag_sja1105.c
+++ b/net/dsa/tag_sja1105.c
@@ -7,21 +7,6 @@
 #include <linux/packing.h>
 #include "dsa_priv.h"
 
-/* Similar to is_link_local_ether_addr(hdr->h_dest) but also covers PTP */
-static inline bool sja1105_is_link_local(const struct sk_buff *skb)
-{
-	const struct ethhdr *hdr = eth_hdr(skb);
-	u64 dmac = ether_addr_to_u64(hdr->h_dest);
-
-	if ((dmac & SJA1105_LINKLOCAL_FILTER_A_MASK) ==
-		    SJA1105_LINKLOCAL_FILTER_A)
-		return true;
-	if ((dmac & SJA1105_LINKLOCAL_FILTER_B_MASK) ==
-		    SJA1105_LINKLOCAL_FILTER_B)
-		return true;
-	return false;
-}
-
 /* This is the first time the tagger sees the frame on RX.
  * Figure out if we can decode it, and if we can, annotate skb->cb with how we
  * plan to do that, so we don't need to check again in the rcv function.
-- 
2.17.1


^ permalink raw reply related	[flat|nested] 40+ messages in thread

* [PATCH v3 net-next 09/17] net: dsa: sja1105: Add logic for TX timestamping
  2019-06-04 17:07 [PATCH v3 net-next 00/17] PTP support for the SJA1105 DSA driver Vladimir Oltean
                   ` (7 preceding siblings ...)
  2019-06-04 17:07 ` [PATCH v3 net-next 08/17] net: dsa: sja1105: Move sja1105_is_link_local to include/linux Vladimir Oltean
@ 2019-06-04 17:07 ` Vladimir Oltean
  2019-06-04 17:07 ` [PATCH v3 net-next 10/17] net: dsa: sja1105: Build a minimal understanding of meta frames Vladimir Oltean
                   ` (8 subsequent siblings)
  17 siblings, 0 replies; 40+ messages in thread
From: Vladimir Oltean @ 2019-06-04 17:07 UTC (permalink / raw)
  To: f.fainelli, vivien.didelot, andrew, davem, richardcochran,
	john.stultz, tglx, sboyd
  Cc: linux-kernel, netdev, Vladimir Oltean

On TX, timestamping is performed synchronously from the
port_deferred_xmit worker thread.
In management routes, the switch is requested to take egress timestamps
(again partial), which are reconstructed and appended to a clone of the
skb that was just sent.  The cloning is done by DSA and we retrieve the
pointer from the structure that DSA keeps in skb->cb.
Then these clones are enqueued to the socket's error queue for
application-level processing.

Signed-off-by: Vladimir Oltean <olteanv@gmail.com>
---
Changes in v3:

Split from previous 09/10 patch (no functional changes).

Changes in v2:

None.

 drivers/net/dsa/sja1105/sja1105.h      |  10 +++
 drivers/net/dsa/sja1105/sja1105_main.c |  55 ++++++++++++-
 drivers/net/dsa/sja1105/sja1105_ptp.c  | 104 +++++++++++++++++++++++++
 drivers/net/dsa/sja1105/sja1105_ptp.h  |  17 ++++
 drivers/net/dsa/sja1105/sja1105_spi.c  |  14 ++++
 include/linux/dsa/sja1105.h            |   1 +
 6 files changed, 199 insertions(+), 2 deletions(-)

diff --git a/drivers/net/dsa/sja1105/sja1105.h b/drivers/net/dsa/sja1105/sja1105.h
index 3c6296203c21..5a4f83a3417b 100644
--- a/drivers/net/dsa/sja1105/sja1105.h
+++ b/drivers/net/dsa/sja1105/sja1105.h
@@ -33,6 +33,7 @@ struct sja1105_regs {
 	u64 ptpclk;
 	u64 ptpclkrate;
 	u64 ptptsclk;
+	u64 ptpegr_ts[SJA1105_NUM_PORTS];
 	u64 pad_mii_tx[SJA1105_NUM_PORTS];
 	u64 cgu_idiv[SJA1105_NUM_PORTS];
 	u64 rgmii_pad_mii_tx[SJA1105_NUM_PORTS];
@@ -56,6 +57,15 @@ struct sja1105_info {
 	 * switch core and device_id)
 	 */
 	u64 part_no;
+	/* E/T and P/Q/R/S have partial timestamps of different sizes.
+	 * They must be reconstructed on both families anyway to get the full
+	 * 64-bit values back.
+	 */
+	int ptp_ts_bits;
+	/* Also SPI commands are of different sizes to retrieve
+	 * the egress timestamps.
+	 */
+	int ptpegr_ts_bytes;
 	const struct sja1105_dynamic_table_ops *dyn_ops;
 	const struct sja1105_table_ops *static_ops;
 	const struct sja1105_regs *regs;
diff --git a/drivers/net/dsa/sja1105/sja1105_main.c b/drivers/net/dsa/sja1105/sja1105_main.c
index 5ed2adbf3505..45c65e77b61d 100644
--- a/drivers/net/dsa/sja1105/sja1105_main.c
+++ b/drivers/net/dsa/sja1105/sja1105_main.c
@@ -1565,7 +1565,7 @@ static int sja1105_setup(struct dsa_switch *ds)
 }
 
 static int sja1105_mgmt_xmit(struct dsa_switch *ds, int port, int slot,
-			     struct sk_buff *skb)
+			     struct sk_buff *skb, bool takets)
 {
 	struct sja1105_mgmt_entry mgmt_route = {0};
 	struct sja1105_private *priv = ds->priv;
@@ -1578,6 +1578,8 @@ static int sja1105_mgmt_xmit(struct dsa_switch *ds, int port, int slot,
 	mgmt_route.macaddr = ether_addr_to_u64(hdr->h_dest);
 	mgmt_route.destports = BIT(port);
 	mgmt_route.enfport = 1;
+	mgmt_route.tsreg = 0;
+	mgmt_route.takets = takets;
 
 	rc = sja1105_dynamic_config_write(priv, BLK_IDX_MGMT_ROUTE,
 					  slot, &mgmt_route, true);
@@ -1629,7 +1631,11 @@ static netdev_tx_t sja1105_port_deferred_xmit(struct dsa_switch *ds, int port,
 {
 	struct sja1105_private *priv = ds->priv;
 	struct sja1105_port *sp = &priv->ports[port];
+	struct skb_shared_hwtstamps shwt = {0};
 	int slot = sp->mgmt_slot;
+	struct sk_buff *clone;
+	u64 now, ts;
+	int rc;
 
 	/* The tragic fact about the switch having 4x2 slots for installing
 	 * management routes is that all of them except one are actually
@@ -1647,8 +1653,36 @@ static netdev_tx_t sja1105_port_deferred_xmit(struct dsa_switch *ds, int port,
 	 */
 	mutex_lock(&priv->mgmt_lock);
 
-	sja1105_mgmt_xmit(ds, port, slot, skb);
+	/* The clone, if there, was made by dsa_skb_tx_timestamp */
+	clone = DSA_SKB_CB(skb)->clone;
+
+	sja1105_mgmt_xmit(ds, port, slot, skb, !!clone);
+
+	if (!clone)
+		goto out;
+
+	skb_shinfo(clone)->tx_flags |= SKBTX_IN_PROGRESS;
+
+	mutex_lock(&priv->ptp_lock);
+
+	now = priv->tstamp_cc.read(&priv->tstamp_cc);
+
+	rc = sja1105_ptpegr_ts_poll(priv, slot, &ts);
+	if (rc < 0) {
+		dev_err(ds->dev, "xmit: timed out polling for tstamp\n");
+		kfree_skb(clone);
+		goto out_unlock_ptp;
+	}
+
+	ts = sja1105_tstamp_reconstruct(priv, now, ts);
+	ts = timecounter_cyc2time(&priv->tstamp_tc, ts);
 
+	shwt.hwtstamp = ns_to_ktime(ts);
+	skb_complete_tx_timestamp(clone, &shwt);
+
+out_unlock_ptp:
+	mutex_unlock(&priv->ptp_lock);
+out:
 	mutex_unlock(&priv->mgmt_lock);
 	return NETDEV_TX_OK;
 }
@@ -1677,6 +1711,22 @@ static int sja1105_set_ageing_time(struct dsa_switch *ds,
 	return sja1105_static_config_reload(priv);
 }
 
+/* Called from dsa_skb_tx_timestamp. This callback is just to make DSA clone
+ * the skb and have it available in DSA_SKB_CB in the .port_deferred_xmit
+ * callback, where we will timestamp it synchronously.
+ */
+bool sja1105_port_txtstamp(struct dsa_switch *ds, int port,
+			   struct sk_buff *skb, unsigned int type)
+{
+	struct sja1105_private *priv = ds->priv;
+	struct sja1105_port *sp = &priv->ports[port];
+
+	if (!sp->hwts_tx_en)
+		return false;
+
+	return true;
+}
+
 static const struct dsa_switch_ops sja1105_switch_ops = {
 	.get_tag_protocol	= sja1105_get_tag_protocol,
 	.setup			= sja1105_setup,
@@ -1701,6 +1751,7 @@ static const struct dsa_switch_ops sja1105_switch_ops = {
 	.port_mdb_add		= sja1105_mdb_add,
 	.port_mdb_del		= sja1105_mdb_del,
 	.port_deferred_xmit	= sja1105_port_deferred_xmit,
+	.port_txtstamp		= sja1105_port_txtstamp,
 };
 
 static int sja1105_check_device_id(struct sja1105_private *priv)
diff --git a/drivers/net/dsa/sja1105/sja1105_ptp.c b/drivers/net/dsa/sja1105/sja1105_ptp.c
index 5ffc985ad89a..1fce413a3fb4 100644
--- a/drivers/net/dsa/sja1105/sja1105_ptp.c
+++ b/drivers/net/dsa/sja1105/sja1105_ptp.c
@@ -110,6 +110,110 @@ int sja1105pqrs_ptp_cmd(const void *ctx, const void *data)
 					   buf, SJA1105_SIZE_PTP_CMD);
 }
 
+/* The switch returns partial timestamps (24 bits for SJA1105 E/T, which wrap
+ * around in 0.135 seconds, and 32 bits for P/Q/R/S, wrapping around in 34.35
+ * seconds).
+ *
+ * This receives the RX or TX MAC timestamps, provided by hardware as
+ * the lower bits of the cycle counter, sampled at the time the timestamp was
+ * collected.
+ *
+ * To reconstruct into a full 64-bit-wide timestamp, the cycle counter is
+ * read and the high-order bits are filled in.
+ *
+ * Must be called within one wraparound period of the partial timestamp since
+ * it was generated by the MAC.
+ */
+u64 sja1105_tstamp_reconstruct(struct sja1105_private *priv, u64 now,
+			       u64 ts_partial)
+{
+	u64 partial_tstamp_mask = CYCLECOUNTER_MASK(priv->info->ptp_ts_bits);
+	u64 ts_reconstructed;
+
+	ts_reconstructed = (now & ~partial_tstamp_mask) | ts_partial;
+
+	/* Check lower bits of current cycle counter against the timestamp.
+	 * If the current cycle counter is lower than the partial timestamp,
+	 * then wraparound surely occurred and must be accounted for.
+	 */
+	if ((now & partial_tstamp_mask) <= ts_partial)
+		ts_reconstructed -= (partial_tstamp_mask + 1);
+
+	return ts_reconstructed;
+}
+
+/* Reads the SPI interface for an egress timestamp generated by the switch
+ * for frames sent using management routes.
+ *
+ * SJA1105 E/T layout of the 4-byte SPI payload:
+ *
+ * 31    23    15    7     0
+ * |     |     |     |     |
+ * +-----+-----+-----+     ^
+ *          ^              |
+ *          |              |
+ *  24-bit timestamp   Update bit
+ *
+ *
+ * SJA1105 P/Q/R/S layout of the 8-byte SPI payload:
+ *
+ * 31    23    15    7     0     63    55    47    39    32
+ * |     |     |     |     |     |     |     |     |     |
+ *                         ^     +-----+-----+-----+-----+
+ *                         |                 ^
+ *                         |                 |
+ *                    Update bit    32-bit timestamp
+ *
+ * Notice that the update bit is in the same place.
+ * To have common code for E/T and P/Q/R/S for reading the timestamp,
+ * we need to juggle with the offset and the bit indices.
+ */
+int sja1105_ptpegr_ts_poll(struct sja1105_private *priv, int port, u64 *ts)
+{
+	const struct sja1105_regs *regs = priv->info->regs;
+	int tstamp_bit_start, tstamp_bit_end;
+	int timeout = 10;
+	u8 packed_buf[8];
+	u64 update;
+	int rc;
+
+	do {
+		rc = sja1105_spi_send_packed_buf(priv, SPI_READ,
+						 regs->ptpegr_ts[port],
+						 packed_buf,
+						 priv->info->ptpegr_ts_bytes);
+		if (rc < 0)
+			return rc;
+
+		sja1105_unpack(packed_buf, &update, 0, 0,
+			       priv->info->ptpegr_ts_bytes);
+		if (update)
+			break;
+
+		usleep_range(10, 50);
+	} while (--timeout);
+
+	if (!timeout)
+		return -ETIMEDOUT;
+
+	/* Point the end bit to the second 32-bit word on P/Q/R/S,
+	 * no-op on E/T.
+	 */
+	tstamp_bit_end = (priv->info->ptpegr_ts_bytes - 4) * 8;
+	/* Shift the 24-bit timestamp on E/T to be collected from 31:8.
+	 * No-op on P/Q/R/S.
+	 */
+	tstamp_bit_end += 32 - priv->info->ptp_ts_bits;
+	tstamp_bit_start = tstamp_bit_end + priv->info->ptp_ts_bits - 1;
+
+	*ts = 0;
+
+	sja1105_unpack(packed_buf, ts, tstamp_bit_start, tstamp_bit_end,
+		       priv->info->ptpegr_ts_bytes);
+
+	return 0;
+}
+
 int sja1105_ptp_reset(struct sja1105_private *priv)
 {
 	struct dsa_switch *ds = priv->ds;
diff --git a/drivers/net/dsa/sja1105/sja1105_ptp.h b/drivers/net/dsa/sja1105/sja1105_ptp.h
index 137ffbb0a233..af456b0a4d27 100644
--- a/drivers/net/dsa/sja1105/sja1105_ptp.h
+++ b/drivers/net/dsa/sja1105/sja1105_ptp.h
@@ -10,6 +10,8 @@ int sja1105_ptp_clock_register(struct sja1105_private *priv);
 
 void sja1105_ptp_clock_unregister(struct sja1105_private *priv);
 
+int sja1105_ptpegr_ts_poll(struct sja1105_private *priv, int port, u64 *ts);
+
 int sja1105et_ptp_cmd(const void *ctx, const void *data);
 
 int sja1105pqrs_ptp_cmd(const void *ctx, const void *data);
@@ -17,6 +19,9 @@ int sja1105pqrs_ptp_cmd(const void *ctx, const void *data);
 int sja1105_get_ts_info(struct dsa_switch *ds, int port,
 			struct ethtool_ts_info *ts);
 
+u64 sja1105_tstamp_reconstruct(struct sja1105_private *priv, u64 now,
+			       u64 ts_partial);
+
 int sja1105_ptp_reset(struct sja1105_private *priv);
 
 #else
@@ -31,6 +36,18 @@ static inline void sja1105_ptp_clock_unregister(struct sja1105_private *priv)
 	return;
 }
 
+static inline int
+sja1105_ptpegr_ts_poll(struct sja1105_private *priv, int port, u64 *ts)
+{
+	return 0;
+}
+
+static inline u64 sja1105_tstamp_reconstruct(struct sja1105_private *priv,
+					     u64 now, u64 ts_partial)
+{
+	return 0;
+}
+
 static inline int sja1105_ptp_reset(struct sja1105_private *priv)
 {
 	return 0;
diff --git a/drivers/net/dsa/sja1105/sja1105_spi.c b/drivers/net/dsa/sja1105/sja1105_spi.c
index d226996881b8..a71b16c5ae5d 100644
--- a/drivers/net/dsa/sja1105/sja1105_spi.c
+++ b/drivers/net/dsa/sja1105/sja1105_spi.c
@@ -512,6 +512,7 @@ static struct sja1105_regs sja1105et_regs = {
 	.rgmii_tx_clk = {0x100016, 0x10001D, 0x100024, 0x10002B, 0x100032},
 	.rmii_ref_clk = {0x100015, 0x10001C, 0x100023, 0x10002A, 0x100031},
 	.rmii_ext_tx_clk = {0x100018, 0x10001F, 0x100026, 0x10002D, 0x100034},
+	.ptpegr_ts = {0xC0, 0xC2, 0xC4, 0xC6, 0xC8},
 	.ptp_control = 0x17,
 	.ptpclk = 0x18, /* Spans 0x18 to 0x19 */
 	.ptpclkrate = 0x1A,
@@ -542,6 +543,7 @@ static struct sja1105_regs sja1105pqrs_regs = {
 	.rmii_ref_clk = {0x100015, 0x10001B, 0x100021, 0x100027, 0x10002D},
 	.rmii_ext_tx_clk = {0x100017, 0x10001D, 0x100023, 0x100029, 0x10002F},
 	.qlevel = {0x604, 0x614, 0x624, 0x634, 0x644},
+	.ptpegr_ts = {0xC0, 0xC4, 0xC8, 0xCC, 0xD0},
 	.ptp_control = 0x18,
 	.ptpclk = 0x19,
 	.ptpclkrate = 0x1B,
@@ -553,6 +555,8 @@ struct sja1105_info sja1105e_info = {
 	.part_no		= SJA1105ET_PART_NO,
 	.static_ops		= sja1105e_table_ops,
 	.dyn_ops		= sja1105et_dyn_ops,
+	.ptp_ts_bits		= 24,
+	.ptpegr_ts_bytes	= 4,
 	.reset_cmd		= sja1105et_reset_cmd,
 	.fdb_add_cmd		= sja1105et_fdb_add,
 	.fdb_del_cmd		= sja1105et_fdb_del,
@@ -565,6 +569,8 @@ struct sja1105_info sja1105t_info = {
 	.part_no		= SJA1105ET_PART_NO,
 	.static_ops		= sja1105t_table_ops,
 	.dyn_ops		= sja1105et_dyn_ops,
+	.ptp_ts_bits		= 24,
+	.ptpegr_ts_bytes	= 4,
 	.reset_cmd		= sja1105et_reset_cmd,
 	.fdb_add_cmd		= sja1105et_fdb_add,
 	.fdb_del_cmd		= sja1105et_fdb_del,
@@ -577,6 +583,8 @@ struct sja1105_info sja1105p_info = {
 	.part_no		= SJA1105P_PART_NO,
 	.static_ops		= sja1105p_table_ops,
 	.dyn_ops		= sja1105pqrs_dyn_ops,
+	.ptp_ts_bits		= 32,
+	.ptpegr_ts_bytes	= 8,
 	.reset_cmd		= sja1105pqrs_reset_cmd,
 	.fdb_add_cmd		= sja1105pqrs_fdb_add,
 	.fdb_del_cmd		= sja1105pqrs_fdb_del,
@@ -589,6 +597,8 @@ struct sja1105_info sja1105q_info = {
 	.part_no		= SJA1105Q_PART_NO,
 	.static_ops		= sja1105q_table_ops,
 	.dyn_ops		= sja1105pqrs_dyn_ops,
+	.ptp_ts_bits		= 32,
+	.ptpegr_ts_bytes	= 8,
 	.reset_cmd		= sja1105pqrs_reset_cmd,
 	.fdb_add_cmd		= sja1105pqrs_fdb_add,
 	.fdb_del_cmd		= sja1105pqrs_fdb_del,
@@ -601,6 +611,8 @@ struct sja1105_info sja1105r_info = {
 	.part_no		= SJA1105R_PART_NO,
 	.static_ops		= sja1105r_table_ops,
 	.dyn_ops		= sja1105pqrs_dyn_ops,
+	.ptp_ts_bits		= 32,
+	.ptpegr_ts_bytes	= 8,
 	.reset_cmd		= sja1105pqrs_reset_cmd,
 	.fdb_add_cmd		= sja1105pqrs_fdb_add,
 	.fdb_del_cmd		= sja1105pqrs_fdb_del,
@@ -614,6 +626,8 @@ struct sja1105_info sja1105s_info = {
 	.static_ops		= sja1105s_table_ops,
 	.dyn_ops		= sja1105pqrs_dyn_ops,
 	.regs			= &sja1105pqrs_regs,
+	.ptp_ts_bits		= 32,
+	.ptpegr_ts_bytes	= 8,
 	.reset_cmd		= sja1105pqrs_reset_cmd,
 	.fdb_add_cmd		= sja1105pqrs_fdb_add,
 	.fdb_del_cmd		= sja1105pqrs_fdb_del,
diff --git a/include/linux/dsa/sja1105.h b/include/linux/dsa/sja1105.h
index f3237afed35a..f5d5f7823da6 100644
--- a/include/linux/dsa/sja1105.h
+++ b/include/linux/dsa/sja1105.h
@@ -22,6 +22,7 @@
 
 struct sja1105_port {
 	struct dsa_port *dp;
+	bool hwts_tx_en;
 	int mgmt_slot;
 };
 
-- 
2.17.1


^ permalink raw reply related	[flat|nested] 40+ messages in thread

* [PATCH v3 net-next 10/17] net: dsa: sja1105: Build a minimal understanding of meta frames
  2019-06-04 17:07 [PATCH v3 net-next 00/17] PTP support for the SJA1105 DSA driver Vladimir Oltean
                   ` (8 preceding siblings ...)
  2019-06-04 17:07 ` [PATCH v3 net-next 09/17] net: dsa: sja1105: Add logic for TX timestamping Vladimir Oltean
@ 2019-06-04 17:07 ` Vladimir Oltean
  2019-06-04 21:00   ` Florian Fainelli
  2019-06-04 17:07 ` [PATCH v3 net-next 11/17] net: dsa: sja1105: Add support for the AVB Parameters Table Vladimir Oltean
                   ` (7 subsequent siblings)
  17 siblings, 1 reply; 40+ messages in thread
From: Vladimir Oltean @ 2019-06-04 17:07 UTC (permalink / raw)
  To: f.fainelli, vivien.didelot, andrew, davem, richardcochran,
	john.stultz, tglx, sboyd
  Cc: linux-kernel, netdev, Vladimir Oltean

Meta frames are sent on the CPU port by the switch if RX timestamping is
enabled. They contain a partial timestamp of the previous frame.

They are Ethernet frames with the Ethernet header constructed out of:

- SJA1105_META_DMAC
- SJA1105_META_SMAC
- ETH_P_SJA1105_META

The Ethernet payload will be decoded in a follow-up patch.

Signed-off-by: Vladimir Oltean <olteanv@gmail.com>
---
Changes in v3:

Split from previous 09/10 patch (no functional changes).

Changes in v2:

None.

 include/linux/dsa/sja1105.h | 11 +++++++++++
 net/dsa/tag_sja1105.c       | 15 +++++++++++++++
 2 files changed, 26 insertions(+)

diff --git a/include/linux/dsa/sja1105.h b/include/linux/dsa/sja1105.h
index f5d5f7823da6..4f09743b4713 100644
--- a/include/linux/dsa/sja1105.h
+++ b/include/linux/dsa/sja1105.h
@@ -12,6 +12,7 @@
 #include <net/dsa.h>
 
 #define ETH_P_SJA1105				ETH_P_DSA_8021Q
+#define ETH_P_SJA1105_META			0x0008
 
 /* IEEE 802.3 Annex 57A: Slow Protocols PDUs (01:80:C2:xx:xx:xx) */
 #define SJA1105_LINKLOCAL_FILTER_A		0x0180C2000000ull
@@ -20,6 +21,16 @@
 #define SJA1105_LINKLOCAL_FILTER_B		0x011B19000000ull
 #define SJA1105_LINKLOCAL_FILTER_B_MASK		0xFFFFFF000000ull
 
+/* Source and Destination MAC of follow-up meta frames.
+ * Whereas the choice of SMAC only affects the unique identification of the
+ * switch as sender of meta frames, the DMAC must be an address that is present
+ * in the DSA master port's multicast MAC filter.
+ * 01-80-C2-00-00-0E is a good choice for this, as all profiles of IEEE 1588
+ * over L2 use this address for some purpose already.
+ */
+#define SJA1105_META_SMAC			0x222222222222ull
+#define SJA1105_META_DMAC			0x0180C200000Eull
+
 struct sja1105_port {
 	struct dsa_port *dp;
 	bool hwts_tx_en;
diff --git a/net/dsa/tag_sja1105.c b/net/dsa/tag_sja1105.c
index 7a56a27a1fd2..9ff7cfa6ea20 100644
--- a/net/dsa/tag_sja1105.c
+++ b/net/dsa/tag_sja1105.c
@@ -7,6 +7,21 @@
 #include <linux/packing.h>
 #include "dsa_priv.h"
 
+static inline bool sja1105_is_meta_frame(const struct sk_buff *skb)
+{
+	const struct ethhdr *hdr = eth_hdr(skb);
+	u64 smac = ether_addr_to_u64(hdr->h_source);
+	u64 dmac = ether_addr_to_u64(hdr->h_dest);
+
+	if (smac != SJA1105_META_SMAC)
+		return false;
+	if (dmac != SJA1105_META_DMAC)
+		return false;
+	if (ntohs(hdr->h_proto) != ETH_P_SJA1105_META)
+		return false;
+	return true;
+}
+
 /* This is the first time the tagger sees the frame on RX.
  * Figure out if we can decode it, and if we can, annotate skb->cb with how we
  * plan to do that, so we don't need to check again in the rcv function.
-- 
2.17.1


^ permalink raw reply related	[flat|nested] 40+ messages in thread

* [PATCH v3 net-next 11/17] net: dsa: sja1105: Add support for the AVB Parameters Table
  2019-06-04 17:07 [PATCH v3 net-next 00/17] PTP support for the SJA1105 DSA driver Vladimir Oltean
                   ` (9 preceding siblings ...)
  2019-06-04 17:07 ` [PATCH v3 net-next 10/17] net: dsa: sja1105: Build a minimal understanding of meta frames Vladimir Oltean
@ 2019-06-04 17:07 ` Vladimir Oltean
  2019-06-04 17:07 ` [PATCH v3 net-next 12/17] net: dsa: sja1105: Make sja1105_is_link_local not match meta frames Vladimir Oltean
                   ` (6 subsequent siblings)
  17 siblings, 0 replies; 40+ messages in thread
From: Vladimir Oltean @ 2019-06-04 17:07 UTC (permalink / raw)
  To: f.fainelli, vivien.didelot, andrew, davem, richardcochran,
	john.stultz, tglx, sboyd
  Cc: linux-kernel, netdev, Vladimir Oltean

This table is used to program the switch to emit "meta" follow-up
Ethernet frames (which contain partial RX timestamps) after each
link-local frame that was trapped to the CPU port through MAC filtering.
This includes PTP frames.

Signed-off-by: Vladimir Oltean <olteanv@gmail.com>
---
Changes in v3:

Split from previous 09/10 patch (no functional changes).

Changes in v2:

None.

 .../net/dsa/sja1105/sja1105_dynamic_config.c  |  2 +
 drivers/net/dsa/sja1105/sja1105_main.c        | 36 +++++++++++
 .../net/dsa/sja1105/sja1105_static_config.c   | 59 +++++++++++++++++++
 .../net/dsa/sja1105/sja1105_static_config.h   | 10 ++++
 4 files changed, 107 insertions(+)

diff --git a/drivers/net/dsa/sja1105/sja1105_dynamic_config.c b/drivers/net/dsa/sja1105/sja1105_dynamic_config.c
index 352bb6e89297..56c83b9d52e4 100644
--- a/drivers/net/dsa/sja1105/sja1105_dynamic_config.c
+++ b/drivers/net/dsa/sja1105/sja1105_dynamic_config.c
@@ -378,6 +378,7 @@ struct sja1105_dynamic_table_ops sja1105et_dyn_ops[BLK_IDX_MAX_DYN] = {
 		.addr = 0x38,
 	},
 	[BLK_IDX_L2_FORWARDING_PARAMS] = {0},
+	[BLK_IDX_AVB_PARAMS] = {0},
 	[BLK_IDX_GENERAL_PARAMS] = {
 		.entry_packing = sja1105et_general_params_entry_packing,
 		.cmd_packing = sja1105et_general_params_cmd_packing,
@@ -441,6 +442,7 @@ struct sja1105_dynamic_table_ops sja1105pqrs_dyn_ops[BLK_IDX_MAX_DYN] = {
 		.addr = 0x38,
 	},
 	[BLK_IDX_L2_FORWARDING_PARAMS] = {0},
+	[BLK_IDX_AVB_PARAMS] = {0},
 	[BLK_IDX_GENERAL_PARAMS] = {
 		.entry_packing = sja1105et_general_params_entry_packing,
 		.cmd_packing = sja1105et_general_params_cmd_packing,
diff --git a/drivers/net/dsa/sja1105/sja1105_main.c b/drivers/net/dsa/sja1105/sja1105_main.c
index 45c65e77b61d..f83f924c0833 100644
--- a/drivers/net/dsa/sja1105/sja1105_main.c
+++ b/drivers/net/dsa/sja1105/sja1105_main.c
@@ -508,6 +508,39 @@ static int sja1105_init_l2_policing(struct sja1105_private *priv)
 	return 0;
 }
 
+static int sja1105_init_avb_params(struct sja1105_private *priv,
+				   bool on)
+{
+	struct sja1105_avb_params_entry *avb;
+	struct sja1105_table *table;
+
+	table = &priv->static_config.tables[BLK_IDX_AVB_PARAMS];
+
+	/* Discard previous AVB Parameters Table */
+	if (table->entry_count) {
+		kfree(table->entries);
+		table->entry_count = 0;
+	}
+
+	/* Configure the reception of meta frames only if requested */
+	if (!on)
+		return 0;
+
+	table->entries = kcalloc(SJA1105_MAX_AVB_PARAMS_COUNT,
+				 table->ops->unpacked_entry_size, GFP_KERNEL);
+	if (!table->entries)
+		return -ENOMEM;
+
+	table->entry_count = SJA1105_MAX_AVB_PARAMS_COUNT;
+
+	avb = table->entries;
+
+	avb->destmeta = SJA1105_META_DMAC;
+	avb->srcmeta  = SJA1105_META_SMAC;
+
+	return 0;
+}
+
 static int sja1105_static_config_load(struct sja1105_private *priv,
 				      struct sja1105_dt_port *ports)
 {
@@ -546,6 +579,9 @@ static int sja1105_static_config_load(struct sja1105_private *priv,
 	if (rc < 0)
 		return rc;
 	rc = sja1105_init_general_params(priv);
+	if (rc < 0)
+		return rc;
+	rc = sja1105_init_avb_params(priv, false);
 	if (rc < 0)
 		return rc;
 
diff --git a/drivers/net/dsa/sja1105/sja1105_static_config.c b/drivers/net/dsa/sja1105/sja1105_static_config.c
index 6d65a7b09395..242f001c59fe 100644
--- a/drivers/net/dsa/sja1105/sja1105_static_config.c
+++ b/drivers/net/dsa/sja1105/sja1105_static_config.c
@@ -91,6 +91,28 @@ u32 sja1105_crc32(const void *buf, size_t len)
 	return ~crc;
 }
 
+static size_t sja1105et_avb_params_entry_packing(void *buf, void *entry_ptr,
+						 enum packing_op op)
+{
+	const size_t size = SJA1105ET_SIZE_AVB_PARAMS_ENTRY;
+	struct sja1105_avb_params_entry *entry = entry_ptr;
+
+	sja1105_packing(buf, &entry->destmeta, 95, 48, size, op);
+	sja1105_packing(buf, &entry->srcmeta,  47,  0, size, op);
+	return size;
+}
+
+static size_t sja1105pqrs_avb_params_entry_packing(void *buf, void *entry_ptr,
+						   enum packing_op op)
+{
+	const size_t size = SJA1105PQRS_SIZE_AVB_PARAMS_ENTRY;
+	struct sja1105_avb_params_entry *entry = entry_ptr;
+
+	sja1105_packing(buf, &entry->destmeta,   125,  78, size, op);
+	sja1105_packing(buf, &entry->srcmeta,     77,  30, size, op);
+	return size;
+}
+
 static size_t sja1105et_general_params_entry_packing(void *buf, void *entry_ptr,
 						     enum packing_op op)
 {
@@ -423,6 +445,7 @@ static u64 blk_id_map[BLK_IDX_MAX] = {
 	[BLK_IDX_MAC_CONFIG] = BLKID_MAC_CONFIG,
 	[BLK_IDX_L2_LOOKUP_PARAMS] = BLKID_L2_LOOKUP_PARAMS,
 	[BLK_IDX_L2_FORWARDING_PARAMS] = BLKID_L2_FORWARDING_PARAMS,
+	[BLK_IDX_AVB_PARAMS] = BLKID_AVB_PARAMS,
 	[BLK_IDX_GENERAL_PARAMS] = BLKID_GENERAL_PARAMS,
 	[BLK_IDX_XMII_PARAMS] = BLKID_XMII_PARAMS,
 };
@@ -624,6 +647,12 @@ struct sja1105_table_ops sja1105e_table_ops[BLK_IDX_MAX] = {
 		.packed_entry_size = SJA1105_SIZE_L2_FORWARDING_PARAMS_ENTRY,
 		.max_entry_count = SJA1105_MAX_L2_FORWARDING_PARAMS_COUNT,
 	},
+	[BLK_IDX_AVB_PARAMS] = {
+		.packing = sja1105et_avb_params_entry_packing,
+		.unpacked_entry_size = sizeof(struct sja1105_avb_params_entry),
+		.packed_entry_size = SJA1105ET_SIZE_AVB_PARAMS_ENTRY,
+		.max_entry_count = SJA1105_MAX_AVB_PARAMS_COUNT,
+	},
 	[BLK_IDX_GENERAL_PARAMS] = {
 		.packing = sja1105et_general_params_entry_packing,
 		.unpacked_entry_size = sizeof(struct sja1105_general_params_entry),
@@ -682,6 +711,12 @@ struct sja1105_table_ops sja1105t_table_ops[BLK_IDX_MAX] = {
 		.packed_entry_size = SJA1105_SIZE_L2_FORWARDING_PARAMS_ENTRY,
 		.max_entry_count = SJA1105_MAX_L2_FORWARDING_PARAMS_COUNT,
 	},
+	[BLK_IDX_AVB_PARAMS] = {
+		.packing = sja1105et_avb_params_entry_packing,
+		.unpacked_entry_size = sizeof(struct sja1105_avb_params_entry),
+		.packed_entry_size = SJA1105ET_SIZE_AVB_PARAMS_ENTRY,
+		.max_entry_count = SJA1105_MAX_AVB_PARAMS_COUNT,
+	},
 	[BLK_IDX_GENERAL_PARAMS] = {
 		.packing = sja1105et_general_params_entry_packing,
 		.unpacked_entry_size = sizeof(struct sja1105_general_params_entry),
@@ -740,6 +775,12 @@ struct sja1105_table_ops sja1105p_table_ops[BLK_IDX_MAX] = {
 		.packed_entry_size = SJA1105_SIZE_L2_FORWARDING_PARAMS_ENTRY,
 		.max_entry_count = SJA1105_MAX_L2_FORWARDING_PARAMS_COUNT,
 	},
+	[BLK_IDX_AVB_PARAMS] = {
+		.packing = sja1105pqrs_avb_params_entry_packing,
+		.unpacked_entry_size = sizeof(struct sja1105_avb_params_entry),
+		.packed_entry_size = SJA1105PQRS_SIZE_AVB_PARAMS_ENTRY,
+		.max_entry_count = SJA1105_MAX_AVB_PARAMS_COUNT,
+	},
 	[BLK_IDX_GENERAL_PARAMS] = {
 		.packing = sja1105pqrs_general_params_entry_packing,
 		.unpacked_entry_size = sizeof(struct sja1105_general_params_entry),
@@ -798,6 +839,12 @@ struct sja1105_table_ops sja1105q_table_ops[BLK_IDX_MAX] = {
 		.packed_entry_size = SJA1105_SIZE_L2_FORWARDING_PARAMS_ENTRY,
 		.max_entry_count = SJA1105_MAX_L2_FORWARDING_PARAMS_COUNT,
 	},
+	[BLK_IDX_AVB_PARAMS] = {
+		.packing = sja1105pqrs_avb_params_entry_packing,
+		.unpacked_entry_size = sizeof(struct sja1105_avb_params_entry),
+		.packed_entry_size = SJA1105PQRS_SIZE_AVB_PARAMS_ENTRY,
+		.max_entry_count = SJA1105_MAX_AVB_PARAMS_COUNT,
+	},
 	[BLK_IDX_GENERAL_PARAMS] = {
 		.packing = sja1105pqrs_general_params_entry_packing,
 		.unpacked_entry_size = sizeof(struct sja1105_general_params_entry),
@@ -856,6 +903,12 @@ struct sja1105_table_ops sja1105r_table_ops[BLK_IDX_MAX] = {
 		.packed_entry_size = SJA1105_SIZE_L2_FORWARDING_PARAMS_ENTRY,
 		.max_entry_count = SJA1105_MAX_L2_FORWARDING_PARAMS_COUNT,
 	},
+	[BLK_IDX_AVB_PARAMS] = {
+		.packing = sja1105pqrs_avb_params_entry_packing,
+		.unpacked_entry_size = sizeof(struct sja1105_avb_params_entry),
+		.packed_entry_size = SJA1105PQRS_SIZE_AVB_PARAMS_ENTRY,
+		.max_entry_count = SJA1105_MAX_AVB_PARAMS_COUNT,
+	},
 	[BLK_IDX_GENERAL_PARAMS] = {
 		.packing = sja1105pqrs_general_params_entry_packing,
 		.unpacked_entry_size = sizeof(struct sja1105_general_params_entry),
@@ -914,6 +967,12 @@ struct sja1105_table_ops sja1105s_table_ops[BLK_IDX_MAX] = {
 		.packed_entry_size = SJA1105_SIZE_L2_FORWARDING_PARAMS_ENTRY,
 		.max_entry_count = SJA1105_MAX_L2_FORWARDING_PARAMS_COUNT,
 	},
+	[BLK_IDX_AVB_PARAMS] = {
+		.packing = sja1105pqrs_avb_params_entry_packing,
+		.unpacked_entry_size = sizeof(struct sja1105_avb_params_entry),
+		.packed_entry_size = SJA1105PQRS_SIZE_AVB_PARAMS_ENTRY,
+		.max_entry_count = SJA1105_MAX_AVB_PARAMS_COUNT,
+	},
 	[BLK_IDX_GENERAL_PARAMS] = {
 		.packing = sja1105pqrs_general_params_entry_packing,
 		.unpacked_entry_size = sizeof(struct sja1105_general_params_entry),
diff --git a/drivers/net/dsa/sja1105/sja1105_static_config.h b/drivers/net/dsa/sja1105/sja1105_static_config.h
index d513b1c91b98..a9586d0b4b3b 100644
--- a/drivers/net/dsa/sja1105/sja1105_static_config.h
+++ b/drivers/net/dsa/sja1105/sja1105_static_config.h
@@ -20,10 +20,12 @@
 #define SJA1105ET_SIZE_MAC_CONFIG_ENTRY			28
 #define SJA1105ET_SIZE_L2_LOOKUP_PARAMS_ENTRY		4
 #define SJA1105ET_SIZE_GENERAL_PARAMS_ENTRY		40
+#define SJA1105ET_SIZE_AVB_PARAMS_ENTRY			12
 #define SJA1105PQRS_SIZE_L2_LOOKUP_ENTRY		20
 #define SJA1105PQRS_SIZE_MAC_CONFIG_ENTRY		32
 #define SJA1105PQRS_SIZE_L2_LOOKUP_PARAMS_ENTRY		16
 #define SJA1105PQRS_SIZE_GENERAL_PARAMS_ENTRY		44
+#define SJA1105PQRS_SIZE_AVB_PARAMS_ENTRY		16
 
 /* UM10944.pdf Page 11, Table 2. Configuration Blocks */
 enum {
@@ -34,6 +36,7 @@ enum {
 	BLKID_MAC_CONFIG				= 0x09,
 	BLKID_L2_LOOKUP_PARAMS				= 0x0D,
 	BLKID_L2_FORWARDING_PARAMS			= 0x0E,
+	BLKID_AVB_PARAMS				= 0x10,
 	BLKID_GENERAL_PARAMS				= 0x11,
 	BLKID_XMII_PARAMS				= 0x4E,
 };
@@ -46,6 +49,7 @@ enum sja1105_blk_idx {
 	BLK_IDX_MAC_CONFIG,
 	BLK_IDX_L2_LOOKUP_PARAMS,
 	BLK_IDX_L2_FORWARDING_PARAMS,
+	BLK_IDX_AVB_PARAMS,
 	BLK_IDX_GENERAL_PARAMS,
 	BLK_IDX_XMII_PARAMS,
 	BLK_IDX_MAX,
@@ -64,6 +68,7 @@ enum sja1105_blk_idx {
 #define SJA1105_MAX_L2_FORWARDING_PARAMS_COUNT		1
 #define SJA1105_MAX_GENERAL_PARAMS_COUNT		1
 #define SJA1105_MAX_XMII_PARAMS_COUNT			1
+#define SJA1105_MAX_AVB_PARAMS_COUNT			1
 
 #define SJA1105_MAX_FRAME_MEMORY			929
 
@@ -179,6 +184,11 @@ struct sja1105_l2_policing_entry {
 	u64 partition;
 };
 
+struct sja1105_avb_params_entry {
+	u64 destmeta;
+	u64 srcmeta;
+};
+
 struct sja1105_mac_config_entry {
 	u64 top[8];
 	u64 base[8];
-- 
2.17.1


^ permalink raw reply related	[flat|nested] 40+ messages in thread

* [PATCH v3 net-next 12/17] net: dsa: sja1105: Make sja1105_is_link_local not match meta frames
  2019-06-04 17:07 [PATCH v3 net-next 00/17] PTP support for the SJA1105 DSA driver Vladimir Oltean
                   ` (10 preceding siblings ...)
  2019-06-04 17:07 ` [PATCH v3 net-next 11/17] net: dsa: sja1105: Add support for the AVB Parameters Table Vladimir Oltean
@ 2019-06-04 17:07 ` Vladimir Oltean
  2019-06-04 17:07 ` [PATCH v3 net-next 13/17] net: dsa: sja1105: Receive and decode " Vladimir Oltean
                   ` (5 subsequent siblings)
  17 siblings, 0 replies; 40+ messages in thread
From: Vladimir Oltean @ 2019-06-04 17:07 UTC (permalink / raw)
  To: f.fainelli, vivien.didelot, andrew, davem, richardcochran,
	john.stultz, tglx, sboyd
  Cc: linux-kernel, netdev, Vladimir Oltean

Although meta frames are configured to be sent at SJA1105_META_DMAC
(01-80-C2-00-00-0E) which is a multicast MAC address that would also be
trapped by the switch to the CPU, were it to receive it on a front-panel
port, meta frames are conceptually not link-local frames, they only
carry their RX timestamps.

The choice of sending meta frames at a multicast DMAC is a pragmatic
one, to avoid installing an extra entry to the DSA master port's
multicast MAC filter.

Signed-off-by: Vladimir Oltean <olteanv@gmail.com>
---
Changes in v3:

Split from previous 09/10 patch (no functional changes).

Changes in v2:

None.

 include/linux/dsa/sja1105.h | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/include/linux/dsa/sja1105.h b/include/linux/dsa/sja1105.h
index 4f09743b4713..b9619d9fca4c 100644
--- a/include/linux/dsa/sja1105.h
+++ b/include/linux/dsa/sja1105.h
@@ -43,6 +43,8 @@ static inline bool sja1105_is_link_local(const struct sk_buff *skb)
 	const struct ethhdr *hdr = eth_hdr(skb);
 	u64 dmac = ether_addr_to_u64(hdr->h_dest);
 
+	if (ntohs(hdr->h_proto) == ETH_P_SJA1105_META)
+		return false;
 	if ((dmac & SJA1105_LINKLOCAL_FILTER_A_MASK) ==
 		    SJA1105_LINKLOCAL_FILTER_A)
 		return true;
-- 
2.17.1


^ permalink raw reply related	[flat|nested] 40+ messages in thread

* [PATCH v3 net-next 13/17] net: dsa: sja1105: Receive and decode meta frames
  2019-06-04 17:07 [PATCH v3 net-next 00/17] PTP support for the SJA1105 DSA driver Vladimir Oltean
                   ` (11 preceding siblings ...)
  2019-06-04 17:07 ` [PATCH v3 net-next 12/17] net: dsa: sja1105: Make sja1105_is_link_local not match meta frames Vladimir Oltean
@ 2019-06-04 17:07 ` Vladimir Oltean
  2019-06-04 17:07 ` [PATCH v3 net-next 14/17] net: dsa: sja1105: Add a global sja1105_tagger_data structure Vladimir Oltean
                   ` (4 subsequent siblings)
  17 siblings, 0 replies; 40+ messages in thread
From: Vladimir Oltean @ 2019-06-04 17:07 UTC (permalink / raw)
  To: f.fainelli, vivien.didelot, andrew, davem, richardcochran,
	john.stultz, tglx, sboyd
  Cc: linux-kernel, netdev, Vladimir Oltean

This adds support in the tagger for understanding the source port and
switch id of meta frames.  Their timestamp is also extracted but not
used yet - this needs to be done in a state machine that modifies the
previously received timestampable frame - will be added in a follow-up
patch.

Signed-off-by: Vladimir Oltean <olteanv@gmail.com>
---
Changes in v3:

Split from previous 09/10 patch (no functional changes).

Changes in v2:

None.

 net/dsa/tag_sja1105.c | 43 ++++++++++++++++++++++++++++++++++++++++++-
 1 file changed, 42 insertions(+), 1 deletion(-)

diff --git a/net/dsa/tag_sja1105.c b/net/dsa/tag_sja1105.c
index 9ff7cfa6ea20..6ec9a32dda62 100644
--- a/net/dsa/tag_sja1105.c
+++ b/net/dsa/tag_sja1105.c
@@ -7,6 +7,36 @@
 #include <linux/packing.h>
 #include "dsa_priv.h"
 
+struct sja1105_meta {
+	u64 tstamp;
+	u64 dmac_byte_4;
+	u64 dmac_byte_3;
+	u64 source_port;
+	u64 switch_id;
+};
+
+static void sja1105_meta_unpack(const struct sk_buff *skb,
+				struct sja1105_meta *meta)
+{
+	u8 *buf = skb_mac_header(skb) + ETH_HLEN;
+
+	/* UM10944.pdf section 4.2.17 AVB Parameters:
+	 * Structure of the meta-data follow-up frame.
+	 * It is in network byte order, so there are no quirks
+	 * while unpacking the meta frame.
+	 *
+	 * Also SJA1105 E/T only populates bits 23:0 of the timestamp
+	 * whereas P/Q/R/S does 32 bits. Since the structure is the
+	 * same and the E/T puts zeroes in the high-order byte, use
+	 * a unified unpacking command for both device series.
+	 */
+	packing(buf,     &meta->tstamp,     31, 0, 4, UNPACK, 0);
+	packing(buf + 4, &meta->dmac_byte_4, 7, 0, 1, UNPACK, 0);
+	packing(buf + 5, &meta->dmac_byte_3, 7, 0, 1, UNPACK, 0);
+	packing(buf + 6, &meta->source_port, 7, 0, 1, UNPACK, 0);
+	packing(buf + 7, &meta->switch_id,   7, 0, 1, UNPACK, 0);
+}
+
 static inline bool sja1105_is_meta_frame(const struct sk_buff *skb)
 {
 	const struct ethhdr *hdr = eth_hdr(skb);
@@ -28,6 +58,8 @@ static inline bool sja1105_is_meta_frame(const struct sk_buff *skb)
  */
 static bool sja1105_filter(const struct sk_buff *skb, struct net_device *dev)
 {
+	if (sja1105_is_meta_frame(skb))
+		return true;
 	if (sja1105_is_link_local(skb))
 		return true;
 	if (!dsa_port_is_vlan_filtering(dev->dsa_ptr))
@@ -66,13 +98,18 @@ static struct sk_buff *sja1105_rcv(struct sk_buff *skb,
 				   struct net_device *netdev,
 				   struct packet_type *pt)
 {
+	struct sja1105_meta meta = {0};
 	int source_port, switch_id;
 	struct sk_buff *nskb;
 	u16 tpid, vid, tci;
+	bool is_link_local;
 	bool is_tagged;
+	bool is_meta;
 
 	nskb = dsa_8021q_rcv(skb, netdev, pt, &tpid, &tci);
 	is_tagged = (nskb && tpid == ETH_P_SJA1105);
+	is_link_local = sja1105_is_link_local(skb);
+	is_meta = sja1105_is_meta_frame(skb);
 
 	skb->offload_fwd_mark = 1;
 
@@ -82,7 +119,7 @@ static struct sk_buff *sja1105_rcv(struct sk_buff *skb,
 		source_port = dsa_8021q_rx_source_port(vid);
 		switch_id = dsa_8021q_rx_switch_id(vid);
 		skb->priority = (tci & VLAN_PRIO_MASK) >> VLAN_PRIO_SHIFT;
-	} else if (sja1105_is_link_local(skb)) {
+	} else if (is_link_local) {
 		struct ethhdr *hdr = eth_hdr(skb);
 
 		/* Management traffic path. Switch embeds the switch ID and
@@ -94,6 +131,10 @@ static struct sk_buff *sja1105_rcv(struct sk_buff *skb,
 		/* Clear the DMAC bytes that were mangled by the switch */
 		hdr->h_dest[3] = 0;
 		hdr->h_dest[4] = 0;
+	} else if (is_meta) {
+		sja1105_meta_unpack(skb, &meta);
+		source_port = meta.source_port;
+		switch_id = meta.switch_id;
 	} else {
 		return NULL;
 	}
-- 
2.17.1


^ permalink raw reply related	[flat|nested] 40+ messages in thread

* [PATCH v3 net-next 14/17] net: dsa: sja1105: Add a global sja1105_tagger_data structure
  2019-06-04 17:07 [PATCH v3 net-next 00/17] PTP support for the SJA1105 DSA driver Vladimir Oltean
                   ` (12 preceding siblings ...)
  2019-06-04 17:07 ` [PATCH v3 net-next 13/17] net: dsa: sja1105: Receive and decode " Vladimir Oltean
@ 2019-06-04 17:07 ` Vladimir Oltean
  2019-06-04 17:07 ` [PATCH v3 net-next 15/17] net: dsa: sja1105: Increase priority of CPU-trapped frames Vladimir Oltean
                   ` (3 subsequent siblings)
  17 siblings, 0 replies; 40+ messages in thread
From: Vladimir Oltean @ 2019-06-04 17:07 UTC (permalink / raw)
  To: f.fainelli, vivien.didelot, andrew, davem, richardcochran,
	john.stultz, tglx, sboyd
  Cc: linux-kernel, netdev, Vladimir Oltean

This will be used to keep state for RX timestamping. It is global
because the switch serializes timestampable and meta frames when
trapping them towards the CPU port (lower port indices have higher
priority) and therefore having one state machine per port would create
unnecessary complications.

Signed-off-by: Vladimir Oltean <olteanv@gmail.com>
---
Changes in v3:

Split from previous 09/10 patch (no functional changes).

Changes in v2:

None.

 drivers/net/dsa/sja1105/sja1105.h      |  1 +
 drivers/net/dsa/sja1105/sja1105_main.c |  5 +++++
 include/linux/dsa/sja1105.h            | 15 +++++++++++++++
 3 files changed, 21 insertions(+)

diff --git a/drivers/net/dsa/sja1105/sja1105.h b/drivers/net/dsa/sja1105/sja1105.h
index 5a4f83a3417b..0fc6fe9ada87 100644
--- a/drivers/net/dsa/sja1105/sja1105.h
+++ b/drivers/net/dsa/sja1105/sja1105.h
@@ -103,6 +103,7 @@ struct sja1105_private {
 	 * the switch doesn't confuse them with one another.
 	 */
 	struct mutex mgmt_lock;
+	struct sja1105_tagger_data tagger_data;
 };
 
 #include "sja1105_dynamic_config.h"
diff --git a/drivers/net/dsa/sja1105/sja1105_main.c b/drivers/net/dsa/sja1105/sja1105_main.c
index f83f924c0833..9dd2ab2725b6 100644
--- a/drivers/net/dsa/sja1105/sja1105_main.c
+++ b/drivers/net/dsa/sja1105/sja1105_main.c
@@ -1828,6 +1828,7 @@ static int sja1105_check_device_id(struct sja1105_private *priv)
 
 static int sja1105_probe(struct spi_device *spi)
 {
+	struct sja1105_tagger_data *tagger_data;
 	struct device *dev = &spi->dev;
 	struct sja1105_private *priv;
 	struct dsa_switch *ds;
@@ -1882,12 +1883,16 @@ static int sja1105_probe(struct spi_device *spi)
 	ds->priv = priv;
 	priv->ds = ds;
 
+	tagger_data = &priv->tagger_data;
+	skb_queue_head_init(&tagger_data->skb_rxtstamp_queue);
+
 	/* Connections between dsa_port and sja1105_port */
 	for (i = 0; i < SJA1105_NUM_PORTS; i++) {
 		struct sja1105_port *sp = &priv->ports[i];
 
 		ds->ports[i].priv = sp;
 		sp->dp = &ds->ports[i];
+		sp->data = tagger_data;
 	}
 	mutex_init(&priv->mgmt_lock);
 
diff --git a/include/linux/dsa/sja1105.h b/include/linux/dsa/sja1105.h
index b9619d9fca4c..b83f6e428e5d 100644
--- a/include/linux/dsa/sja1105.h
+++ b/include/linux/dsa/sja1105.h
@@ -31,7 +31,22 @@
 #define SJA1105_META_SMAC			0x222222222222ull
 #define SJA1105_META_DMAC			0x0180C200000Eull
 
+/* Global tagger data: each struct sja1105_port has a reference to
+ * the structure defined in struct sja1105_private.
+ */
+struct sja1105_tagger_data {
+	struct sk_buff_head skb_rxtstamp_queue;
+	struct work_struct rxtstamp_work;
+	struct sk_buff *stampable_skb;
+	/* Protects concurrent access to the meta state machine
+	 * from taggers running on multiple ports on SMP systems
+	 */
+	spinlock_t meta_lock;
+	bool hwts_rx_en;
+};
+
 struct sja1105_port {
+	struct sja1105_tagger_data *data;
 	struct dsa_port *dp;
 	bool hwts_tx_en;
 	int mgmt_slot;
-- 
2.17.1


^ permalink raw reply related	[flat|nested] 40+ messages in thread

* [PATCH v3 net-next 15/17] net: dsa: sja1105: Increase priority of CPU-trapped frames
  2019-06-04 17:07 [PATCH v3 net-next 00/17] PTP support for the SJA1105 DSA driver Vladimir Oltean
                   ` (13 preceding siblings ...)
  2019-06-04 17:07 ` [PATCH v3 net-next 14/17] net: dsa: sja1105: Add a global sja1105_tagger_data structure Vladimir Oltean
@ 2019-06-04 17:07 ` Vladimir Oltean
  2019-06-04 17:07 ` [PATCH v3 net-next 16/17] net: dsa: sja1105: Add a state machine for RX timestamping Vladimir Oltean
                   ` (2 subsequent siblings)
  17 siblings, 0 replies; 40+ messages in thread
From: Vladimir Oltean @ 2019-06-04 17:07 UTC (permalink / raw)
  To: f.fainelli, vivien.didelot, andrew, davem, richardcochran,
	john.stultz, tglx, sboyd
  Cc: linux-kernel, netdev, Vladimir Oltean

Without noticing any particular issue, this patch ensures that
management traffic is treated with the maximum priority on RX by the
switch.  This is generally desirable, as the driver keeps a state
machine that waits for metadata follow-up frames as soon as a management
frame is received.  Increasing the priority helps expedite the reception
(and further reconstruction) of the RX timestamp to the driver after the
MAC has generated it.

Signed-off-by: Vladimir Oltean <olteanv@gmail.com>
---
Changes in v3:

None.

Changes in v2:

None.

 drivers/net/dsa/sja1105/sja1105_main.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/net/dsa/sja1105/sja1105_main.c b/drivers/net/dsa/sja1105/sja1105_main.c
index 9dd2ab2725b6..fceca0e5984f 100644
--- a/drivers/net/dsa/sja1105/sja1105_main.c
+++ b/drivers/net/dsa/sja1105/sja1105_main.c
@@ -389,7 +389,7 @@ static int sja1105_init_general_params(struct sja1105_private *priv)
 		.mirr_ptacu = 0,
 		.switchid = priv->ds->index,
 		/* Priority queue for link-local frames trapped to CPU */
-		.hostprio = 0,
+		.hostprio = 7,
 		.mac_fltres1 = SJA1105_LINKLOCAL_FILTER_A,
 		.mac_flt1    = SJA1105_LINKLOCAL_FILTER_A_MASK,
 		.incl_srcpt1 = false,
-- 
2.17.1


^ permalink raw reply related	[flat|nested] 40+ messages in thread

* [PATCH v3 net-next 16/17] net: dsa: sja1105: Add a state machine for RX timestamping
  2019-06-04 17:07 [PATCH v3 net-next 00/17] PTP support for the SJA1105 DSA driver Vladimir Oltean
                   ` (14 preceding siblings ...)
  2019-06-04 17:07 ` [PATCH v3 net-next 15/17] net: dsa: sja1105: Increase priority of CPU-trapped frames Vladimir Oltean
@ 2019-06-04 17:07 ` Vladimir Oltean
  2019-06-04 17:07 ` [PATCH v3 net-next 17/17] net: dsa: sja1105: Expose PTP timestamping ioctls to userspace Vladimir Oltean
  2019-06-05  3:22 ` [PATCH v3 net-next 00/17] PTP support for the SJA1105 DSA driver David Miller
  17 siblings, 0 replies; 40+ messages in thread
From: Vladimir Oltean @ 2019-06-04 17:07 UTC (permalink / raw)
  To: f.fainelli, vivien.didelot, andrew, davem, richardcochran,
	john.stultz, tglx, sboyd
  Cc: linux-kernel, netdev, Vladimir Oltean

Meta frame reception relies on the hardware keeping its promise that it
will send no other traffic towards the CPU port between a link-local
frame and a meta frame.  Otherwise there is no other way to associate
the meta frame with the link-local frame it's holding a timestamp of.
The receive function is made stateful, and buffers a timestampable frame
until its meta frame arrives, then merges the two, drops the meta and
releases the link-local frame up the stack.

Signed-off-by: Vladimir Oltean <olteanv@gmail.com>
---
Changes in v3:

Split from previous 09/10 patch (no functional changes).

Changes in v2:

None.

 drivers/net/dsa/sja1105/sja1105_main.c |  65 +++++++++++++
 include/linux/dsa/sja1105.h            |   7 ++
 net/dsa/tag_sja1105.c                  | 121 ++++++++++++++++++++++++-
 3 files changed, 192 insertions(+), 1 deletion(-)

diff --git a/drivers/net/dsa/sja1105/sja1105_main.c b/drivers/net/dsa/sja1105/sja1105_main.c
index fceca0e5984f..46a851f54b83 100644
--- a/drivers/net/dsa/sja1105/sja1105_main.c
+++ b/drivers/net/dsa/sja1105/sja1105_main.c
@@ -1600,6 +1600,14 @@ static int sja1105_setup(struct dsa_switch *ds)
 	return sja1105_setup_8021q_tagging(ds, true);
 }
 
+static void sja1105_teardown(struct dsa_switch *ds)
+{
+	struct sja1105_private *priv = ds->priv;
+
+	cancel_work_sync(&priv->tagger_data.rxtstamp_work);
+	skb_queue_purge(&priv->tagger_data.skb_rxtstamp_queue);
+}
+
 static int sja1105_mgmt_xmit(struct dsa_switch *ds, int port, int slot,
 			     struct sk_buff *skb, bool takets)
 {
@@ -1747,6 +1755,60 @@ static int sja1105_set_ageing_time(struct dsa_switch *ds,
 	return sja1105_static_config_reload(priv);
 }
 
+#define to_tagger(d) \
+	container_of((d), struct sja1105_tagger_data, rxtstamp_work)
+#define to_sja1105(d) \
+	container_of((d), struct sja1105_private, tagger_data)
+
+static void sja1105_rxtstamp_work(struct work_struct *work)
+{
+	struct sja1105_tagger_data *data = to_tagger(work);
+	struct sja1105_private *priv = to_sja1105(data);
+	struct sk_buff *skb;
+	u64 now;
+
+	mutex_lock(&priv->ptp_lock);
+
+	now = priv->tstamp_cc.read(&priv->tstamp_cc);
+
+	while ((skb = skb_dequeue(&data->skb_rxtstamp_queue)) != NULL) {
+		struct skb_shared_hwtstamps *shwt = skb_hwtstamps(skb);
+		u64 ts;
+
+		*shwt = (struct skb_shared_hwtstamps) {0};
+
+		ts = SJA1105_SKB_CB(skb)->meta_tstamp;
+		ts = sja1105_tstamp_reconstruct(priv, now, ts);
+		ts = timecounter_cyc2time(&priv->tstamp_tc, ts);
+
+		shwt->hwtstamp = ns_to_ktime(ts);
+		netif_rx_ni(skb);
+	}
+
+	mutex_unlock(&priv->ptp_lock);
+}
+
+/* Called from dsa_skb_defer_rx_timestamp */
+bool sja1105_port_rxtstamp(struct dsa_switch *ds, int port,
+			   struct sk_buff *skb, unsigned int type)
+{
+	struct sja1105_private *priv = ds->priv;
+	struct sja1105_tagger_data *data = &priv->tagger_data;
+
+	if (!data->hwts_rx_en)
+		return false;
+
+	if (!sja1105_is_link_local(skb))
+		return false;
+
+	/* We need to read the full PTP clock to reconstruct the Rx
+	 * timestamp. For that we need a sleepable context.
+	 */
+	skb_queue_tail(&data->skb_rxtstamp_queue, skb);
+	schedule_work(&data->rxtstamp_work);
+	return true;
+}
+
 /* Called from dsa_skb_tx_timestamp. This callback is just to make DSA clone
  * the skb and have it available in DSA_SKB_CB in the .port_deferred_xmit
  * callback, where we will timestamp it synchronously.
@@ -1766,6 +1828,7 @@ bool sja1105_port_txtstamp(struct dsa_switch *ds, int port,
 static const struct dsa_switch_ops sja1105_switch_ops = {
 	.get_tag_protocol	= sja1105_get_tag_protocol,
 	.setup			= sja1105_setup,
+	.teardown		= sja1105_teardown,
 	.set_ageing_time	= sja1105_set_ageing_time,
 	.phylink_validate	= sja1105_phylink_validate,
 	.phylink_mac_config	= sja1105_mac_config,
@@ -1787,6 +1850,7 @@ static const struct dsa_switch_ops sja1105_switch_ops = {
 	.port_mdb_add		= sja1105_mdb_add,
 	.port_mdb_del		= sja1105_mdb_del,
 	.port_deferred_xmit	= sja1105_port_deferred_xmit,
+	.port_rxtstamp		= sja1105_port_rxtstamp,
 	.port_txtstamp		= sja1105_port_txtstamp,
 };
 
@@ -1885,6 +1949,7 @@ static int sja1105_probe(struct spi_device *spi)
 
 	tagger_data = &priv->tagger_data;
 	skb_queue_head_init(&tagger_data->skb_rxtstamp_queue);
+	INIT_WORK(&tagger_data->rxtstamp_work, sja1105_rxtstamp_work);
 
 	/* Connections between dsa_port and sja1105_port */
 	for (i = 0; i < SJA1105_NUM_PORTS; i++) {
diff --git a/include/linux/dsa/sja1105.h b/include/linux/dsa/sja1105.h
index b83f6e428e5d..794ee76aae56 100644
--- a/include/linux/dsa/sja1105.h
+++ b/include/linux/dsa/sja1105.h
@@ -45,6 +45,13 @@ struct sja1105_tagger_data {
 	bool hwts_rx_en;
 };
 
+struct sja1105_skb_cb {
+	u32 meta_tstamp;
+};
+
+#define SJA1105_SKB_CB(skb) \
+	((struct sja1105_skb_cb *)DSA_SKB_CB_PRIV(skb))
+
 struct sja1105_port {
 	struct sja1105_tagger_data *data;
 	struct dsa_port *dp;
diff --git a/net/dsa/tag_sja1105.c b/net/dsa/tag_sja1105.c
index 6ec9a32dda62..aac48b42f210 100644
--- a/net/dsa/tag_sja1105.c
+++ b/net/dsa/tag_sja1105.c
@@ -94,6 +94,124 @@ static struct sk_buff *sja1105_xmit(struct sk_buff *skb,
 			     ((pcp << VLAN_PRIO_SHIFT) | tx_vid));
 }
 
+static void sja1105_transfer_meta(struct sk_buff *skb,
+				  const struct sja1105_meta *meta)
+{
+	struct ethhdr *hdr = eth_hdr(skb);
+
+	hdr->h_dest[3] = meta->dmac_byte_3;
+	hdr->h_dest[4] = meta->dmac_byte_4;
+	SJA1105_SKB_CB(skb)->meta_tstamp = meta->tstamp;
+}
+
+/* This is a simple state machine which follows the hardware mechanism of
+ * generating RX timestamps:
+ *
+ * After each timestampable skb (all traffic for which send_meta1 and
+ * send_meta0 is true, aka all MAC-filtered link-local traffic) a meta frame
+ * containing a partial timestamp is immediately generated by the switch and
+ * sent as a follow-up to the link-local frame on the CPU port.
+ *
+ * The meta frames have no unique identifier (such as sequence number) by which
+ * one may pair them to the correct timestampable frame.
+ * Instead, the switch has internal logic that ensures no frames are sent on
+ * the CPU port between a link-local timestampable frame and its corresponding
+ * meta follow-up. It also ensures strict ordering between ports (lower ports
+ * have higher priority towards the CPU port). For this reason, a per-port
+ * data structure is not needed/desirable.
+ *
+ * This function pairs the link-local frame with its partial timestamp from the
+ * meta follow-up frame. The full timestamp will be reconstructed later in a
+ * work queue.
+ */
+static struct sk_buff
+*sja1105_rcv_meta_state_machine(struct sk_buff *skb,
+				struct sja1105_meta *meta,
+				bool is_link_local,
+				bool is_meta)
+{
+	struct sja1105_port *sp;
+	struct dsa_port *dp;
+
+	dp = dsa_slave_to_port(skb->dev);
+	sp = dp->priv;
+
+	/* Step 1: A timestampable frame was received.
+	 * Buffer it until we get its meta frame.
+	 */
+	if (is_link_local && sp->data->hwts_rx_en) {
+		spin_lock(&sp->data->meta_lock);
+		/* Was this a link-local frame instead of the meta
+		 * that we were expecting?
+		 */
+		if (sp->data->stampable_skb) {
+			dev_err_ratelimited(dp->ds->dev,
+					    "Expected meta frame, is %12llx "
+					    "in the DSA master multicast filter?\n",
+					    SJA1105_META_DMAC);
+		}
+
+		/* Hold a reference to avoid dsa_switch_rcv
+		 * from freeing the skb.
+		 */
+		sp->data->stampable_skb = skb_get(skb);
+		spin_unlock(&sp->data->meta_lock);
+
+		/* Tell DSA we got nothing */
+		return NULL;
+
+	/* Step 2: The meta frame arrived.
+	 * Time to take the stampable skb out of the closet, annotate it
+	 * with the partial timestamp, and pretend that we received it
+	 * just now (basically masquerade the buffered frame as the meta
+	 * frame, which serves no further purpose).
+	 */
+	} else if (is_meta) {
+		struct sk_buff *stampable_skb;
+
+		spin_lock(&sp->data->meta_lock);
+
+		stampable_skb = sp->data->stampable_skb;
+		sp->data->stampable_skb = NULL;
+
+		/* Was this a meta frame instead of the link-local
+		 * that we were expecting?
+		 */
+		if (!stampable_skb) {
+			dev_err_ratelimited(dp->ds->dev,
+					    "Unexpected meta frame\n");
+			spin_unlock(&sp->data->meta_lock);
+			return NULL;
+		}
+
+		if (stampable_skb->dev != skb->dev) {
+			dev_err_ratelimited(dp->ds->dev,
+					    "Meta frame on wrong port\n");
+			spin_unlock(&sp->data->meta_lock);
+			return NULL;
+		}
+
+		/* Free the meta frame and give DSA the buffered stampable_skb
+		 * for further processing up the network stack.
+		 */
+		kfree_skb(skb);
+
+		skb = skb_copy(stampable_skb, GFP_ATOMIC);
+		if (!skb) {
+			dev_err_ratelimited(dp->ds->dev,
+					    "Failed to copy stampable skb\n");
+			return NULL;
+		}
+		sja1105_transfer_meta(skb, meta);
+		/* The cached copy will be freed now */
+		skb_unref(stampable_skb);
+
+		spin_unlock(&sp->data->meta_lock);
+	}
+
+	return skb;
+}
+
 static struct sk_buff *sja1105_rcv(struct sk_buff *skb,
 				   struct net_device *netdev,
 				   struct packet_type *pt)
@@ -151,7 +269,8 @@ static struct sk_buff *sja1105_rcv(struct sk_buff *skb,
 	if (is_tagged)
 		skb = dsa_8021q_remove_header(skb);
 
-	return skb;
+	return sja1105_rcv_meta_state_machine(skb, &meta, is_link_local,
+					      is_meta);
 }
 
 static struct dsa_device_ops sja1105_netdev_ops = {
-- 
2.17.1


^ permalink raw reply related	[flat|nested] 40+ messages in thread

* [PATCH v3 net-next 17/17] net: dsa: sja1105: Expose PTP timestamping ioctls to userspace
  2019-06-04 17:07 [PATCH v3 net-next 00/17] PTP support for the SJA1105 DSA driver Vladimir Oltean
                   ` (15 preceding siblings ...)
  2019-06-04 17:07 ` [PATCH v3 net-next 16/17] net: dsa: sja1105: Add a state machine for RX timestamping Vladimir Oltean
@ 2019-06-04 17:07 ` Vladimir Oltean
  2019-06-05  3:22 ` [PATCH v3 net-next 00/17] PTP support for the SJA1105 DSA driver David Miller
  17 siblings, 0 replies; 40+ messages in thread
From: Vladimir Oltean @ 2019-06-04 17:07 UTC (permalink / raw)
  To: f.fainelli, vivien.didelot, andrew, davem, richardcochran,
	john.stultz, tglx, sboyd
  Cc: linux-kernel, netdev, Vladimir Oltean

This enables the PTP support towards userspace applications such as
linuxptp.

The switches can timestamp only trapped multicast MAC frames, and
therefore only the profiles of 1588 over L2 are supported.

TX timestamping can be enabled per port, but RX timestamping is enabled
globally. As long as RX timestamping is enabled, the switch will emit
metadata follow-up frames that will be processed by the tagger. It may
be a problem that linuxptp does not restore the RX timestamping settings
when exiting.

Signed-off-by: Vladimir Oltean <olteanv@gmail.com>
---
Changes in v3:

Split from previous 09/10 patch (no functional changes).

Changes in v2:

None.

 drivers/net/dsa/sja1105/sja1105_main.c | 96 ++++++++++++++++++++++++++
 drivers/net/dsa/sja1105/sja1105_ptp.c  |  6 +-
 2 files changed, 100 insertions(+), 2 deletions(-)

diff --git a/drivers/net/dsa/sja1105/sja1105_main.c b/drivers/net/dsa/sja1105/sja1105_main.c
index 46a851f54b83..b68136c002bb 100644
--- a/drivers/net/dsa/sja1105/sja1105_main.c
+++ b/drivers/net/dsa/sja1105/sja1105_main.c
@@ -1755,6 +1755,100 @@ static int sja1105_set_ageing_time(struct dsa_switch *ds,
 	return sja1105_static_config_reload(priv);
 }
 
+/* Caller must hold priv->tagger_data.meta_lock */
+static int sja1105_change_rxtstamping(struct sja1105_private *priv,
+				      bool on)
+{
+	struct sja1105_general_params_entry *general_params;
+	struct sja1105_table *table;
+	int rc;
+
+	table = &priv->static_config.tables[BLK_IDX_GENERAL_PARAMS];
+	general_params = table->entries;
+	general_params->send_meta1 = on;
+	general_params->send_meta0 = on;
+
+	rc = sja1105_init_avb_params(priv, on);
+	if (rc < 0)
+		return rc;
+
+	/* Initialize the meta state machine to a known state */
+	if (priv->tagger_data.stampable_skb) {
+		kfree_skb(priv->tagger_data.stampable_skb);
+		priv->tagger_data.stampable_skb = NULL;
+	}
+
+	return sja1105_static_config_reload(priv);
+}
+
+static int sja1105_hwtstamp_set(struct dsa_switch *ds, int port,
+				struct ifreq *ifr)
+{
+	struct sja1105_private *priv = ds->priv;
+	struct hwtstamp_config config;
+	bool rx_on;
+	int rc;
+
+	if (copy_from_user(&config, ifr->ifr_data, sizeof(config)))
+		return -EFAULT;
+
+	switch (config.tx_type) {
+	case HWTSTAMP_TX_OFF:
+		priv->ports[port].hwts_tx_en = false;
+		break;
+	case HWTSTAMP_TX_ON:
+		priv->ports[port].hwts_tx_en = true;
+		break;
+	default:
+		return -ERANGE;
+	}
+
+	switch (config.rx_filter) {
+	case HWTSTAMP_FILTER_NONE:
+		rx_on = false;
+		break;
+	default:
+		rx_on = true;
+		break;
+	}
+
+	if (rx_on != priv->tagger_data.hwts_rx_en) {
+		spin_lock(&priv->tagger_data.meta_lock);
+		rc = sja1105_change_rxtstamping(priv, rx_on);
+		spin_unlock(&priv->tagger_data.meta_lock);
+		if (rc < 0) {
+			dev_err(ds->dev,
+				"Failed to change RX timestamping: %d\n", rc);
+			return -EFAULT;
+		}
+		priv->tagger_data.hwts_rx_en = rx_on;
+	}
+
+	if (copy_to_user(ifr->ifr_data, &config, sizeof(config)))
+		return -EFAULT;
+	return 0;
+}
+
+static int sja1105_hwtstamp_get(struct dsa_switch *ds, int port,
+				struct ifreq *ifr)
+{
+	struct sja1105_private *priv = ds->priv;
+	struct hwtstamp_config config;
+
+	config.flags = 0;
+	if (priv->ports[port].hwts_tx_en)
+		config.tx_type = HWTSTAMP_TX_ON;
+	else
+		config.tx_type = HWTSTAMP_TX_OFF;
+	if (priv->tagger_data.hwts_rx_en)
+		config.rx_filter = HWTSTAMP_FILTER_PTP_V2_L2_EVENT;
+	else
+		config.rx_filter = HWTSTAMP_FILTER_NONE;
+
+	return copy_to_user(ifr->ifr_data, &config, sizeof(config)) ?
+		-EFAULT : 0;
+}
+
 #define to_tagger(d) \
 	container_of((d), struct sja1105_tagger_data, rxtstamp_work)
 #define to_sja1105(d) \
@@ -1850,6 +1944,8 @@ static const struct dsa_switch_ops sja1105_switch_ops = {
 	.port_mdb_add		= sja1105_mdb_add,
 	.port_mdb_del		= sja1105_mdb_del,
 	.port_deferred_xmit	= sja1105_port_deferred_xmit,
+	.port_hwtstamp_get	= sja1105_hwtstamp_get,
+	.port_hwtstamp_set	= sja1105_hwtstamp_set,
 	.port_rxtstamp		= sja1105_port_rxtstamp,
 	.port_txtstamp		= sja1105_port_txtstamp,
 };
diff --git a/drivers/net/dsa/sja1105/sja1105_ptp.c b/drivers/net/dsa/sja1105/sja1105_ptp.c
index 1fce413a3fb4..c7ce1edd8471 100644
--- a/drivers/net/dsa/sja1105/sja1105_ptp.c
+++ b/drivers/net/dsa/sja1105/sja1105_ptp.c
@@ -70,8 +70,10 @@ int sja1105_get_ts_info(struct dsa_switch *ds, int port,
 	info->so_timestamping = SOF_TIMESTAMPING_TX_HARDWARE |
 				SOF_TIMESTAMPING_RX_HARDWARE |
 				SOF_TIMESTAMPING_RAW_HARDWARE;
-	info->tx_types = (1 << HWTSTAMP_TX_OFF);
-	info->rx_filters = (1 << HWTSTAMP_FILTER_NONE);
+	info->tx_types = (1 << HWTSTAMP_TX_OFF) |
+			 (1 << HWTSTAMP_TX_ON);
+	info->rx_filters = (1 << HWTSTAMP_FILTER_NONE) |
+			   (1 << HWTSTAMP_FILTER_PTP_V2_L2_EVENT);
 	info->phc_index = ptp_clock_index(priv->clock);
 	return 0;
 }
-- 
2.17.1


^ permalink raw reply related	[flat|nested] 40+ messages in thread

* Re: [PATCH v3 net-next 02/17] net: dsa: Add teardown callback for drivers
  2019-06-04 17:07 ` [PATCH v3 net-next 02/17] net: dsa: Add teardown callback for drivers Vladimir Oltean
@ 2019-06-04 18:15   ` Andrew Lunn
  2019-06-04 20:32   ` Florian Fainelli
  1 sibling, 0 replies; 40+ messages in thread
From: Andrew Lunn @ 2019-06-04 18:15 UTC (permalink / raw)
  To: Vladimir Oltean
  Cc: f.fainelli, vivien.didelot, davem, richardcochran, john.stultz,
	tglx, sboyd, linux-kernel, netdev

On Tue, Jun 04, 2019 at 08:07:41PM +0300, Vladimir Oltean wrote:
> This is helpful for e.g. draining per-driver (not per-port) tagger
> queues.
> 
> Signed-off-by: Vladimir Oltean <olteanv@gmail.com>

Reviewed-by: Andrew Lunn <andrew@lunn.ch>

    Andrew

^ permalink raw reply	[flat|nested] 40+ messages in thread

* Re: [PATCH v3 net-next 01/17] net: dsa: Keep a pointer to the skb clone for TX timestamping
  2019-06-04 17:07 ` [PATCH v3 net-next 01/17] net: dsa: Keep a pointer to the skb clone for TX timestamping Vladimir Oltean
@ 2019-06-04 20:31   ` Florian Fainelli
  0 siblings, 0 replies; 40+ messages in thread
From: Florian Fainelli @ 2019-06-04 20:31 UTC (permalink / raw)
  To: Vladimir Oltean, vivien.didelot, andrew, davem, richardcochran,
	john.stultz, tglx, sboyd
  Cc: linux-kernel, netdev



On 6/4/2019 10:07 AM, Vladimir Oltean wrote:
> For drivers that use deferred_xmit for PTP frames (such as sja1105),
> there is no need to perform matching between PTP frames and their egress
> timestamps, since the sending process can be serialized.
> 
> In that case, it makes sense to have the pointer to the skb clone that
> DSA made directly in the skb->cb. It will be used for pushing the egress
> timestamp back in the application socket's error queue.
> 
> Signed-off-by: Vladimir Oltean <olteanv@gmail.com>

Reviewed-by: Florian Fainelli <f.fainelli@gmail.com>
-- 
Florian

^ permalink raw reply	[flat|nested] 40+ messages in thread

* Re: [PATCH v3 net-next 02/17] net: dsa: Add teardown callback for drivers
  2019-06-04 17:07 ` [PATCH v3 net-next 02/17] net: dsa: Add teardown callback for drivers Vladimir Oltean
  2019-06-04 18:15   ` Andrew Lunn
@ 2019-06-04 20:32   ` Florian Fainelli
  1 sibling, 0 replies; 40+ messages in thread
From: Florian Fainelli @ 2019-06-04 20:32 UTC (permalink / raw)
  To: Vladimir Oltean, vivien.didelot, andrew, davem, richardcochran,
	john.stultz, tglx, sboyd
  Cc: linux-kernel, netdev



On 6/4/2019 10:07 AM, Vladimir Oltean wrote:
> This is helpful for e.g. draining per-driver (not per-port) tagger
> queues.
> 
> Signed-off-by: Vladimir Oltean <olteanv@gmail.com>

Reviewed-by: Florian Fainelli <f.fainelli@gmail.com>
-- 
Florian

^ permalink raw reply	[flat|nested] 40+ messages in thread

* Re: [PATCH v3 net-next 05/17] net: dsa: sja1105: Reverse TPID and TPID2
  2019-06-04 17:07 ` [PATCH v3 net-next 05/17] net: dsa: sja1105: Reverse TPID and TPID2 Vladimir Oltean
@ 2019-06-04 20:33   ` Florian Fainelli
  0 siblings, 0 replies; 40+ messages in thread
From: Florian Fainelli @ 2019-06-04 20:33 UTC (permalink / raw)
  To: Vladimir Oltean, vivien.didelot, andrew, davem, richardcochran,
	john.stultz, tglx, sboyd
  Cc: linux-kernel, netdev



On 6/4/2019 10:07 AM, Vladimir Oltean wrote:
> From reading the P/Q/R/S user manual, it appears that TPID is used by
> the switch for detecting S-tags and TPID2 for C-tags.  Their meaning is
> not clear from the E/T manual.
> 
> Signed-off-by: Vladimir Oltean <olteanv@gmail.com>


Reviewed-by: Florian Fainelli <f.fainelli@gmail.com>
-- 
Florian

^ permalink raw reply	[flat|nested] 40+ messages in thread

* Re: [PATCH v3 net-next 06/17] net: dsa: sja1105: Limit use of incl_srcpt to bridge+vlan mode
  2019-06-04 17:07 ` [PATCH v3 net-next 06/17] net: dsa: sja1105: Limit use of incl_srcpt to bridge+vlan mode Vladimir Oltean
@ 2019-06-04 20:35   ` Florian Fainelli
  0 siblings, 0 replies; 40+ messages in thread
From: Florian Fainelli @ 2019-06-04 20:35 UTC (permalink / raw)
  To: Vladimir Oltean, vivien.didelot, andrew, davem, richardcochran,
	john.stultz, tglx, sboyd
  Cc: linux-kernel, netdev



On 6/4/2019 10:07 AM, Vladimir Oltean wrote:
> The incl_srcpt setting makes the switch mangle the destination MACs of
> multicast frames trapped to the CPU - a primitive tagging mechanism that
> works even when we cannot use the 802.1Q software features.
> 
> The downside is that the two multicast MAC addresses that the switch
> traps for L2 PTP (01-80-C2-00-00-0E and 01-1B-19-00-00-00) quickly turn
> into a lot more, as the switch encodes the source port and switch id
> into bytes 3 and 4 of the MAC. The resulting range of MAC addresses
> would need to be installed manually into the DSA master port's multicast
> MAC filter, and even then, most devices might not have a large enough
> MAC filtering table.
> 
> As a result, only limit use of incl_srcpt to when it's strictly
> necessary: when under a VLAN filtering bridge.  This fixes PTP in
> non-bridged mode (standalone ports). Otherwise, PTP frames, as well as
> metadata follow-up frames holding RX timestamps won't be received
> because they will be blocked by the master port's MAC filter.
> Linuxptp doesn't help, because it only requests the addition of the
> unmodified PTP MACs to the multicast filter.
> This issue is not seen in bridged mode because the master port is put in
> promiscuous mode when the slave ports are enslaved to a bridge.
> Therefore, there is no downside to having the incl_srcpt mechanism
> active there.
> 
> Signed-off-by: Vladimir Oltean <olteanv@gmail.com>

Reviewed-by: Florian Fainelli <f.fainelli@gmail.com>
-- 
Florian

^ permalink raw reply	[flat|nested] 40+ messages in thread

* Re: [PATCH v3 net-next 08/17] net: dsa: sja1105: Move sja1105_is_link_local to include/linux
  2019-06-04 17:07 ` [PATCH v3 net-next 08/17] net: dsa: sja1105: Move sja1105_is_link_local to include/linux Vladimir Oltean
@ 2019-06-04 20:35   ` Florian Fainelli
  0 siblings, 0 replies; 40+ messages in thread
From: Florian Fainelli @ 2019-06-04 20:35 UTC (permalink / raw)
  To: Vladimir Oltean, vivien.didelot, andrew, davem, richardcochran,
	john.stultz, tglx, sboyd
  Cc: linux-kernel, netdev



On 6/4/2019 10:07 AM, Vladimir Oltean wrote:
> This function will be reused from the .port_rxtstamp callback to see if
> the received SKB can be timestamped by the switch.
> 
> Signed-off-by: Vladimir Oltean <olteanv@gmail.com>

Reviewed-by: Florian Fainelli <f.fainelli@gmail.com>
-- 
Florian

^ permalink raw reply	[flat|nested] 40+ messages in thread

* Re: [PATCH v3 net-next 04/17] net: dsa: sja1105: Move sja1105_change_tpid into sja1105_vlan_filtering
  2019-06-04 17:07 ` [PATCH v3 net-next 04/17] net: dsa: sja1105: Move sja1105_change_tpid into sja1105_vlan_filtering Vladimir Oltean
@ 2019-06-04 20:58   ` Florian Fainelli
  0 siblings, 0 replies; 40+ messages in thread
From: Florian Fainelli @ 2019-06-04 20:58 UTC (permalink / raw)
  To: Vladimir Oltean, vivien.didelot, andrew, davem, richardcochran,
	john.stultz, tglx, sboyd
  Cc: linux-kernel, netdev



On 6/4/2019 10:07 AM, Vladimir Oltean wrote:
> This is a cosmetic patch, pre-cursor to making another change to the
> General Parameters Table (incl_srcpt) which does not logically pertain
> to the sja1105_change_tpid function name, but not putting it there would
> otherwise create a need of resetting the switch twice.
> 
> So simply move the existing code into the .port_vlan_filtering callback,
> where the incl_srcpt change will be added as well.
> 
> Signed-off-by: Vladimir Oltean <olteanv@gmail.com>

Reviewed-by: Florian Fainelli <f.fainelli@gmail.com>
-- 
Florian

^ permalink raw reply	[flat|nested] 40+ messages in thread

* Re: [PATCH v3 net-next 10/17] net: dsa: sja1105: Build a minimal understanding of meta frames
  2019-06-04 17:07 ` [PATCH v3 net-next 10/17] net: dsa: sja1105: Build a minimal understanding of meta frames Vladimir Oltean
@ 2019-06-04 21:00   ` Florian Fainelli
  0 siblings, 0 replies; 40+ messages in thread
From: Florian Fainelli @ 2019-06-04 21:00 UTC (permalink / raw)
  To: Vladimir Oltean, vivien.didelot, andrew, davem, richardcochran,
	john.stultz, tglx, sboyd
  Cc: linux-kernel, netdev



On 6/4/2019 10:07 AM, Vladimir Oltean wrote:
> Meta frames are sent on the CPU port by the switch if RX timestamping is
> enabled. They contain a partial timestamp of the previous frame.
> 
> They are Ethernet frames with the Ethernet header constructed out of:
> 
> - SJA1105_META_DMAC
> - SJA1105_META_SMAC
> - ETH_P_SJA1105_META
> 
> The Ethernet payload will be decoded in a follow-up patch.
> 
> Signed-off-by: Vladimir Oltean <olteanv@gmail.com>

Reviewed-by: Florian Fainelli <f.fainelli@gmail.com>
-- 
Florian

^ permalink raw reply	[flat|nested] 40+ messages in thread

* Re: [PATCH v3 net-next 00/17] PTP support for the SJA1105 DSA driver
  2019-06-04 17:07 [PATCH v3 net-next 00/17] PTP support for the SJA1105 DSA driver Vladimir Oltean
                   ` (16 preceding siblings ...)
  2019-06-04 17:07 ` [PATCH v3 net-next 17/17] net: dsa: sja1105: Expose PTP timestamping ioctls to userspace Vladimir Oltean
@ 2019-06-05  3:22 ` David Miller
  2019-06-05  9:13   ` Vladimir Oltean
  17 siblings, 1 reply; 40+ messages in thread
From: David Miller @ 2019-06-05  3:22 UTC (permalink / raw)
  To: olteanv
  Cc: f.fainelli, vivien.didelot, andrew, richardcochran, john.stultz,
	tglx, sboyd, linux-kernel, netdev

From: Vladimir Oltean <olteanv@gmail.com>
Date: Tue,  4 Jun 2019 20:07:39 +0300

> This patchset adds the following:
> 
>  - A timecounter/cyclecounter based PHC for the free-running
>    timestamping clock of this switch.
> 
>  - A state machine implemented in the DSA tagger for SJA1105, which
>    keeps track of metadata follow-up Ethernet frames (the switch's way
>    of transmitting RX timestamps).

This series doesn't apply cleanly to net-next, please respin.

Thank you.

^ permalink raw reply	[flat|nested] 40+ messages in thread

* Re: [PATCH v3 net-next 00/17] PTP support for the SJA1105 DSA driver
  2019-06-05  3:22 ` [PATCH v3 net-next 00/17] PTP support for the SJA1105 DSA driver David Miller
@ 2019-06-05  9:13   ` Vladimir Oltean
  2019-06-05 11:33     ` Vladimir Oltean
  2019-06-05 18:44     ` David Miller
  0 siblings, 2 replies; 40+ messages in thread
From: Vladimir Oltean @ 2019-06-05  9:13 UTC (permalink / raw)
  To: David Miller
  Cc: Florian Fainelli, Vivien Didelot, Andrew Lunn, Richard Cochran,
	John Stultz, Thomas Gleixner, Stephen Boyd, lkml, netdev

On Wed, 5 Jun 2019 at 06:23, David Miller <davem@davemloft.net> wrote:
>
> From: Vladimir Oltean <olteanv@gmail.com>
> Date: Tue,  4 Jun 2019 20:07:39 +0300
>
> > This patchset adds the following:
> >
> >  - A timecounter/cyclecounter based PHC for the free-running
> >    timestamping clock of this switch.
> >
> >  - A state machine implemented in the DSA tagger for SJA1105, which
> >    keeps track of metadata follow-up Ethernet frames (the switch's way
> >    of transmitting RX timestamps).
>
> This series doesn't apply cleanly to net-next, please respin.
>
> Thank you.

Hi Dave,

It is conflicting because net-next at the moment lacks this patch that
I submitted to net:
https://git.kernel.org/pub/scm/linux/kernel/git/davem/net.git/commit/?id=e8d67fa5696e2fcaf956dae36d11e6eff5246101
What would you like me to do: resubmit after you merge net into
net-next, add the above patch to this series (which you'll have to
skip upon the next merge), or you can just cherry-pick it and then the
series will apply?

Thanks!
-Vladimir

^ permalink raw reply	[flat|nested] 40+ messages in thread

* Re: [PATCH v3 net-next 00/17] PTP support for the SJA1105 DSA driver
  2019-06-05  9:13   ` Vladimir Oltean
@ 2019-06-05 11:33     ` Vladimir Oltean
  2019-06-05 17:45       ` Richard Cochran
  2019-06-05 18:44     ` David Miller
  1 sibling, 1 reply; 40+ messages in thread
From: Vladimir Oltean @ 2019-06-05 11:33 UTC (permalink / raw)
  To: David Miller
  Cc: Florian Fainelli, Vivien Didelot, Andrew Lunn, Richard Cochran,
	John Stultz, Thomas Gleixner, Stephen Boyd, lkml, netdev

On Wed, 5 Jun 2019 at 12:13, Vladimir Oltean <olteanv@gmail.com> wrote:
>
> On Wed, 5 Jun 2019 at 06:23, David Miller <davem@davemloft.net> wrote:
> >
> > From: Vladimir Oltean <olteanv@gmail.com>
> > Date: Tue,  4 Jun 2019 20:07:39 +0300
> >
> > > This patchset adds the following:
> > >
> > >  - A timecounter/cyclecounter based PHC for the free-running
> > >    timestamping clock of this switch.
> > >
> > >  - A state machine implemented in the DSA tagger for SJA1105, which
> > >    keeps track of metadata follow-up Ethernet frames (the switch's way
> > >    of transmitting RX timestamps).
> >
> > This series doesn't apply cleanly to net-next, please respin.
> >
> > Thank you.
>
> Hi Dave,
>
> It is conflicting because net-next at the moment lacks this patch that
> I submitted to net:
> https://git.kernel.org/pub/scm/linux/kernel/git/davem/net.git/commit/?id=e8d67fa5696e2fcaf956dae36d11e6eff5246101
> What would you like me to do: resubmit after you merge net into
> net-next, add the above patch to this series (which you'll have to
> skip upon the next merge), or you can just cherry-pick it and then the
> series will apply?
>
> Thanks!
> -Vladimir

In the meantime: Richard, do you have any objections to this patchset?
I was wondering whether the path delay difference between E2E and P2P
rings any bell to you.

Thank you,
-Vladimir

^ permalink raw reply	[flat|nested] 40+ messages in thread

* Re: [PATCH v3 net-next 00/17] PTP support for the SJA1105 DSA driver
  2019-06-05 11:33     ` Vladimir Oltean
@ 2019-06-05 17:45       ` Richard Cochran
  2019-06-05 17:50         ` Vladimir Oltean
  2019-06-05 18:08         ` Vladimir Oltean
  0 siblings, 2 replies; 40+ messages in thread
From: Richard Cochran @ 2019-06-05 17:45 UTC (permalink / raw)
  To: Vladimir Oltean
  Cc: David Miller, Florian Fainelli, Vivien Didelot, Andrew Lunn,
	John Stultz, Thomas Gleixner, Stephen Boyd, lkml, netdev

On Wed, Jun 05, 2019 at 02:33:52PM +0300, Vladimir Oltean wrote:
> In the meantime: Richard, do you have any objections to this patchset?

I like the fact that you didn't have to change the dsa or ptp
frameworks this time around.  I haven't taken a closer look than that
yet.

> I was wondering whether the path delay difference between E2E and P2P
> rings any bell to you.

Can it be that the switch applies corrections in HW?

Thanks,
Richard

^ permalink raw reply	[flat|nested] 40+ messages in thread

* Re: [PATCH v3 net-next 00/17] PTP support for the SJA1105 DSA driver
  2019-06-05 17:45       ` Richard Cochran
@ 2019-06-05 17:50         ` Vladimir Oltean
  2019-06-05 17:52           ` Vladimir Oltean
  2019-06-05 18:08         ` Vladimir Oltean
  1 sibling, 1 reply; 40+ messages in thread
From: Vladimir Oltean @ 2019-06-05 17:50 UTC (permalink / raw)
  To: Richard Cochran
  Cc: David Miller, Florian Fainelli, Vivien Didelot, Andrew Lunn,
	John Stultz, Thomas Gleixner, Stephen Boyd, lkml, netdev

On Wed, 5 Jun 2019 at 20:45, Richard Cochran <richardcochran@gmail.com> wrote:
>
> On Wed, Jun 05, 2019 at 02:33:52PM +0300, Vladimir Oltean wrote:
> > In the meantime: Richard, do you have any objections to this patchset?
>
> I like the fact that you didn't have to change the dsa or ptp
> frameworks this time around.  I haven't taken a closer look than that
> yet.
>
> > I was wondering whether the path delay difference between E2E and P2P
> > rings any bell to you.
>
> Can it be that the switch applies corrections in HW?
>

Yes it can be. It was one of the first things I thought of.
Normally it updates the correction field with its own residence time
in 1-step L2 event messages (but I use 2 step).
It also has a bit called IGNORE2STF (ignore 2-step flag) by which it
updates the correction field in all L2 event messages (including sync,
thereby violating the spec for a switch, as far as I'm aware). But I'm
not setting it.
I also looked at egress frames with wireshark and the correction field is zero.

> Thanks,
> Richard

Thanks,
-Vladimir

^ permalink raw reply	[flat|nested] 40+ messages in thread

* Re: [PATCH v3 net-next 00/17] PTP support for the SJA1105 DSA driver
  2019-06-05 17:50         ` Vladimir Oltean
@ 2019-06-05 17:52           ` Vladimir Oltean
  0 siblings, 0 replies; 40+ messages in thread
From: Vladimir Oltean @ 2019-06-05 17:52 UTC (permalink / raw)
  To: Richard Cochran
  Cc: David Miller, Florian Fainelli, Vivien Didelot, Andrew Lunn,
	John Stultz, Thomas Gleixner, Stephen Boyd, lkml, netdev

On Wed, 5 Jun 2019 at 20:50, Vladimir Oltean <olteanv@gmail.com> wrote:
>
> On Wed, 5 Jun 2019 at 20:45, Richard Cochran <richardcochran@gmail.com> wrote:
> >
> > On Wed, Jun 05, 2019 at 02:33:52PM +0300, Vladimir Oltean wrote:
> > > In the meantime: Richard, do you have any objections to this patchset?
> >
> > I like the fact that you didn't have to change the dsa or ptp
> > frameworks this time around.  I haven't taken a closer look than that
> > yet.
> >
> > > I was wondering whether the path delay difference between E2E and P2P
> > > rings any bell to you.
> >
> > Can it be that the switch applies corrections in HW?
> >
>
> Yes it can be. It was one of the first things I thought of.
> Normally it updates the correction field with its own residence time
> in 1-step L2 event messages (but I use 2 step).
> It also has a bit called IGNORE2STF (ignore 2-step flag) by which it
> updates the correction field in all L2 event messages (including sync,
> thereby violating the spec for a switch, as far as I'm aware). But I'm
> not setting it.
> I also looked at egress frames with wireshark and the correction field is zero.
>

I also changed around the values of ptp_dst_mac and p2p_dst_mac in
linuxptp in the hope that I'd throw off whatever hardware parser it
has to identify the event frames, but I still get negative path delay
with E2E nonetheless. So it's probably not that.

> > Thanks,
> > Richard
>
> Thanks,
> -Vladimir

-Vladimir

^ permalink raw reply	[flat|nested] 40+ messages in thread

* Re: [PATCH v3 net-next 00/17] PTP support for the SJA1105 DSA driver
  2019-06-05 17:45       ` Richard Cochran
  2019-06-05 17:50         ` Vladimir Oltean
@ 2019-06-05 18:08         ` Vladimir Oltean
  2019-06-06  3:11           ` Richard Cochran
  1 sibling, 1 reply; 40+ messages in thread
From: Vladimir Oltean @ 2019-06-05 18:08 UTC (permalink / raw)
  To: Richard Cochran
  Cc: David Miller, Florian Fainelli, Vivien Didelot, Andrew Lunn,
	John Stultz, Thomas Gleixner, Stephen Boyd, lkml, netdev

On Wed, 5 Jun 2019 at 20:45, Richard Cochran <richardcochran@gmail.com> wrote:
>
> On Wed, Jun 05, 2019 at 02:33:52PM +0300, Vladimir Oltean wrote:
> > In the meantime: Richard, do you have any objections to this patchset?
>
> I like the fact that you didn't have to change the dsa or ptp
> frameworks this time around.  I haven't taken a closer look than that
> yet.
>

There's one more thing I wanted to ask you if you get the chance to
take a closer look.
Currently I'm using a cyclecounter, but I *will* need actual PHC
manipulations for the time-based shaping and policing features that
the switch has in hardware. On the other hand I get much tighter sync
offset using the free-running counter than with hardware-corrected
timestamps. So as far as I see it, I'll need to have two sets of
operations.
How should I design such a dual-PHC device driver? Just register two
separate clocks, one for the timestamping counter, the other for the
scheduling/policing PTP clock, and have phc2sys keep them in sync
externally to the driver? Or implement the hardware corrections
alongside the timecounter ones, and expose a single PHC (and for
clock_gettime, just pick one of the time sources)?

> > I was wondering whether the path delay difference between E2E and P2P
> > rings any bell to you.
>
> Can it be that the switch applies corrections in HW?
>
> Thanks,
> Richard

Thanks,
-Vladimir

^ permalink raw reply	[flat|nested] 40+ messages in thread

* Re: [PATCH v3 net-next 00/17] PTP support for the SJA1105 DSA driver
  2019-06-05  9:13   ` Vladimir Oltean
  2019-06-05 11:33     ` Vladimir Oltean
@ 2019-06-05 18:44     ` David Miller
  2019-06-07 19:15       ` David Miller
  1 sibling, 1 reply; 40+ messages in thread
From: David Miller @ 2019-06-05 18:44 UTC (permalink / raw)
  To: olteanv
  Cc: f.fainelli, vivien.didelot, andrew, richardcochran, john.stultz,
	tglx, sboyd, linux-kernel, netdev

From: Vladimir Oltean <olteanv@gmail.com>
Date: Wed, 5 Jun 2019 12:13:59 +0300

> On Wed, 5 Jun 2019 at 06:23, David Miller <davem@davemloft.net> wrote:
>>
>> From: Vladimir Oltean <olteanv@gmail.com>
>> Date: Tue,  4 Jun 2019 20:07:39 +0300
>>
>> > This patchset adds the following:
>> >
>> >  - A timecounter/cyclecounter based PHC for the free-running
>> >    timestamping clock of this switch.
>> >
>> >  - A state machine implemented in the DSA tagger for SJA1105, which
>> >    keeps track of metadata follow-up Ethernet frames (the switch's way
>> >    of transmitting RX timestamps).
>>
>> This series doesn't apply cleanly to net-next, please respin.
>>
>> Thank you.
> 
> Hi Dave,
> 
> It is conflicting because net-next at the moment lacks this patch that
> I submitted to net:
> https://git.kernel.org/pub/scm/linux/kernel/git/davem/net.git/commit/?id=e8d67fa5696e2fcaf956dae36d11e6eff5246101
> What would you like me to do: resubmit after you merge net into
> net-next, add the above patch to this series (which you'll have to
> skip upon the next merge), or you can just cherry-pick it and then the
> series will apply?

So let me bring this series back to state "Under Review" and I'll apply it
after I next merge net into net-next.

Thanks for letting me know.

^ permalink raw reply	[flat|nested] 40+ messages in thread

* Re: [PATCH v3 net-next 00/17] PTP support for the SJA1105 DSA driver
  2019-06-05 18:08         ` Vladimir Oltean
@ 2019-06-06  3:11           ` Richard Cochran
  2019-06-06 13:40             ` Vladimir Oltean
  0 siblings, 1 reply; 40+ messages in thread
From: Richard Cochran @ 2019-06-06  3:11 UTC (permalink / raw)
  To: Vladimir Oltean
  Cc: David Miller, Florian Fainelli, Vivien Didelot, Andrew Lunn,
	John Stultz, Thomas Gleixner, Stephen Boyd, lkml, netdev

On Wed, Jun 05, 2019 at 09:08:54PM +0300, Vladimir Oltean wrote:
> Currently I'm using a cyclecounter, but I *will* need actual PHC
> manipulations for the time-based shaping and policing features that
> the switch has in hardware.

Okay.

> On the other hand I get much tighter sync
> offset using the free-running counter than with hardware-corrected
> timestamps.

Why?  The time stamps come from the very same counter, don't they?

> So as far as I see it, I'll need to have two sets of
> operations.

I doubt very much that this will work well.

> How should I design such a dual-PHC device driver? Just register two
> separate clocks, one for the timestamping counter, the other for the
> scheduling/policing PTP clock, and have phc2sys keep them in sync
> externally to the driver?

But how would phc2sys do this?  By comparing clock_gettime() values?
That would surely introduce unnecessary time error.

> Or implement the hardware corrections
> alongside the timecounter ones, and expose a single PHC (and for
> clock_gettime, just pick one of the time sources)?

I would implement the hardware clock and drop the timecounter
altogether.

HTH,
Richard

^ permalink raw reply	[flat|nested] 40+ messages in thread

* Re: [PATCH v3 net-next 00/17] PTP support for the SJA1105 DSA driver
  2019-06-06  3:11           ` Richard Cochran
@ 2019-06-06 13:40             ` Vladimir Oltean
  2019-06-07  3:32               ` Richard Cochran
  0 siblings, 1 reply; 40+ messages in thread
From: Vladimir Oltean @ 2019-06-06 13:40 UTC (permalink / raw)
  To: Richard Cochran
  Cc: David Miller, Florian Fainelli, Vivien Didelot, Andrew Lunn,
	John Stultz, Thomas Gleixner, Stephen Boyd, lkml, netdev

On Thu, 6 Jun 2019 at 06:11, Richard Cochran <richardcochran@gmail.com> wrote:
>
> On Wed, Jun 05, 2019 at 09:08:54PM +0300, Vladimir Oltean wrote:
> > Currently I'm using a cyclecounter, but I *will* need actual PHC
> > manipulations for the time-based shaping and policing features that
> > the switch has in hardware.
>
> Okay.
>
> > On the other hand I get much tighter sync
> > offset using the free-running counter than with hardware-corrected
> > timestamps.
>
> Why?  The time stamps come from the very same counter, don't they?
>

Plain and simply because it doesn't work very well.
Even phc2sys from the system clock to the hardware (no timestamps
involved) has trouble staying put (under 1000 ns offset).
And using the hardware-corrected timestamps triggers a lot of clockchecks.

> > So as far as I see it, I'll need to have two sets of
> > operations.
>
> I doubt very much that this will work well.
>
> > How should I design such a dual-PHC device driver? Just register two
> > separate clocks, one for the timestamping counter, the other for the
> > scheduling/policing PTP clock, and have phc2sys keep them in sync
> > externally to the driver?
>
> But how would phc2sys do this?  By comparing clock_gettime() values?
> That would surely introduce unnecessary time error.
>
> > Or implement the hardware corrections
> > alongside the timecounter ones, and expose a single PHC (and for
> > clock_gettime, just pick one of the time sources)?
>
> I would implement the hardware clock and drop the timecounter
> altogether.
>
> HTH,
> Richard

^ permalink raw reply	[flat|nested] 40+ messages in thread

* Re: [PATCH v3 net-next 00/17] PTP support for the SJA1105 DSA driver
  2019-06-06 13:40             ` Vladimir Oltean
@ 2019-06-07  3:32               ` Richard Cochran
  2019-06-07  9:43                 ` Vladimir Oltean
  0 siblings, 1 reply; 40+ messages in thread
From: Richard Cochran @ 2019-06-07  3:32 UTC (permalink / raw)
  To: Vladimir Oltean
  Cc: David Miller, Florian Fainelli, Vivien Didelot, Andrew Lunn,
	John Stultz, Thomas Gleixner, Stephen Boyd, lkml, netdev

On Thu, Jun 06, 2019 at 04:40:19PM +0300, Vladimir Oltean wrote:
> Plain and simply because it doesn't work very well.
> Even phc2sys from the system clock to the hardware (no timestamps
> involved) has trouble staying put (under 1000 ns offset).
> And using the hardware-corrected timestamps triggers a lot of clockchecks.

It sounds like a bug in reading or adjusting the HW clock.  Is the HW
clock stable when you don't adjust its frequency?

Thanks,
Richard




^ permalink raw reply	[flat|nested] 40+ messages in thread

* Re: [PATCH v3 net-next 00/17] PTP support for the SJA1105 DSA driver
  2019-06-07  3:32               ` Richard Cochran
@ 2019-06-07  9:43                 ` Vladimir Oltean
  0 siblings, 0 replies; 40+ messages in thread
From: Vladimir Oltean @ 2019-06-07  9:43 UTC (permalink / raw)
  To: Richard Cochran
  Cc: David Miller, Florian Fainelli, Vivien Didelot, Andrew Lunn,
	John Stultz, Thomas Gleixner, Stephen Boyd, lkml, netdev

On Fri, 7 Jun 2019 at 06:32, Richard Cochran <richardcochran@gmail.com> wrote:
>
> On Thu, Jun 06, 2019 at 04:40:19PM +0300, Vladimir Oltean wrote:
> > Plain and simply because it doesn't work very well.
> > Even phc2sys from the system clock to the hardware (no timestamps
> > involved) has trouble staying put (under 1000 ns offset).
> > And using the hardware-corrected timestamps triggers a lot of clockchecks.
>
> It sounds like a bug in reading or adjusting the HW clock.  Is the HW
> clock stable when you don't adjust its frequency?

How can I tell that for sure?

>
> Thanks,
> Richard

^ permalink raw reply	[flat|nested] 40+ messages in thread

* Re: [PATCH v3 net-next 00/17] PTP support for the SJA1105 DSA driver
  2019-06-05 18:44     ` David Miller
@ 2019-06-07 19:15       ` David Miller
  2019-06-07 19:38         ` Vladimir Oltean
  0 siblings, 1 reply; 40+ messages in thread
From: David Miller @ 2019-06-07 19:15 UTC (permalink / raw)
  To: olteanv
  Cc: f.fainelli, vivien.didelot, andrew, richardcochran, john.stultz,
	tglx, sboyd, linux-kernel, netdev

From: David Miller <davem@davemloft.net>
Date: Wed, 05 Jun 2019 11:44:29 -0700 (PDT)

> From: Vladimir Oltean <olteanv@gmail.com>
> Date: Wed, 5 Jun 2019 12:13:59 +0300
> 
>> It is conflicting because net-next at the moment lacks this patch that
>> I submitted to net:
>> https://git.kernel.org/pub/scm/linux/kernel/git/davem/net.git/commit/?id=e8d67fa5696e2fcaf956dae36d11e6eff5246101
>> What would you like me to do: resubmit after you merge net into
>> net-next, add the above patch to this series (which you'll have to
>> skip upon the next merge), or you can just cherry-pick it and then the
>> series will apply?
> 
> So let me bring this series back to state "Under Review" and I'll apply it
> after I next merge net into net-next.

So I applied the series but it doesn't even build:

ERROR: "sja1105_unpack" [drivers/net/dsa/sja1105/sja1105_ptp.ko] undefined!
ERROR: "sja1105_spi_send_packed_buf" [drivers/net/dsa/sja1105/sja1105_ptp.ko] undefined!
ERROR: "sja1105_pack" [drivers/net/dsa/sja1105/sja1105_ptp.ko] undefined!
ERROR: "sja1105_spi_send_int" [drivers/net/dsa/sja1105/sja1105_ptp.ko] undefined!
ERROR: "sja1105_get_ts_info" [drivers/net/dsa/sja1105/sja1105.ko] undefined!
ERROR: "sja1105pqrs_ptp_cmd" [drivers/net/dsa/sja1105/sja1105.ko] undefined!
ERROR: "sja1105_ptp_clock_unregister" [drivers/net/dsa/sja1105/sja1105.ko] undefined!
ERROR: "sja1105_ptpegr_ts_poll" [drivers/net/dsa/sja1105/sja1105.ko] undefined!
ERROR: "sja1105et_ptp_cmd" [drivers/net/dsa/sja1105/sja1105.ko] undefined!
ERROR: "sja1105_ptp_reset" [drivers/net/dsa/sja1105/sja1105.ko] undefined!
ERROR: "sja1105_tstamp_reconstruct" [drivers/net/dsa/sja1105/sja1105.ko] undefined!
ERROR: "sja1105_ptp_clock_register" [drivers/net/dsa/sja1105/sja1105.ko] undefined!

You have to test better with the various modular/non-modular combinations.

Thanks.

^ permalink raw reply	[flat|nested] 40+ messages in thread

* Re: [PATCH v3 net-next 00/17] PTP support for the SJA1105 DSA driver
  2019-06-07 19:15       ` David Miller
@ 2019-06-07 19:38         ` Vladimir Oltean
  0 siblings, 0 replies; 40+ messages in thread
From: Vladimir Oltean @ 2019-06-07 19:38 UTC (permalink / raw)
  To: David Miller
  Cc: Florian Fainelli, Vivien Didelot, Andrew Lunn, Richard Cochran,
	John Stultz, Thomas Gleixner, Stephen Boyd, lkml, netdev

On Fri, 7 Jun 2019 at 22:15, David Miller <davem@davemloft.net> wrote:
>
> From: David Miller <davem@davemloft.net>
> Date: Wed, 05 Jun 2019 11:44:29 -0700 (PDT)
>
> > From: Vladimir Oltean <olteanv@gmail.com>
> > Date: Wed, 5 Jun 2019 12:13:59 +0300
> >
> >> It is conflicting because net-next at the moment lacks this patch that
> >> I submitted to net:
> >> https://git.kernel.org/pub/scm/linux/kernel/git/davem/net.git/commit/?id=e8d67fa5696e2fcaf956dae36d11e6eff5246101
> >> What would you like me to do: resubmit after you merge net into
> >> net-next, add the above patch to this series (which you'll have to
> >> skip upon the next merge), or you can just cherry-pick it and then the
> >> series will apply?
> >
> > So let me bring this series back to state "Under Review" and I'll apply it
> > after I next merge net into net-next.
>
> So I applied the series but it doesn't even build:
>
> ERROR: "sja1105_unpack" [drivers/net/dsa/sja1105/sja1105_ptp.ko] undefined!
> ERROR: "sja1105_spi_send_packed_buf" [drivers/net/dsa/sja1105/sja1105_ptp.ko] undefined!
> ERROR: "sja1105_pack" [drivers/net/dsa/sja1105/sja1105_ptp.ko] undefined!
> ERROR: "sja1105_spi_send_int" [drivers/net/dsa/sja1105/sja1105_ptp.ko] undefined!
> ERROR: "sja1105_get_ts_info" [drivers/net/dsa/sja1105/sja1105.ko] undefined!
> ERROR: "sja1105pqrs_ptp_cmd" [drivers/net/dsa/sja1105/sja1105.ko] undefined!
> ERROR: "sja1105_ptp_clock_unregister" [drivers/net/dsa/sja1105/sja1105.ko] undefined!
> ERROR: "sja1105_ptpegr_ts_poll" [drivers/net/dsa/sja1105/sja1105.ko] undefined!
> ERROR: "sja1105et_ptp_cmd" [drivers/net/dsa/sja1105/sja1105.ko] undefined!
> ERROR: "sja1105_ptp_reset" [drivers/net/dsa/sja1105/sja1105.ko] undefined!
> ERROR: "sja1105_tstamp_reconstruct" [drivers/net/dsa/sja1105/sja1105.ko] undefined!
> ERROR: "sja1105_ptp_clock_register" [drivers/net/dsa/sja1105/sja1105.ko] undefined!
>
> You have to test better with the various modular/non-modular combinations.
>
> Thanks.

Ok, my bad, I'll resubmit it tomorrow.

Thanks!
-Vladimir

^ permalink raw reply	[flat|nested] 40+ messages in thread

end of thread, other threads:[~2019-06-07 19:38 UTC | newest]

Thread overview: 40+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2019-06-04 17:07 [PATCH v3 net-next 00/17] PTP support for the SJA1105 DSA driver Vladimir Oltean
2019-06-04 17:07 ` [PATCH v3 net-next 01/17] net: dsa: Keep a pointer to the skb clone for TX timestamping Vladimir Oltean
2019-06-04 20:31   ` Florian Fainelli
2019-06-04 17:07 ` [PATCH v3 net-next 02/17] net: dsa: Add teardown callback for drivers Vladimir Oltean
2019-06-04 18:15   ` Andrew Lunn
2019-06-04 20:32   ` Florian Fainelli
2019-06-04 17:07 ` [PATCH v3 net-next 03/17] net: dsa: tag_8021q: Create helper function for removing VLAN header Vladimir Oltean
2019-06-04 17:07 ` [PATCH v3 net-next 04/17] net: dsa: sja1105: Move sja1105_change_tpid into sja1105_vlan_filtering Vladimir Oltean
2019-06-04 20:58   ` Florian Fainelli
2019-06-04 17:07 ` [PATCH v3 net-next 05/17] net: dsa: sja1105: Reverse TPID and TPID2 Vladimir Oltean
2019-06-04 20:33   ` Florian Fainelli
2019-06-04 17:07 ` [PATCH v3 net-next 06/17] net: dsa: sja1105: Limit use of incl_srcpt to bridge+vlan mode Vladimir Oltean
2019-06-04 20:35   ` Florian Fainelli
2019-06-04 17:07 ` [PATCH v3 net-next 07/17] net: dsa: sja1105: Add support for the PTP clock Vladimir Oltean
2019-06-04 17:07 ` [PATCH v3 net-next 08/17] net: dsa: sja1105: Move sja1105_is_link_local to include/linux Vladimir Oltean
2019-06-04 20:35   ` Florian Fainelli
2019-06-04 17:07 ` [PATCH v3 net-next 09/17] net: dsa: sja1105: Add logic for TX timestamping Vladimir Oltean
2019-06-04 17:07 ` [PATCH v3 net-next 10/17] net: dsa: sja1105: Build a minimal understanding of meta frames Vladimir Oltean
2019-06-04 21:00   ` Florian Fainelli
2019-06-04 17:07 ` [PATCH v3 net-next 11/17] net: dsa: sja1105: Add support for the AVB Parameters Table Vladimir Oltean
2019-06-04 17:07 ` [PATCH v3 net-next 12/17] net: dsa: sja1105: Make sja1105_is_link_local not match meta frames Vladimir Oltean
2019-06-04 17:07 ` [PATCH v3 net-next 13/17] net: dsa: sja1105: Receive and decode " Vladimir Oltean
2019-06-04 17:07 ` [PATCH v3 net-next 14/17] net: dsa: sja1105: Add a global sja1105_tagger_data structure Vladimir Oltean
2019-06-04 17:07 ` [PATCH v3 net-next 15/17] net: dsa: sja1105: Increase priority of CPU-trapped frames Vladimir Oltean
2019-06-04 17:07 ` [PATCH v3 net-next 16/17] net: dsa: sja1105: Add a state machine for RX timestamping Vladimir Oltean
2019-06-04 17:07 ` [PATCH v3 net-next 17/17] net: dsa: sja1105: Expose PTP timestamping ioctls to userspace Vladimir Oltean
2019-06-05  3:22 ` [PATCH v3 net-next 00/17] PTP support for the SJA1105 DSA driver David Miller
2019-06-05  9:13   ` Vladimir Oltean
2019-06-05 11:33     ` Vladimir Oltean
2019-06-05 17:45       ` Richard Cochran
2019-06-05 17:50         ` Vladimir Oltean
2019-06-05 17:52           ` Vladimir Oltean
2019-06-05 18:08         ` Vladimir Oltean
2019-06-06  3:11           ` Richard Cochran
2019-06-06 13:40             ` Vladimir Oltean
2019-06-07  3:32               ` Richard Cochran
2019-06-07  9:43                 ` Vladimir Oltean
2019-06-05 18:44     ` David Miller
2019-06-07 19:15       ` David Miller
2019-06-07 19:38         ` Vladimir Oltean

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).