Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0-or-later
0002 /*
0003  * PTP 1588 clock support - support for timestamping in PHY devices
0004  *
0005  * Copyright (C) 2010 OMICRON electronics GmbH
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);