timestamping.c 1.5 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071
  1. // SPDX-License-Identifier: GPL-2.0-or-later
  2. /*
  3. * PTP 1588 clock support - support for timestamping in PHY devices
  4. *
  5. * Copyright (C) 2010 OMICRON electronics GmbH
  6. */
  7. #include <linux/errqueue.h>
  8. #include <linux/phy.h>
  9. #include <linux/ptp_classify.h>
  10. #include <linux/skbuff.h>
  11. #include <linux/export.h>
  12. static unsigned int classify(const struct sk_buff *skb)
  13. {
  14. if (likely(skb->dev && skb->dev->phydev &&
  15. skb->dev->phydev->mii_ts))
  16. return ptp_classify_raw(skb);
  17. else
  18. return PTP_CLASS_NONE;
  19. }
  20. void skb_clone_tx_timestamp(struct sk_buff *skb)
  21. {
  22. struct mii_timestamper *mii_ts;
  23. struct sk_buff *clone;
  24. unsigned int type;
  25. if (!skb->sk)
  26. return;
  27. type = classify(skb);
  28. if (type == PTP_CLASS_NONE)
  29. return;
  30. mii_ts = skb->dev->phydev->mii_ts;
  31. if (likely(mii_ts->txtstamp)) {
  32. clone = skb_clone_sk(skb);
  33. if (!clone)
  34. return;
  35. mii_ts->txtstamp(mii_ts, clone, type);
  36. }
  37. }
  38. EXPORT_SYMBOL_GPL(skb_clone_tx_timestamp);
  39. bool skb_defer_rx_timestamp(struct sk_buff *skb)
  40. {
  41. struct mii_timestamper *mii_ts;
  42. unsigned int type;
  43. if (!skb->dev || !skb->dev->phydev || !skb->dev->phydev->mii_ts)
  44. return false;
  45. if (skb_headroom(skb) < ETH_HLEN)
  46. return false;
  47. __skb_push(skb, ETH_HLEN);
  48. type = ptp_classify_raw(skb);
  49. __skb_pull(skb, ETH_HLEN);
  50. if (type == PTP_CLASS_NONE)
  51. return false;
  52. mii_ts = skb->dev->phydev->mii_ts;
  53. if (likely(mii_ts->rxtstamp))
  54. return mii_ts->rxtstamp(mii_ts, skb, type);
  55. return false;
  56. }
  57. EXPORT_SYMBOL_GPL(skb_defer_rx_timestamp);