diff mbox series

[net-next,v17,04/14] net: Change the API of PHY default timestamp to MAC

Message ID 20240709-feature_ptp_netnext-v17-4-b5317f50df2a@bootlin.com (mailing list archive)
State Changes Requested
Delegated to: Netdev Maintainers
Headers show
Series net: Make timestamping selectable | expand

Checks

Context Check Description
netdev/series_format success Posting correctly formatted
netdev/tree_selection success Clearly marked for net-next, async
netdev/ynl success Generated files up to date; no warnings/errors; GEN HAS DIFF 2 files changed, 624 insertions(+);
netdev/fixes_present success Fixes tag not required for -next series
netdev/header_inline success No static functions without inline keyword in header files
netdev/build_32bit success Errors and warnings before: 816 this patch: 816
netdev/build_tools success Errors and warnings before: 0 this patch: 0
netdev/cc_maintainers warning 2 maintainers not CCed: glipus@gmail.com andrei.botila@oss.nxp.com
netdev/build_clang success Errors and warnings before: 834 this patch: 834
netdev/verify_signedoff success Signed-off-by tag matches author and committer
netdev/deprecated_api success None detected
netdev/check_selftest success No net selftest shell script
netdev/verify_fixes success No Fixes tag
netdev/build_allmodconfig_warn success Errors and warnings before: 1255 this patch: 1255
netdev/checkpatch success total: 0 errors, 0 warnings, 0 checks, 141 lines checked
netdev/build_clang_rust success No Rust files in patch. Skipping build
netdev/kdoc success Errors and warnings before: 35 this patch: 35
netdev/source_inline success Was 0 now: 0

Commit Message

Kory Maincent July 9, 2024, 1:53 p.m. UTC
Change the API to select MAC default time stamping instead of the PHY.
Indeed the PHY is closer to the wire therefore theoretically it has less
delay than the MAC timestamping but the reality is different. Due to lower
time stamping clock frequency, latency in the MDIO bus and no PHC hardware
synchronization between different PHY, the PHY PTP is often less precise
than the MAC. The exception is for PHY designed specially for PTP case but
these devices are not very widespread. For not breaking the compatibility
default_timestamp flag has been introduced in phy_device that is set by
the phy driver to know we are using the old API behavior.

Reviewed-by: Rahul Rameshbabu <rrameshbabu@nvidia.com>
Signed-off-by: Kory Maincent <kory.maincent@bootlin.com>
---

Changes in v5:
- Extract the API change in this patch.
- Rename whitelist to allowlist.
- Set NETDEV_TIMESTAMPING in register_netdevice function.
- Add software timestamping case description in ts_info.

Change in v6:
- Replace the allowlist phy with a default_timestamp flag to know which
  phy is using old API behavior.
- Fix dereferenced of a possible null pointer.
- Follow timestamping layer naming update.
- Update timestamp default set between MAC and software.
- Update ts_info returned in case of software timestamping.

Change in v8:
- Reform the implementation to use a simple phy_is_default_hwtstamp helper
  instead of saving the hwtstamp in the net_device struct.

Change in v9:
- Update few nit following the review.

Change in v12:
- Add missing return description in the kdoc.
---
 drivers/net/phy/bcm-phy-ptp.c     |  3 +++
 drivers/net/phy/dp83640.c         |  2 ++
 drivers/net/phy/micrel.c          |  6 ++++++
 drivers/net/phy/mscc/mscc_ptp.c   |  3 +++
 drivers/net/phy/nxp-c45-tja11xx.c |  3 +++
 include/linux/phy.h               | 19 +++++++++++++++++++
 net/core/dev_ioctl.c              |  8 +++-----
 net/core/timestamping.c           |  5 +++--
 net/ethtool/common.c              |  2 +-
 9 files changed, 43 insertions(+), 8 deletions(-)

Comments

Jacob Keller July 15, 2024, 11:37 p.m. UTC | #1
On 7/9/2024 6:53 AM, Kory Maincent wrote:
> Change the API to select MAC default time stamping instead of the PHY.
> Indeed the PHY is closer to the wire therefore theoretically it has less
> delay than the MAC timestamping but the reality is different. Due to lower
> time stamping clock frequency, latency in the MDIO bus and no PHC hardware
> synchronization between different PHY, the PHY PTP is often less precise
> than the MAC. The exception is for PHY designed specially for PTP case but
> these devices are not very widespread. For not breaking the compatibility
> default_timestamp flag has been introduced in phy_device that is set by
> the phy driver to know we are using the old API behavior.
> 

This description feels like it is making a pretty broad generalization
about devices. The specifics of whether MAC or PHY timestamping is
better will be device dependent.

It looks like you introduce a default_timestamp flag to ensure existing
devices default to PHY? I assume your goal here is to discourage this
and not allow setting it for new devices? Or do we want to let device
driver authors decide which is a better default?

> Reviewed-by: Rahul Rameshbabu <rrameshbabu@nvidia.com>
> Signed-off-by: Kory Maincent <kory.maincent@bootlin.com>

Overall this makes sense, with a couple questions I had during review.

Reviewed-by: Jacob Keller <jacob.e.keller@intel.com>

> ---
> diff --git a/include/linux/phy.h b/include/linux/phy.h
> index bd68f9d8e74f..e7a38137211c 100644
> --- a/include/linux/phy.h
> +++ b/include/linux/phy.h
> @@ -616,6 +616,8 @@ struct macsec_ops;
>   *                 handling shall be postponed until PHY has resumed
>   * @irq_rerun: Flag indicating interrupts occurred while PHY was suspended,
>   *             requiring a rerun of the interrupt handler after resume
> + * @default_timestamp: Flag indicating whether we are using the phy
> + *		       timestamp as the default one

This is clearly intended to ensure existing drivers maintain legacy
behavior. But what is our policy going forward for new devices? Do we
want to leave it up to PHY driver authors?

>   * @interface: enum phy_interface_t value
>   * @possible_interfaces: bitmap if interface modes that the attached PHY
>   *			 will switch between depending on media speed.
> @@ -681,6 +683,8 @@ struct phy_device {
>  	unsigned irq_suspended:1;
>  	unsigned irq_rerun:1;
>  
> +	unsigned default_timestamp:1;
> +
>  	int rate_matching;
>  
>  	enum phy_state state;
> @@ -1625,6 +1629,21 @@ static inline void phy_txtstamp(struct phy_device *phydev, struct sk_buff *skb,
>  	phydev->mii_ts->txtstamp(phydev->mii_ts, skb, type);
>  }
>  
> +/**
> + * phy_is_default_hwtstamp - Is the PHY hwtstamp the default timestamp
> + * @phydev: Pointer to phy_device
> + *
> + * This is used to get default timestamping device taking into account
> + * the new API choice, which is selecting the timestamping from MAC by
> + * default if the phydev does not have default_timestamp flag enabled.
> + *
> + * Return: True if phy is the default hw timestamp, false otherwise.
> + */
> +static inline bool phy_is_default_hwtstamp(struct phy_device *phydev)
> +{
> +	return phy_has_hwtstamp(phydev) && phydev->default_timestamp;
> +}
> +
>  /**
>   * phy_is_internal - Convenience function for testing if a PHY is internal
>   * @phydev: the phy_device struct
> diff --git a/net/core/dev_ioctl.c b/net/core/dev_ioctl.c
> index 6aaa8326bf8f..36cea843381f 100644
> --- a/net/core/dev_ioctl.c
> +++ b/net/core/dev_ioctl.c
> @@ -259,9 +259,7 @@ static int dev_eth_ioctl(struct net_device *dev,
>   * @dev: Network device
>   * @cfg: Timestamping configuration structure
>   *
> - * Helper for enforcing a common policy that phylib timestamping, if available,
> - * should take precedence in front of hardware timestamping provided by the
> - * netdev.
> + * Helper for calling the default hardware provider timestamping.
>   *
>   * Note: phy_mii_ioctl() only handles SIOCSHWTSTAMP (not SIOCGHWTSTAMP), and
>   * there only exists a phydev->mii_ts->hwtstamp() method. So this will return
> @@ -271,7 +269,7 @@ static int dev_eth_ioctl(struct net_device *dev,
>  int dev_get_hwtstamp_phylib(struct net_device *dev,
>  			    struct kernel_hwtstamp_config *cfg)
>  {
> -	if (phy_has_hwtstamp(dev->phydev))
> +	if (phy_is_default_hwtstamp(dev->phydev))
>  		return phy_hwtstamp_get(dev->phydev, cfg);
>  
>  	return dev->netdev_ops->ndo_hwtstamp_get(dev, cfg);
> @@ -327,7 +325,7 @@ int dev_set_hwtstamp_phylib(struct net_device *dev,
>  			    struct netlink_ext_ack *extack)
>  {
>  	const struct net_device_ops *ops = dev->netdev_ops;
> -	bool phy_ts = phy_has_hwtstamp(dev->phydev);
> +	bool phy_ts = phy_is_default_hwtstamp(dev->phydev);
>  	struct kernel_hwtstamp_config old_cfg = {};
>  	bool changed = false;
>  	int err;
> diff --git a/net/core/timestamping.c b/net/core/timestamping.c
> index 04840697fe79..3717fb152ecc 100644
> --- a/net/core/timestamping.c
> +++ b/net/core/timestamping.c
> @@ -25,7 +25,8 @@ void skb_clone_tx_timestamp(struct sk_buff *skb)
>  	struct sk_buff *clone;
>  	unsigned int type;
>  
> -	if (!skb->sk)
> +	if (!skb->sk || !skb->dev ||
> +	    !phy_is_default_hwtstamp(skb->dev->phydev))

I don't follow why this check is added and its not calling something
like "phy_is_current_hwtstamp"? I guess because we don't yet have a way
to select between MAC/PHY at this point in the series? Ok.

>  		return;
>  
>  	type = classify(skb);
> @@ -47,7 +48,7 @@ bool skb_defer_rx_timestamp(struct sk_buff *skb)
>  	struct mii_timestamper *mii_ts;
>  	unsigned int type;
>  
> -	if (!skb->dev || !skb->dev->phydev || !skb->dev->phydev->mii_ts)
> +	if (!skb->dev || !phy_is_default_hwtstamp(skb->dev->phydev))
>  		return false;
>  
>  	if (skb_headroom(skb) < ETH_HLEN)
> diff --git a/net/ethtool/common.c b/net/ethtool/common.c
> index 6b2a360dcdf0..01b7550f12c6 100644
> --- a/net/ethtool/common.c
> +++ b/net/ethtool/common.c
> @@ -637,7 +637,7 @@ int __ethtool_get_ts_info(struct net_device *dev, struct ethtool_ts_info *info)
>  	memset(info, 0, sizeof(*info));
>  	info->cmd = ETHTOOL_GET_TS_INFO;
>  
> -	if (phy_has_tsinfo(phydev))
> +	if (phy_is_default_hwtstamp(phydev) && phy_has_tsinfo(phydev))
>  		return phy_ts_info(phydev, info);
>  	if (ops->get_ts_info)
>  		return ops->get_ts_info(dev, info);
>
Kory Maincent July 27, 2024, 1:44 p.m. UTC | #2
On Mon, 15 Jul 2024 16:37:01 -0700
Jacob Keller <jacob.e.keller@intel.com> wrote:

> On 7/9/2024 6:53 AM, Kory Maincent wrote:
> > Change the API to select MAC default time stamping instead of the PHY.
> > Indeed the PHY is closer to the wire therefore theoretically it has less
> > delay than the MAC timestamping but the reality is different. Due to lower
> > time stamping clock frequency, latency in the MDIO bus and no PHC hardware
> > synchronization between different PHY, the PHY PTP is often less precise
> > than the MAC. The exception is for PHY designed specially for PTP case but
> > these devices are not very widespread. For not breaking the compatibility
> > default_timestamp flag has been introduced in phy_device that is set by
> > the phy driver to know we are using the old API behavior.
> >   
> 
> This description feels like it is making a pretty broad generalization
> about devices. The specifics of whether MAC or PHY timestamping is
> better will be device dependent.

As explained, except for specific PTP specialized PHY, the MAC is better in
term of PTP precision.
This patch was a requisite from Russell, who wanted to add support for the PTP
in the marvell PHY. Doing so would select the PHY PTP by default which cause a
regression as the PHY hardware timestamp is less precise than the MAC.
https://lore.kernel.org/netdev/20200729105807.GZ1551@shell.armlinux.org.uk/
https://lore.kernel.org/netdev/Y%2F4DZIDm1d74MuFJ@shell.armlinux.org.uk/
There is also discussion on how to support it in older version of this series.
 
> It looks like you introduce a default_timestamp flag to ensure existing
> devices default to PHY? I assume your goal here is to discourage this
> and not allow setting it for new devices? Or do we want to let device
> driver authors decide which is a better default?

Yes to not change the old behavior the current PHY with PTP support will still
behave as default PTP. The point is indeed to discourage future drivers to
select the PHY as default PTP.

> > Reviewed-by: Rahul Rameshbabu <rrameshbabu@nvidia.com>
> > Signed-off-by: Kory Maincent <kory.maincent@bootlin.com>  
> 
> Overall this makes sense, with a couple questions I had during review.
> 
> Reviewed-by: Jacob Keller <jacob.e.keller@intel.com>
> 
> > ---
> > diff --git a/include/linux/phy.h b/include/linux/phy.h
> > index bd68f9d8e74f..e7a38137211c 100644
> > --- a/include/linux/phy.h
> > +++ b/include/linux/phy.h
> > @@ -616,6 +616,8 @@ struct macsec_ops;
> >   *                 handling shall be postponed until PHY has resumed
> >   * @irq_rerun: Flag indicating interrupts occurred while PHY was suspended,
> >   *             requiring a rerun of the interrupt handler after resume
> > + * @default_timestamp: Flag indicating whether we are using the phy
> > + *		       timestamp as the default one  
> 
> This is clearly intended to ensure existing drivers maintain legacy
> behavior. But what is our policy going forward for new devices? Do we
> want to leave it up to PHY driver authors?

Yes, new devices should not set this flag.

> > diff --git a/net/core/timestamping.c b/net/core/timestamping.c
> > index 04840697fe79..3717fb152ecc 100644
> > --- a/net/core/timestamping.c
> > +++ b/net/core/timestamping.c
> > @@ -25,7 +25,8 @@ void skb_clone_tx_timestamp(struct sk_buff *skb)
> >  	struct sk_buff *clone;
> >  	unsigned int type;
> >  
> > -	if (!skb->sk)
> > +	if (!skb->sk || !skb->dev ||
> > +	    !phy_is_default_hwtstamp(skb->dev->phydev))  
> 
> I don't follow why this check is added and its not calling something
> like "phy_is_current_hwtstamp"? I guess because we don't yet have a way
> to select between MAC/PHY at this point in the series? Ok.

skb_clone_tx_timestamp is only used for PHY timestamping so we should do nothing
if the default PTP is the MAC.

Regards,
Jacob Keller July 29, 2024, 6:08 p.m. UTC | #3
On 7/27/2024 6:44 AM, Kory Maincent wrote:
> On Mon, 15 Jul 2024 16:37:01 -0700
> Jacob Keller <jacob.e.keller@intel.com> wrote:
> 
>> On 7/9/2024 6:53 AM, Kory Maincent wrote:
>>> Change the API to select MAC default time stamping instead of the PHY.
>>> Indeed the PHY is closer to the wire therefore theoretically it has less
>>> delay than the MAC timestamping but the reality is different. Due to lower
>>> time stamping clock frequency, latency in the MDIO bus and no PHC hardware
>>> synchronization between different PHY, the PHY PTP is often less precise
>>> than the MAC. The exception is for PHY designed specially for PTP case but
>>> these devices are not very widespread. For not breaking the compatibility
>>> default_timestamp flag has been introduced in phy_device that is set by
>>> the phy driver to know we are using the old API behavior.
>>>   
>>
>> This description feels like it is making a pretty broad generalization
>> about devices. The specifics of whether MAC or PHY timestamping is
>> better will be device dependent.
> 
> As explained, except for specific PTP specialized PHY, the MAC is better in
> term of PTP precision.
> This patch was a requisite from Russell, who wanted to add support for the PTP
> in the marvell PHY. Doing so would select the PHY PTP by default which cause a
> regression as the PHY hardware timestamp is less precise than the MAC.
> https://lore.kernel.org/netdev/20200729105807.GZ1551@shell.armlinux.org.uk/
> https://lore.kernel.org/netdev/Y%2F4DZIDm1d74MuFJ@shell.armlinux.org.uk/
> There is also discussion on how to support it in older version of this series.
>  


Right. So it is a bit of a generalization, but in practice it matches up
with the available hardware on the market.

>> It looks like you introduce a default_timestamp flag to ensure existing
>> devices default to PHY? I assume your goal here is to discourage this
>> and not allow setting it for new devices? Or do we want to let device
>> driver authors decide which is a better default?
> 
> Yes to not change the old behavior the current PHY with PTP support will still
> behave as default PTP. The point is indeed to discourage future drivers to
> select the PHY as default PTP.
> 

Ok great!

>>> diff --git a/net/core/timestamping.c b/net/core/timestamping.c
>>> index 04840697fe79..3717fb152ecc 100644
>>> --- a/net/core/timestamping.c
>>> +++ b/net/core/timestamping.c
>>> @@ -25,7 +25,8 @@ void skb_clone_tx_timestamp(struct sk_buff *skb)
>>>  	struct sk_buff *clone;
>>>  	unsigned int type;
>>>  
>>> -	if (!skb->sk)
>>> +	if (!skb->sk || !skb->dev ||
>>> +	    !phy_is_default_hwtstamp(skb->dev->phydev))  
>>
>> I don't follow why this check is added and its not calling something
>> like "phy_is_current_hwtstamp"? I guess because we don't yet have a way
>> to select between MAC/PHY at this point in the series? Ok.
> 
> skb_clone_tx_timestamp is only used for PHY timestamping so we should do nothing
> if the default PTP is the MAC.
> 

I guess my misunderstanding is what about the case where user selects
PHY timestamping with the netlink command? Then it would still need to
do the skb_clone_tx_timestamp even though its not the default? Or does
phy_is_default_hwtstamp take that into account? In which case it would
make more sense to name it phy_is_current_hwtstamp.

Either way this is mostly bikeshedding and probably just some
misunderstanding in my reading of the code.

Thanks,
Jake

> Regards,
Kory Maincent Sept. 25, 2024, 12:46 p.m. UTC | #4
Hello Jacob,

On Mon, 29 Jul 2024 11:08:01 -0700
Jacob Keller <jacob.e.keller@intel.com> wrote:

Sorry for answering it so late. I was a bit busy.

> >>> --- a/net/core/timestamping.c
> >>> +++ b/net/core/timestamping.c
> >>> @@ -25,7 +25,8 @@ void skb_clone_tx_timestamp(struct sk_buff *skb)
> >>>  	struct sk_buff *clone;
> >>>  	unsigned int type;
> >>>  
> >>> -	if (!skb->sk)
> >>> +	if (!skb->sk || !skb->dev ||
> >>> +	    !phy_is_default_hwtstamp(skb->dev->phydev))    
> >>
> >> I don't follow why this check is added and its not calling something
> >> like "phy_is_current_hwtstamp"? I guess because we don't yet have a way
> >> to select between MAC/PHY at this point in the series? Ok.  
> > 
> > skb_clone_tx_timestamp is only used for PHY timestamping so we should do
> > nothing if the default PTP is the MAC.
> >   
> 
> I guess my misunderstanding is what about the case where user selects
> PHY timestamping with the netlink command? Then it would still need to
> do the skb_clone_tx_timestamp even though its not the default? Or does
> phy_is_default_hwtstamp take that into account? In which case it would
> make more sense to name it phy_is_current_hwtstamp.
> 
> Either way this is mostly bikeshedding and probably just some
> misunderstanding in my reading of the code.

In fact the phy_is_default_hwtstamp() is only needed in case of no netlink
command used. As you can see in patch 8, we call it only if dev->hwtstamp is
null which mean that a netlink command has been sent. 

Regards,
diff mbox series

Patch

diff --git a/drivers/net/phy/bcm-phy-ptp.c b/drivers/net/phy/bcm-phy-ptp.c
index 617d384d4551..d3e825c951ee 100644
--- a/drivers/net/phy/bcm-phy-ptp.c
+++ b/drivers/net/phy/bcm-phy-ptp.c
@@ -931,6 +931,9 @@  struct bcm_ptp_private *bcm_ptp_probe(struct phy_device *phydev)
 		return ERR_CAST(clock);
 	priv->ptp_clock = clock;
 
+	/* Timestamp selected by default to keep legacy API */
+	phydev->default_timestamp = true;
+
 	priv->phydev = phydev;
 	bcm_ptp_init(priv);
 
diff --git a/drivers/net/phy/dp83640.c b/drivers/net/phy/dp83640.c
index 5c42c47dc564..d3e72d5c1472 100644
--- a/drivers/net/phy/dp83640.c
+++ b/drivers/net/phy/dp83640.c
@@ -1447,6 +1447,8 @@  static int dp83640_probe(struct phy_device *phydev)
 	for (i = 0; i < MAX_RXTS; i++)
 		list_add(&dp83640->rx_pool_data[i].list, &dp83640->rxpool);
 
+	/* Timestamp selected by default to keep legacy API */
+	phydev->default_timestamp = true;
 	phydev->mii_ts = &dp83640->mii_ts;
 	phydev->priv = dp83640;
 
diff --git a/drivers/net/phy/micrel.c b/drivers/net/phy/micrel.c
index ebafedde0ab7..8d57225d8575 100644
--- a/drivers/net/phy/micrel.c
+++ b/drivers/net/phy/micrel.c
@@ -3781,6 +3781,9 @@  static void lan8814_ptp_init(struct phy_device *phydev)
 	ptp_priv->mii_ts.ts_info  = lan8814_ts_info;
 
 	phydev->mii_ts = &ptp_priv->mii_ts;
+
+	/* Timestamp selected by default to keep legacy API */
+	phydev->default_timestamp = true;
 }
 
 static int lan8814_ptp_probe_once(struct phy_device *phydev)
@@ -5279,6 +5282,9 @@  static int lan8841_probe(struct phy_device *phydev)
 
 	phydev->mii_ts = &ptp_priv->mii_ts;
 
+	/* Timestamp selected by default to keep legacy API */
+	phydev->default_timestamp = true;
+
 	return 0;
 }
 
diff --git a/drivers/net/phy/mscc/mscc_ptp.c b/drivers/net/phy/mscc/mscc_ptp.c
index eb0b032cb613..e66d20eff7c4 100644
--- a/drivers/net/phy/mscc/mscc_ptp.c
+++ b/drivers/net/phy/mscc/mscc_ptp.c
@@ -1570,6 +1570,9 @@  int vsc8584_ptp_probe(struct phy_device *phydev)
 		return PTR_ERR(vsc8531->load_save);
 	}
 
+	/* Timestamp selected by default to keep legacy API */
+	phydev->default_timestamp = true;
+
 	vsc8531->ptp->phydev = phydev;
 
 	return 0;
diff --git a/drivers/net/phy/nxp-c45-tja11xx.c b/drivers/net/phy/nxp-c45-tja11xx.c
index 3cf614b4cd52..d18c133e6013 100644
--- a/drivers/net/phy/nxp-c45-tja11xx.c
+++ b/drivers/net/phy/nxp-c45-tja11xx.c
@@ -1660,6 +1660,9 @@  static int nxp_c45_probe(struct phy_device *phydev)
 		priv->mii_ts.ts_info = nxp_c45_ts_info;
 		phydev->mii_ts = &priv->mii_ts;
 		ret = nxp_c45_init_ptp_clock(priv);
+
+		/* Timestamp selected by default to keep legacy API */
+		phydev->default_timestamp = true;
 	} else {
 		phydev_dbg(phydev, "PTP support not enabled even if the phy supports it");
 	}
diff --git a/include/linux/phy.h b/include/linux/phy.h
index bd68f9d8e74f..e7a38137211c 100644
--- a/include/linux/phy.h
+++ b/include/linux/phy.h
@@ -616,6 +616,8 @@  struct macsec_ops;
  *                 handling shall be postponed until PHY has resumed
  * @irq_rerun: Flag indicating interrupts occurred while PHY was suspended,
  *             requiring a rerun of the interrupt handler after resume
+ * @default_timestamp: Flag indicating whether we are using the phy
+ *		       timestamp as the default one
  * @interface: enum phy_interface_t value
  * @possible_interfaces: bitmap if interface modes that the attached PHY
  *			 will switch between depending on media speed.
@@ -681,6 +683,8 @@  struct phy_device {
 	unsigned irq_suspended:1;
 	unsigned irq_rerun:1;
 
+	unsigned default_timestamp:1;
+
 	int rate_matching;
 
 	enum phy_state state;
@@ -1625,6 +1629,21 @@  static inline void phy_txtstamp(struct phy_device *phydev, struct sk_buff *skb,
 	phydev->mii_ts->txtstamp(phydev->mii_ts, skb, type);
 }
 
+/**
+ * phy_is_default_hwtstamp - Is the PHY hwtstamp the default timestamp
+ * @phydev: Pointer to phy_device
+ *
+ * This is used to get default timestamping device taking into account
+ * the new API choice, which is selecting the timestamping from MAC by
+ * default if the phydev does not have default_timestamp flag enabled.
+ *
+ * Return: True if phy is the default hw timestamp, false otherwise.
+ */
+static inline bool phy_is_default_hwtstamp(struct phy_device *phydev)
+{
+	return phy_has_hwtstamp(phydev) && phydev->default_timestamp;
+}
+
 /**
  * phy_is_internal - Convenience function for testing if a PHY is internal
  * @phydev: the phy_device struct
diff --git a/net/core/dev_ioctl.c b/net/core/dev_ioctl.c
index 6aaa8326bf8f..36cea843381f 100644
--- a/net/core/dev_ioctl.c
+++ b/net/core/dev_ioctl.c
@@ -259,9 +259,7 @@  static int dev_eth_ioctl(struct net_device *dev,
  * @dev: Network device
  * @cfg: Timestamping configuration structure
  *
- * Helper for enforcing a common policy that phylib timestamping, if available,
- * should take precedence in front of hardware timestamping provided by the
- * netdev.
+ * Helper for calling the default hardware provider timestamping.
  *
  * Note: phy_mii_ioctl() only handles SIOCSHWTSTAMP (not SIOCGHWTSTAMP), and
  * there only exists a phydev->mii_ts->hwtstamp() method. So this will return
@@ -271,7 +269,7 @@  static int dev_eth_ioctl(struct net_device *dev,
 int dev_get_hwtstamp_phylib(struct net_device *dev,
 			    struct kernel_hwtstamp_config *cfg)
 {
-	if (phy_has_hwtstamp(dev->phydev))
+	if (phy_is_default_hwtstamp(dev->phydev))
 		return phy_hwtstamp_get(dev->phydev, cfg);
 
 	return dev->netdev_ops->ndo_hwtstamp_get(dev, cfg);
@@ -327,7 +325,7 @@  int dev_set_hwtstamp_phylib(struct net_device *dev,
 			    struct netlink_ext_ack *extack)
 {
 	const struct net_device_ops *ops = dev->netdev_ops;
-	bool phy_ts = phy_has_hwtstamp(dev->phydev);
+	bool phy_ts = phy_is_default_hwtstamp(dev->phydev);
 	struct kernel_hwtstamp_config old_cfg = {};
 	bool changed = false;
 	int err;
diff --git a/net/core/timestamping.c b/net/core/timestamping.c
index 04840697fe79..3717fb152ecc 100644
--- a/net/core/timestamping.c
+++ b/net/core/timestamping.c
@@ -25,7 +25,8 @@  void skb_clone_tx_timestamp(struct sk_buff *skb)
 	struct sk_buff *clone;
 	unsigned int type;
 
-	if (!skb->sk)
+	if (!skb->sk || !skb->dev ||
+	    !phy_is_default_hwtstamp(skb->dev->phydev))
 		return;
 
 	type = classify(skb);
@@ -47,7 +48,7 @@  bool skb_defer_rx_timestamp(struct sk_buff *skb)
 	struct mii_timestamper *mii_ts;
 	unsigned int type;
 
-	if (!skb->dev || !skb->dev->phydev || !skb->dev->phydev->mii_ts)
+	if (!skb->dev || !phy_is_default_hwtstamp(skb->dev->phydev))
 		return false;
 
 	if (skb_headroom(skb) < ETH_HLEN)
diff --git a/net/ethtool/common.c b/net/ethtool/common.c
index 6b2a360dcdf0..01b7550f12c6 100644
--- a/net/ethtool/common.c
+++ b/net/ethtool/common.c
@@ -637,7 +637,7 @@  int __ethtool_get_ts_info(struct net_device *dev, struct ethtool_ts_info *info)
 	memset(info, 0, sizeof(*info));
 	info->cmd = ETHTOOL_GET_TS_INFO;
 
-	if (phy_has_tsinfo(phydev))
+	if (phy_is_default_hwtstamp(phydev) && phy_has_tsinfo(phydev))
 		return phy_ts_info(phydev, info);
 	if (ops->get_ts_info)
 		return ops->get_ts_info(dev, info);