mirror of
https://github.com/Fishwaldo/Star64_linux.git
synced 2025-06-24 15:42:32 +00: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:
parent
12d0efb9e6
commit
4715f65ffa
6 changed files with 106 additions and 58 deletions
|
@ -98,6 +98,7 @@ struct dp83640_private {
|
||||||
struct list_head list;
|
struct list_head list;
|
||||||
struct dp83640_clock *clock;
|
struct dp83640_clock *clock;
|
||||||
struct phy_device *phydev;
|
struct phy_device *phydev;
|
||||||
|
struct mii_timestamper mii_ts;
|
||||||
struct delayed_work ts_work;
|
struct delayed_work ts_work;
|
||||||
int hwts_tx_en;
|
int hwts_tx_en;
|
||||||
int hwts_rx_en;
|
int hwts_rx_en;
|
||||||
|
@ -1229,9 +1230,10 @@ static int dp83640_config_intr(struct phy_device *phydev)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static int dp83640_hwtstamp(struct phy_device *phydev, struct ifreq *ifr)
|
static int dp83640_hwtstamp(struct mii_timestamper *mii_ts, struct ifreq *ifr)
|
||||||
{
|
{
|
||||||
struct dp83640_private *dp83640 = phydev->priv;
|
struct dp83640_private *dp83640 =
|
||||||
|
container_of(mii_ts, struct dp83640_private, mii_ts);
|
||||||
struct hwtstamp_config cfg;
|
struct hwtstamp_config cfg;
|
||||||
u16 txcfg0, rxcfg0;
|
u16 txcfg0, rxcfg0;
|
||||||
|
|
||||||
|
@ -1307,8 +1309,8 @@ static int dp83640_hwtstamp(struct phy_device *phydev, struct ifreq *ifr)
|
||||||
|
|
||||||
mutex_lock(&dp83640->clock->extreg_lock);
|
mutex_lock(&dp83640->clock->extreg_lock);
|
||||||
|
|
||||||
ext_write(0, phydev, PAGE5, PTP_TXCFG0, txcfg0);
|
ext_write(0, dp83640->phydev, PAGE5, PTP_TXCFG0, txcfg0);
|
||||||
ext_write(0, phydev, PAGE5, PTP_RXCFG0, rxcfg0);
|
ext_write(0, dp83640->phydev, PAGE5, PTP_RXCFG0, rxcfg0);
|
||||||
|
|
||||||
mutex_unlock(&dp83640->clock->extreg_lock);
|
mutex_unlock(&dp83640->clock->extreg_lock);
|
||||||
|
|
||||||
|
@ -1338,10 +1340,11 @@ static void rx_timestamp_work(struct work_struct *work)
|
||||||
schedule_delayed_work(&dp83640->ts_work, SKB_TIMESTAMP_TIMEOUT);
|
schedule_delayed_work(&dp83640->ts_work, SKB_TIMESTAMP_TIMEOUT);
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool dp83640_rxtstamp(struct phy_device *phydev,
|
static bool dp83640_rxtstamp(struct mii_timestamper *mii_ts,
|
||||||
struct sk_buff *skb, int type)
|
struct sk_buff *skb, int type)
|
||||||
{
|
{
|
||||||
struct dp83640_private *dp83640 = phydev->priv;
|
struct dp83640_private *dp83640 =
|
||||||
|
container_of(mii_ts, struct dp83640_private, mii_ts);
|
||||||
struct dp83640_skb_info *skb_info = (struct dp83640_skb_info *)skb->cb;
|
struct dp83640_skb_info *skb_info = (struct dp83640_skb_info *)skb->cb;
|
||||||
struct list_head *this, *next;
|
struct list_head *this, *next;
|
||||||
struct rxts *rxts;
|
struct rxts *rxts;
|
||||||
|
@ -1387,11 +1390,12 @@ static bool dp83640_rxtstamp(struct phy_device *phydev,
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void dp83640_txtstamp(struct phy_device *phydev,
|
static void dp83640_txtstamp(struct mii_timestamper *mii_ts,
|
||||||
struct sk_buff *skb, int type)
|
struct sk_buff *skb, int type)
|
||||||
{
|
{
|
||||||
struct dp83640_skb_info *skb_info = (struct dp83640_skb_info *)skb->cb;
|
struct dp83640_skb_info *skb_info = (struct dp83640_skb_info *)skb->cb;
|
||||||
struct dp83640_private *dp83640 = phydev->priv;
|
struct dp83640_private *dp83640 =
|
||||||
|
container_of(mii_ts, struct dp83640_private, mii_ts);
|
||||||
|
|
||||||
switch (dp83640->hwts_tx_en) {
|
switch (dp83640->hwts_tx_en) {
|
||||||
|
|
||||||
|
@ -1414,9 +1418,11 @@ static void dp83640_txtstamp(struct phy_device *phydev,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static int dp83640_ts_info(struct phy_device *dev, struct ethtool_ts_info *info)
|
static int dp83640_ts_info(struct mii_timestamper *mii_ts,
|
||||||
|
struct ethtool_ts_info *info)
|
||||||
{
|
{
|
||||||
struct dp83640_private *dp83640 = dev->priv;
|
struct dp83640_private *dp83640 =
|
||||||
|
container_of(mii_ts, struct dp83640_private, mii_ts);
|
||||||
|
|
||||||
info->so_timestamping =
|
info->so_timestamping =
|
||||||
SOF_TIMESTAMPING_TX_HARDWARE |
|
SOF_TIMESTAMPING_TX_HARDWARE |
|
||||||
|
@ -1454,13 +1460,18 @@ static int dp83640_probe(struct phy_device *phydev)
|
||||||
goto no_memory;
|
goto no_memory;
|
||||||
|
|
||||||
dp83640->phydev = phydev;
|
dp83640->phydev = phydev;
|
||||||
INIT_DELAYED_WORK(&dp83640->ts_work, rx_timestamp_work);
|
dp83640->mii_ts.rxtstamp = dp83640_rxtstamp;
|
||||||
|
dp83640->mii_ts.txtstamp = dp83640_txtstamp;
|
||||||
|
dp83640->mii_ts.hwtstamp = dp83640_hwtstamp;
|
||||||
|
dp83640->mii_ts.ts_info = dp83640_ts_info;
|
||||||
|
|
||||||
|
INIT_DELAYED_WORK(&dp83640->ts_work, rx_timestamp_work);
|
||||||
INIT_LIST_HEAD(&dp83640->rxts);
|
INIT_LIST_HEAD(&dp83640->rxts);
|
||||||
INIT_LIST_HEAD(&dp83640->rxpool);
|
INIT_LIST_HEAD(&dp83640->rxpool);
|
||||||
for (i = 0; i < MAX_RXTS; i++)
|
for (i = 0; i < MAX_RXTS; i++)
|
||||||
list_add(&dp83640->rx_pool_data[i].list, &dp83640->rxpool);
|
list_add(&dp83640->rx_pool_data[i].list, &dp83640->rxpool);
|
||||||
|
|
||||||
|
phydev->mii_ts = &dp83640->mii_ts;
|
||||||
phydev->priv = dp83640;
|
phydev->priv = dp83640;
|
||||||
|
|
||||||
spin_lock_init(&dp83640->rx_lock);
|
spin_lock_init(&dp83640->rx_lock);
|
||||||
|
@ -1501,6 +1512,8 @@ static void dp83640_remove(struct phy_device *phydev)
|
||||||
if (phydev->mdio.addr == BROADCAST_ADDR)
|
if (phydev->mdio.addr == BROADCAST_ADDR)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
phydev->mii_ts = NULL;
|
||||||
|
|
||||||
enable_status_frames(phydev, false);
|
enable_status_frames(phydev, false);
|
||||||
cancel_delayed_work_sync(&dp83640->ts_work);
|
cancel_delayed_work_sync(&dp83640->ts_work);
|
||||||
|
|
||||||
|
@ -1537,10 +1550,6 @@ static struct phy_driver dp83640_driver = {
|
||||||
.config_init = dp83640_config_init,
|
.config_init = dp83640_config_init,
|
||||||
.ack_interrupt = dp83640_ack_interrupt,
|
.ack_interrupt = dp83640_ack_interrupt,
|
||||||
.config_intr = dp83640_config_intr,
|
.config_intr = dp83640_config_intr,
|
||||||
.ts_info = dp83640_ts_info,
|
|
||||||
.hwtstamp = dp83640_hwtstamp,
|
|
||||||
.rxtstamp = dp83640_rxtstamp,
|
|
||||||
.txtstamp = dp83640_txtstamp,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
static int __init dp83640_init(void)
|
static int __init dp83640_init(void)
|
||||||
|
|
|
@ -422,8 +422,8 @@ int phy_mii_ioctl(struct phy_device *phydev, struct ifreq *ifr, int cmd)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
case SIOCSHWTSTAMP:
|
case SIOCSHWTSTAMP:
|
||||||
if (phydev->drv && phydev->drv->hwtstamp)
|
if (phydev->mii_ts && phydev->mii_ts->hwtstamp)
|
||||||
return phydev->drv->hwtstamp(phydev, ifr);
|
return phydev->mii_ts->hwtstamp(phydev->mii_ts, ifr);
|
||||||
/* fall through */
|
/* fall through */
|
||||||
|
|
||||||
default:
|
default:
|
||||||
|
|
|
@ -919,6 +919,8 @@ static void phy_link_change(struct phy_device *phydev, bool up, bool do_carrier)
|
||||||
netif_carrier_off(netdev);
|
netif_carrier_off(netdev);
|
||||||
}
|
}
|
||||||
phydev->adjust_link(netdev);
|
phydev->adjust_link(netdev);
|
||||||
|
if (phydev->mii_ts && phydev->mii_ts->link_state)
|
||||||
|
phydev->mii_ts->link_state(phydev->mii_ts, phydev);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
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/linkmode.h>
|
||||||
#include <linux/mdio.h>
|
#include <linux/mdio.h>
|
||||||
#include <linux/mii.h>
|
#include <linux/mii.h>
|
||||||
|
#include <linux/mii_timestamper.h>
|
||||||
#include <linux/module.h>
|
#include <linux/module.h>
|
||||||
#include <linux/timer.h>
|
#include <linux/timer.h>
|
||||||
#include <linux/workqueue.h>
|
#include <linux/workqueue.h>
|
||||||
|
@ -441,6 +442,7 @@ struct phy_device {
|
||||||
struct sfp_bus *sfp_bus;
|
struct sfp_bus *sfp_bus;
|
||||||
struct phylink *phylink;
|
struct phylink *phylink;
|
||||||
struct net_device *attached_dev;
|
struct net_device *attached_dev;
|
||||||
|
struct mii_timestamper *mii_ts;
|
||||||
|
|
||||||
u8 mdix;
|
u8 mdix;
|
||||||
u8 mdix_ctrl;
|
u8 mdix_ctrl;
|
||||||
|
@ -546,29 +548,6 @@ struct phy_driver {
|
||||||
*/
|
*/
|
||||||
int (*match_phy_device)(struct phy_device *phydev);
|
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
|
/* 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
|
* enable Wake on LAN, so set_wol is provided to be called in the
|
||||||
* ethernet driver's set_wol function. */
|
* 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)
|
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)
|
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)
|
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)
|
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)
|
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,
|
static inline bool phy_rxtstamp(struct phy_device *phydev, struct sk_buff *skb,
|
||||||
int type)
|
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,
|
static inline int phy_ts_info(struct phy_device *phydev,
|
||||||
struct ethtool_ts_info *tsinfo)
|
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,
|
static inline void phy_txtstamp(struct phy_device *phydev, struct sk_buff *skb,
|
||||||
int type)
|
int type)
|
||||||
{
|
{
|
||||||
phydev->drv->txtstamp(phydev, skb, type);
|
phydev->mii_ts->txtstamp(phydev->mii_ts, skb, type);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -13,7 +13,7 @@
|
||||||
static unsigned int classify(const struct sk_buff *skb)
|
static unsigned int classify(const struct sk_buff *skb)
|
||||||
{
|
{
|
||||||
if (likely(skb->dev && skb->dev->phydev &&
|
if (likely(skb->dev && skb->dev->phydev &&
|
||||||
skb->dev->phydev->drv))
|
skb->dev->phydev->mii_ts))
|
||||||
return ptp_classify_raw(skb);
|
return ptp_classify_raw(skb);
|
||||||
else
|
else
|
||||||
return PTP_CLASS_NONE;
|
return PTP_CLASS_NONE;
|
||||||
|
@ -21,7 +21,7 @@ static unsigned int classify(const struct sk_buff *skb)
|
||||||
|
|
||||||
void skb_clone_tx_timestamp(struct sk_buff *skb)
|
void skb_clone_tx_timestamp(struct sk_buff *skb)
|
||||||
{
|
{
|
||||||
struct phy_device *phydev;
|
struct mii_timestamper *mii_ts;
|
||||||
struct sk_buff *clone;
|
struct sk_buff *clone;
|
||||||
unsigned int type;
|
unsigned int type;
|
||||||
|
|
||||||
|
@ -32,22 +32,22 @@ void skb_clone_tx_timestamp(struct sk_buff *skb)
|
||||||
if (type == PTP_CLASS_NONE)
|
if (type == PTP_CLASS_NONE)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
phydev = skb->dev->phydev;
|
mii_ts = skb->dev->phydev->mii_ts;
|
||||||
if (likely(phydev->drv->txtstamp)) {
|
if (likely(mii_ts->txtstamp)) {
|
||||||
clone = skb_clone_sk(skb);
|
clone = skb_clone_sk(skb);
|
||||||
if (!clone)
|
if (!clone)
|
||||||
return;
|
return;
|
||||||
phydev->drv->txtstamp(phydev, clone, type);
|
mii_ts->txtstamp(mii_ts, clone, type);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL_GPL(skb_clone_tx_timestamp);
|
EXPORT_SYMBOL_GPL(skb_clone_tx_timestamp);
|
||||||
|
|
||||||
bool skb_defer_rx_timestamp(struct sk_buff *skb)
|
bool skb_defer_rx_timestamp(struct sk_buff *skb)
|
||||||
{
|
{
|
||||||
struct phy_device *phydev;
|
struct mii_timestamper *mii_ts;
|
||||||
unsigned int type;
|
unsigned int type;
|
||||||
|
|
||||||
if (!skb->dev || !skb->dev->phydev || !skb->dev->phydev->drv)
|
if (!skb->dev || !skb->dev->phydev || !skb->dev->phydev->mii_ts)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
if (skb_headroom(skb) < ETH_HLEN)
|
if (skb_headroom(skb) < ETH_HLEN)
|
||||||
|
@ -62,9 +62,9 @@ bool skb_defer_rx_timestamp(struct sk_buff *skb)
|
||||||
if (type == PTP_CLASS_NONE)
|
if (type == PTP_CLASS_NONE)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
phydev = skb->dev->phydev;
|
mii_ts = skb->dev->phydev->mii_ts;
|
||||||
if (likely(phydev->drv->rxtstamp))
|
if (likely(mii_ts->rxtstamp))
|
||||||
return phydev->drv->rxtstamp(phydev, skb, type);
|
return mii_ts->rxtstamp(mii_ts, skb, type);
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue