diff options
author | Brandon Streiff <brandon.streiff@ni.com> | 2018-02-13 19:07:49 -0500 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2018-02-14 14:33:37 -0500 |
commit | 90af1059c52c0031f3bfd8279c9ede153ca83275 (patch) | |
tree | 66b3f0407a9189ef36649951fc8da47305028a8c /net/dsa/dsa.c | |
parent | 0336369d3a4d65c9332476b618ff3bb9b41045e1 (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.c | 36 |
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 | } |
123 | EXPORT_SYMBOL_GPL(dsa_dev_to_net_device); | 124 | EXPORT_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 | */ | ||
134 | static 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 | |||
125 | static int dsa_switch_rcv(struct sk_buff *skb, struct net_device *dev, | 158 | static 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; |