12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485 |
- /*
- * PTP 1588 clock support - support for timestamping in PHY devices
- *
- * Copyright (C) 2010 OMICRON electronics GmbH
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
- #include <linux/errqueue.h>
- #include <linux/phy.h>
- #include <linux/ptp_classify.h>
- #include <linux/skbuff.h>
- #include <linux/export.h>
- static unsigned int classify(const struct sk_buff *skb)
- {
- if (likely(skb->dev && skb->dev->phydev &&
- skb->dev->phydev->drv))
- return ptp_classify_raw(skb);
- else
- return PTP_CLASS_NONE;
- }
- void skb_clone_tx_timestamp(struct sk_buff *skb)
- {
- struct phy_device *phydev;
- struct sk_buff *clone;
- unsigned int type;
- if (!skb->sk)
- return;
- type = classify(skb);
- if (type == PTP_CLASS_NONE)
- return;
- phydev = skb->dev->phydev;
- if (likely(phydev->drv->txtstamp)) {
- clone = skb_clone_sk(skb);
- if (!clone)
- return;
- phydev->drv->txtstamp(phydev, clone, type);
- }
- }
- EXPORT_SYMBOL_GPL(skb_clone_tx_timestamp);
- bool skb_defer_rx_timestamp(struct sk_buff *skb)
- {
- struct phy_device *phydev;
- unsigned int type;
- if (!skb->dev || !skb->dev->phydev || !skb->dev->phydev->drv)
- return false;
- if (skb_headroom(skb) < ETH_HLEN)
- return false;
- __skb_push(skb, ETH_HLEN);
- type = ptp_classify_raw(skb);
- __skb_pull(skb, ETH_HLEN);
- if (type == PTP_CLASS_NONE)
- return false;
- phydev = skb->dev->phydev;
- if (likely(phydev->drv->rxtstamp))
- return phydev->drv->rxtstamp(phydev, skb, type);
- return false;
- }
- EXPORT_SYMBOL_GPL(skb_defer_rx_timestamp);
|