mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
synced 2026-05-11 12:44:49 -04:00
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>
This commit is contained in:
committed by
David S. Miller
parent
12d0efb9e6
commit
4715f65ffa
58
include/linux/mii_timestamper.h
Normal file
58
include/linux/mii_timestamper.h
Normal file
@@ -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
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
Reference in New Issue
Block a user