aboutsummaryrefslogtreecommitdiffstats
path: root/net/dsa/dsa.c
diff options
context:
space:
mode:
authorBrandon Streiff <brandon.streiff@ni.com>2018-02-13 19:07:49 -0500
committerDavid S. Miller <davem@davemloft.net>2018-02-14 14:33:37 -0500
commit90af1059c52c0031f3bfd8279c9ede153ca83275 (patch)
tree66b3f0407a9189ef36649951fc8da47305028a8c /net/dsa/dsa.c
parent0336369d3a4d65c9332476b618ff3bb9b41045e1 (diff)
net: dsa: forward timestamping callbacks to switch drivers
Forward the rx/tx timestamp machinery from the dsa infrastructure to the switch driver. On the rx side, defer delivery of skbs until we have an rx timestamp. This mimicks the behavior of skb_defer_rx_timestamp. On the tx side, identify PTP packets, clone them, and pass them to the underlying switch driver before we transmit. This mimicks the behavior of skb_tx_timestamp. Adjusted txstamp API to keep the allocation and freeing of the clone in the same central function by Richard Cochran Signed-off-by: Brandon Streiff <brandon.streiff@ni.com> Signed-off-by: Richard Cochran <richardcochran@gmail.com> Signed-off-by: Andrew Lunn <andrew@lunn.ch> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/dsa/dsa.c')
-rw-r--r--net/dsa/dsa.c36
1 files changed, 36 insertions, 0 deletions
diff --git a/net/dsa/dsa.c b/net/dsa/dsa.c
index 6a9d0f50fbee..e63c554e0623 100644
--- a/net/dsa/dsa.c
+++ b/net/dsa/dsa.c
@@ -23,6 +23,7 @@
23#include <linux/netdevice.h> 23#include <linux/netdevice.h>
24#include <linux/sysfs.h> 24#include <linux/sysfs.h>
25#include <linux/phy_fixed.h> 25#include <linux/phy_fixed.h>
26#include <linux/ptp_classify.h>
26#include <linux/gpio/consumer.h> 27#include <linux/gpio/consumer.h>
27#include <linux/etherdevice.h> 28#include <linux/etherdevice.h>
28 29
@@ -122,6 +123,38 @@ struct net_device *dsa_dev_to_net_device(struct device *dev)
122} 123}
123EXPORT_SYMBOL_GPL(dsa_dev_to_net_device); 124EXPORT_SYMBOL_GPL(dsa_dev_to_net_device);
124 125
126/* Determine if we should defer delivery of skb until we have a rx timestamp.
127 *
128 * Called from dsa_switch_rcv. For now, this will only work if tagging is
129 * enabled on the switch. Normally the MAC driver would retrieve the hardware
130 * timestamp when it reads the packet out of the hardware. However in a DSA
131 * switch, the DSA driver owning the interface to which the packet is
132 * delivered is never notified unless we do so here.
133 */
134static bool dsa_skb_defer_rx_timestamp(struct dsa_slave_priv *p,
135 struct sk_buff *skb)
136{
137 struct dsa_switch *ds = p->dp->ds;
138 unsigned int type;
139
140 if (skb_headroom(skb) < ETH_HLEN)
141 return false;
142
143 __skb_push(skb, ETH_HLEN);
144
145 type = ptp_classify_raw(skb);
146
147 __skb_pull(skb, ETH_HLEN);
148
149 if (type == PTP_CLASS_NONE)
150 return false;
151
152 if (likely(ds->ops->port_rxtstamp))
153 return ds->ops->port_rxtstamp(ds, p->dp->index, skb, type);
154
155 return false;
156}
157
125static int dsa_switch_rcv(struct sk_buff *skb, struct net_device *dev, 158static int dsa_switch_rcv(struct sk_buff *skb, struct net_device *dev,
126 struct packet_type *pt, struct net_device *unused) 159 struct packet_type *pt, struct net_device *unused)
127{ 160{
@@ -157,6 +190,9 @@ static int dsa_switch_rcv(struct sk_buff *skb, struct net_device *dev,
157 s->rx_bytes += skb->len; 190 s->rx_bytes += skb->len;
158 u64_stats_update_end(&s->syncp); 191 u64_stats_update_end(&s->syncp);
159 192
193 if (dsa_skb_defer_rx_timestamp(p, skb))
194 return 0;
195
160 netif_receive_skb(skb); 196 netif_receive_skb(skb);
161 197
162 return 0; 198 return 0;