diff options
author | Richard Cochran <richardcochran@gmail.com> | 2019-12-25 18:16:15 -0800 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2019-12-25 19:51:33 -0800 |
commit | 4715f65ffa0520af0680dbfbedbe349f175adaf4 (patch) | |
tree | a9723490345512b0883ab8a6c950389f62baf41e /include | |
parent | 12d0efb9e6d90e6ff5c94e46d1ea273a41e36454 (diff) | |
download | lwn-4715f65ffa0520af0680dbfbedbe349f175adaf4.tar.gz lwn-4715f65ffa0520af0680dbfbedbe349f175adaf4.zip |
net: Introduce a new MII time stamping interface.
Currently the stack supports time stamping in PHY devices. However,
there are newer, non-PHY devices that can snoop an MII bus and provide
time stamps. In order to support such devices, this patch introduces
a new interface to be used by both PHY and non-PHY devices.
In addition, the one and only user of the old PHY time stamping API is
converted to the new interface.
Signed-off-by: Richard Cochran <richardcochran@gmail.com>
Reviewed-by: Andrew Lunn <andrew@lunn.ch>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'include')
-rw-r--r-- | include/linux/mii_timestamper.h | 58 | ||||
-rw-r--r-- | include/linux/phy.h | 41 |
2 files changed, 68 insertions, 31 deletions
diff --git a/include/linux/mii_timestamper.h b/include/linux/mii_timestamper.h new file mode 100644 index 000000000000..36002386029c --- /dev/null +++ b/include/linux/mii_timestamper.h @@ -0,0 +1,58 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Support for generic time stamping devices on MII buses. + * Copyright (C) 2018 Richard Cochran <richardcochran@gmail.com> + */ +#ifndef _LINUX_MII_TIMESTAMPER_H +#define _LINUX_MII_TIMESTAMPER_H + +#include <linux/device.h> +#include <linux/ethtool.h> +#include <linux/skbuff.h> + +struct phy_device; + +/** + * struct mii_timestamper - Callback interface to MII time stamping devices. + * + * @rxtstamp: Requests a Rx timestamp for 'skb'. If the skb is accepted, + * the MII time stamping device promises to deliver it using + * netif_rx() as soon as a timestamp becomes available. One of + * the PTP_CLASS_ values is passed in 'type'. The function + * must return true if the skb is accepted for delivery. + * + * @txtstamp: Requests a Tx timestamp for 'skb'. The MII time stamping + * device promises to deliver it using skb_complete_tx_timestamp() + * as soon as a timestamp becomes available. One of the PTP_CLASS_ + * values is passed in 'type'. + * + * @hwtstamp: Handles SIOCSHWTSTAMP ioctl for hardware time stamping. + * + * @link_state: Allows the device to respond to changes in the link + * state. The caller invokes this function while holding + * the phy_device mutex. + * + * @ts_info: Handles ethtool queries for hardware time stamping. + * + * Drivers for PHY time stamping devices should embed their + * mii_timestamper within a private structure, obtaining a reference + * to it using container_of(). + */ +struct mii_timestamper { + bool (*rxtstamp)(struct mii_timestamper *mii_ts, + struct sk_buff *skb, int type); + + void (*txtstamp)(struct mii_timestamper *mii_ts, + struct sk_buff *skb, int type); + + int (*hwtstamp)(struct mii_timestamper *mii_ts, + struct ifreq *ifreq); + + void (*link_state)(struct mii_timestamper *mii_ts, + struct phy_device *phydev); + + int (*ts_info)(struct mii_timestamper *mii_ts, + struct ethtool_ts_info *ts_info); +}; + +#endif diff --git a/include/linux/phy.h b/include/linux/phy.h index 0248f5e9939d..30e599c454db 100644 --- a/include/linux/phy.h +++ b/include/linux/phy.h @@ -17,6 +17,7 @@ #include <linux/linkmode.h> #include <linux/mdio.h> #include <linux/mii.h> +#include <linux/mii_timestamper.h> #include <linux/module.h> #include <linux/timer.h> #include <linux/workqueue.h> @@ -441,6 +442,7 @@ struct phy_device { struct sfp_bus *sfp_bus; struct phylink *phylink; struct net_device *attached_dev; + struct mii_timestamper *mii_ts; u8 mdix; u8 mdix_ctrl; @@ -546,29 +548,6 @@ struct phy_driver { */ int (*match_phy_device)(struct phy_device *phydev); - /* Handles ethtool queries for hardware time stamping. */ - int (*ts_info)(struct phy_device *phydev, struct ethtool_ts_info *ti); - - /* Handles SIOCSHWTSTAMP ioctl for hardware time stamping. */ - int (*hwtstamp)(struct phy_device *phydev, struct ifreq *ifr); - - /* - * Requests a Rx timestamp for 'skb'. If the skb is accepted, - * the phy driver promises to deliver it using netif_rx() as - * soon as a timestamp becomes available. One of the - * PTP_CLASS_ values is passed in 'type'. The function must - * return true if the skb is accepted for delivery. - */ - bool (*rxtstamp)(struct phy_device *dev, struct sk_buff *skb, int type); - - /* - * Requests a Tx timestamp for 'skb'. The phy driver promises - * to deliver it using skb_complete_tx_timestamp() as soon as a - * timestamp becomes available. One of the PTP_CLASS_ values - * is passed in 'type'. - */ - void (*txtstamp)(struct phy_device *dev, struct sk_buff *skb, int type); - /* Some devices (e.g. qnap TS-119P II) require PHY register changes to * enable Wake on LAN, so set_wol is provided to be called in the * ethernet driver's set_wol function. */ @@ -942,7 +921,7 @@ static inline bool phy_polling_mode(struct phy_device *phydev) */ static inline bool phy_has_hwtstamp(struct phy_device *phydev) { - return phydev && phydev->drv && phydev->drv->hwtstamp; + return phydev && phydev->mii_ts && phydev->mii_ts->hwtstamp; } /** @@ -951,7 +930,7 @@ static inline bool phy_has_hwtstamp(struct phy_device *phydev) */ static inline bool phy_has_rxtstamp(struct phy_device *phydev) { - return phydev && phydev->drv && phydev->drv->rxtstamp; + return phydev && phydev->mii_ts && phydev->mii_ts->rxtstamp; } /** @@ -961,7 +940,7 @@ static inline bool phy_has_rxtstamp(struct phy_device *phydev) */ static inline bool phy_has_tsinfo(struct phy_device *phydev) { - return phydev && phydev->drv && phydev->drv->ts_info; + return phydev && phydev->mii_ts && phydev->mii_ts->ts_info; } /** @@ -970,30 +949,30 @@ static inline bool phy_has_tsinfo(struct phy_device *phydev) */ static inline bool phy_has_txtstamp(struct phy_device *phydev) { - return phydev && phydev->drv && phydev->drv->txtstamp; + return phydev && phydev->mii_ts && phydev->mii_ts->txtstamp; } static inline int phy_hwtstamp(struct phy_device *phydev, struct ifreq *ifr) { - return phydev->drv->hwtstamp(phydev, ifr); + return phydev->mii_ts->hwtstamp(phydev->mii_ts, ifr); } static inline bool phy_rxtstamp(struct phy_device *phydev, struct sk_buff *skb, int type) { - return phydev->drv->rxtstamp(phydev, skb, type); + return phydev->mii_ts->rxtstamp(phydev->mii_ts, skb, type); } static inline int phy_ts_info(struct phy_device *phydev, struct ethtool_ts_info *tsinfo) { - return phydev->drv->ts_info(phydev, tsinfo); + return phydev->mii_ts->ts_info(phydev->mii_ts, tsinfo); } static inline void phy_txtstamp(struct phy_device *phydev, struct sk_buff *skb, int type) { - phydev->drv->txtstamp(phydev, skb, type); + phydev->mii_ts->txtstamp(phydev->mii_ts, skb, type); } /** |