0001
0002
0003
0004
0005
0006
0007 #include <linux/errqueue.h>
0008 #include <linux/phy.h>
0009 #include <linux/ptp_classify.h>
0010 #include <linux/skbuff.h>
0011 #include <linux/export.h>
0012
0013 static unsigned int classify(const struct sk_buff *skb)
0014 {
0015 if (likely(skb->dev && skb->dev->phydev &&
0016 skb->dev->phydev->mii_ts))
0017 return ptp_classify_raw(skb);
0018 else
0019 return PTP_CLASS_NONE;
0020 }
0021
0022 void skb_clone_tx_timestamp(struct sk_buff *skb)
0023 {
0024 struct mii_timestamper *mii_ts;
0025 struct sk_buff *clone;
0026 unsigned int type;
0027
0028 if (!skb->sk)
0029 return;
0030
0031 type = classify(skb);
0032 if (type == PTP_CLASS_NONE)
0033 return;
0034
0035 mii_ts = skb->dev->phydev->mii_ts;
0036 if (likely(mii_ts->txtstamp)) {
0037 clone = skb_clone_sk(skb);
0038 if (!clone)
0039 return;
0040 mii_ts->txtstamp(mii_ts, clone, type);
0041 }
0042 }
0043 EXPORT_SYMBOL_GPL(skb_clone_tx_timestamp);
0044
0045 bool skb_defer_rx_timestamp(struct sk_buff *skb)
0046 {
0047 struct mii_timestamper *mii_ts;
0048 unsigned int type;
0049
0050 if (!skb->dev || !skb->dev->phydev || !skb->dev->phydev->mii_ts)
0051 return false;
0052
0053 if (skb_headroom(skb) < ETH_HLEN)
0054 return false;
0055
0056 __skb_push(skb, ETH_HLEN);
0057
0058 type = ptp_classify_raw(skb);
0059
0060 __skb_pull(skb, ETH_HLEN);
0061
0062 if (type == PTP_CLASS_NONE)
0063 return false;
0064
0065 mii_ts = skb->dev->phydev->mii_ts;
0066 if (likely(mii_ts->rxtstamp))
0067 return mii_ts->rxtstamp(mii_ts, skb, type);
0068
0069 return false;
0070 }
0071 EXPORT_SYMBOL_GPL(skb_defer_rx_timestamp);