aboutsummaryrefslogtreecommitdiffstats
path: root/net/dsa/dsa.c
diff options
context:
space:
mode:
authorDavid S. Miller <davem@davemloft.net>2018-02-14 14:33:38 -0500
committerDavid S. Miller <davem@davemloft.net>2018-02-14 14:33:38 -0500
commit64da58528bdbdba171cf6c6ffaf39c2ee75e3a10 (patch)
treed779fcb16a984e9c1070269050d885c2d73ce120 /net/dsa/dsa.c
parente0f9759f530bf789e984961dce79f525b151ecf3 (diff)
parenta2e47134e577713add97124afd812bc3f93627fb (diff)
Merge branch 'PTP-support-for-DSA-and-mv88e6xxx-driver'
Andrew Lunn says: ==================== PTP support for DSA and mv88e6xxx driver. This patchset adds support for using the PTP hardware in switches supported by the mv88e6xxx driver. The code was produces in collaboration with Brandon Streiff doing the initial implementation, and then Richard Cochran and Andrew Lunn making further changes and cleanups. The code is sufficient to use ptp4l on a single DSA interface, either as a master or a slave. Due to the use of an MDIO bus to access the switch, reading hardware timestamps is slower than what ptp4l expects. Thus it is necessary to use the option --tx_timestamp_timeout=32. Heavy use of ethtool -S, or bridge fdb show can also upset ptp4l. Patches to address this will follow. Further work is requires to support bridges using Boundary Clock or Transparent Clock mode. Since the RFC, an overflow bug has been fixed. Brandon Streiff has also Acked-by: the updates to his initial patchset. ==================== 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;