1 // SPDX-License-Identifier: GPL-2.0-or-later
3 * PTP 1588 clock support - support for timestamping in PHY devices
5 * Copyright (C) 2010 OMICRON electronics GmbH
7 #include <linux/errqueue.h>
9 #include <linux/ptp_classify.h>
10 #include <linux/skbuff.h>
11 #include <linux/export.h>
12 #include <linux/ptp_clock_kernel.h>
14 static unsigned int classify(const struct sk_buff
*skb
)
16 if (likely(skb
->dev
&& skb
->dev
->phydev
&&
17 skb
->dev
->phydev
->mii_ts
))
18 return ptp_classify_raw(skb
);
20 return PTP_CLASS_NONE
;
23 void skb_clone_tx_timestamp(struct sk_buff
*skb
)
25 struct hwtstamp_provider
*hwprov
;
26 struct mii_timestamper
*mii_ts
;
27 struct phy_device
*phydev
;
28 struct sk_buff
*clone
;
31 if (!skb
->sk
|| !skb
->dev
)
35 hwprov
= rcu_dereference(skb
->dev
->hwprov
);
37 if (hwprov
->source
!= HWTSTAMP_SOURCE_PHYLIB
||
43 phydev
= hwprov
->phydev
;
45 phydev
= skb
->dev
->phydev
;
46 if (!phy_is_default_hwtstamp(phydev
)) {
54 if (type
== PTP_CLASS_NONE
)
57 mii_ts
= phydev
->mii_ts
;
58 if (likely(mii_ts
->txtstamp
)) {
59 clone
= skb_clone_sk(skb
);
62 mii_ts
->txtstamp(mii_ts
, clone
, type
);
65 EXPORT_SYMBOL_GPL(skb_clone_tx_timestamp
);
67 bool skb_defer_rx_timestamp(struct sk_buff
*skb
)
69 struct hwtstamp_provider
*hwprov
;
70 struct mii_timestamper
*mii_ts
;
71 struct phy_device
*phydev
;
78 hwprov
= rcu_dereference(skb
->dev
->hwprov
);
80 if (hwprov
->source
!= HWTSTAMP_SOURCE_PHYLIB
||
86 phydev
= hwprov
->phydev
;
88 phydev
= skb
->dev
->phydev
;
89 if (!phy_is_default_hwtstamp(phydev
)) {
96 if (skb_headroom(skb
) < ETH_HLEN
)
99 __skb_push(skb
, ETH_HLEN
);
101 type
= ptp_classify_raw(skb
);
103 __skb_pull(skb
, ETH_HLEN
);
105 if (type
== PTP_CLASS_NONE
)
108 mii_ts
= phydev
->mii_ts
;
109 if (likely(mii_ts
->rxtstamp
))
110 return mii_ts
->rxtstamp(mii_ts
, skb
, type
);
114 EXPORT_SYMBOL_GPL(skb_defer_rx_timestamp
);