diff mbox series

[1/2] net: stmmac: retain PTP-clock at hwtstamp_set

Message ID 20201216113239.2980816-1-h.assmann@pengutronix.de (mailing list archive)
State Changes Requested
Delegated to: Netdev Maintainers
Headers show
Series [1/2] net: stmmac: retain PTP-clock at hwtstamp_set | expand

Checks

Context Check Description
netdev/cover_letter success Link
netdev/fixes_present success Link
netdev/patch_count success Link
netdev/tree_selection success Guessed tree name to be net-next
netdev/subject_prefix warning Target tree name not specified in the subject
netdev/source_inline success Was 0 now: 0
netdev/verify_signedoff success Link
netdev/module_param success Was 0 now: 0
netdev/build_32bit fail Errors and warnings before: 0 this patch: 1
netdev/kdoc success Errors and warnings before: 0 this patch: 0
netdev/verify_fixes fail Link
netdev/checkpatch fail CHECK: Alignment should match open parenthesis CHECK: Please don't use multiple blank lines ERROR: trailing whitespace WARNING: Block comments use a trailing */ on a separate line WARNING: line length of 81 exceeds 80 columns WARNING: line length of 84 exceeds 80 columns WARNING: line length of 90 exceeds 80 columns
netdev/build_allmodconfig_warn fail Errors and warnings before: 0 this patch: 1
netdev/header_inline success Link
netdev/stable success Stable not CCed

Commit Message

Holger Assmann Dec. 16, 2020, 11:32 a.m. UTC
As it is, valid SIOCSHWTSTAMP ioctl calls - i.e. enable/disable time
stamping or changing filter settings - lead to synchronization of the
NIC's hardware clock with CLOCK_REALTIME. This might be necessary
during system initialization, but at runtime, when the PTP clock has
already been synchronized to a grand master, a reset of the timestamp
settings might result in a clock jump.

This further differs from how drivers like IGB and FEC behave: Those
initialize the PTP system time less frequently - on interface up and
at probe time, respectively.

We consequently introduce the new function stmmac_init_hwtstamp(), which
gets called during ndo_open(). It contains the code snippet moved
from stmmac_hwtstamp_set() that manages the time synchronization. Besides,
the sub second increment configuration is also moved here since the
related values are hardware dependent and do not change during runtime.

Furthermore, the hardware clock must be kept running even when no time
stamping mode is selected in order to retain the once synced time basis.
That way, time stamping can be enabled again at any time only with the
need for compensation of the clock's natural drifting.

As a side effect, this patch fixes a potential race between SIOCSHWTSTAMP
and ptp_clock_info::enable regarding priv->systime_flags. Subsequently,
since this variable becomes deprecated by this commit, it should be
removed completely in a follow-up patch.

Fixes: 92ba6888510c ("stmmac: add the support for PTP hw clock driver")
Fixes: cc4c9001ce31 ("net: stmmac: Switch stmmac_hwtimestamp to generic
HW Interface Helpers")

Reported-by: Michael Olbrich <m.olbrich@pengutronix.de>
Signed-off-by: Ahmad Fatoum <a.fatoum@pengutronix.de>
Signed-off-by: Holger Assmann <h.assmann@pengutronix.de>
---
 .../net/ethernet/stmicro/stmmac/stmmac_main.c | 121 ++++++++++++------
 1 file changed, 80 insertions(+), 41 deletions(-)


base-commit: 3db1a3fa98808aa90f95ec3e0fa2fc7abf28f5c9

Comments

Jakub Kicinski Dec. 17, 2020, 1:13 a.m. UTC | #1
On Wed, 16 Dec 2020 12:32:38 +0100 Holger Assmann wrote:
> As it is, valid SIOCSHWTSTAMP ioctl calls - i.e. enable/disable time
> stamping or changing filter settings - lead to synchronization of the
> NIC's hardware clock with CLOCK_REALTIME. This might be necessary
> during system initialization, but at runtime, when the PTP clock has
> already been synchronized to a grand master, a reset of the timestamp
> settings might result in a clock jump.
> 
> This further differs from how drivers like IGB and FEC behave: Those
> initialize the PTP system time less frequently - on interface up and
> at probe time, respectively.
> 
> We consequently introduce the new function stmmac_init_hwtstamp(), which
> gets called during ndo_open(). It contains the code snippet moved
> from stmmac_hwtstamp_set() that manages the time synchronization. Besides,
> the sub second increment configuration is also moved here since the
> related values are hardware dependent and do not change during runtime.
> 
> Furthermore, the hardware clock must be kept running even when no time
> stamping mode is selected in order to retain the once synced time basis.
> That way, time stamping can be enabled again at any time only with the
> need for compensation of the clock's natural drifting.
> 
> As a side effect, this patch fixes a potential race between SIOCSHWTSTAMP
> and ptp_clock_info::enable regarding priv->systime_flags. Subsequently,
> since this variable becomes deprecated by this commit, it should be
> removed completely in a follow-up patch.
> 
> Fixes: 92ba6888510c ("stmmac: add the support for PTP hw clock driver")
> Fixes: cc4c9001ce31 ("net: stmmac: Switch stmmac_hwtimestamp to generic
> HW Interface Helpers")
> 

Thanks for the patch, minor nits below.

If you post a v2 please don't wrap fixes tags and no space between
those and the other tags.

Also please put the tree in the subject, like [PATCH net 1/2].

Please remember to CC Richard, the PTP maintainer.

> Reported-by: Michael Olbrich <m.olbrich@pengutronix.de>
> Signed-off-by: Ahmad Fatoum <a.fatoum@pengutronix.de>
> Signed-off-by: Holger Assmann <h.assmann@pengutronix.de>
> ---
>  .../net/ethernet/stmicro/stmmac/stmmac_main.c | 121 ++++++++++++------
>  1 file changed, 80 insertions(+), 41 deletions(-)
> 
> diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
> index 5b1c12ff98c0..55f5e6cd1cad 100644
> --- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
> +++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
> @@ -46,6 +46,13 @@
>  #include "dwxgmac2.h"
>  #include "hwif.h"
>  
> +

Spurious new line

> +/* As long the interface is active, we keep the timestamping HW enabled with
> + * fine resolution and binary rollover. This avoid non-monotonic behavior
> + * when changing timestamp settings at runtime
> + * */

The */ should be on a line of its own.

> +#define STMMAC_HWTS_ACTIVE (PTP_TCR_TSENA | PTP_TCR_TSCFUPDT | PTP_TCR_TSCTRLSSR)
> +
>  #define	STMMAC_ALIGN(x)		ALIGN(ALIGN(x, SMP_CACHE_BYTES), 16)
>  #define	TSO_MAX_BUFF_SIZE	(SZ_16K - 1)

> @@ -791,6 +772,63 @@ static void stmmac_release_ptp(struct stmmac_priv *priv)
>  	stmmac_ptp_unregister(priv);
>  }
>  
> +/**
> + * stmmac_init_hwtstamp - init Timestamping Hardware
> + * @priv: driver private structure
> + * Description: Initialize hardware for Timestamping use
> + * This is valid as long as the interface is open and not suspended.
> + * Will be rerun after resume from suspension.
> + */
> +static int stmmac_init_hwtstamp(struct stmmac_priv *priv)
> +{
> +	bool xmac = priv->plat->has_gmac4 || priv->plat->has_xgmac;
> +	struct timespec64 now;
> +	u32 sec_inc = 0;
> +	u64 temp = 0;
> +	u32 value;
> +	int ret;
> +
> +	ret = clk_prepare_enable(priv->plat->clk_ptp_ref);
> +	if (ret < 0) {
> +		netdev_warn(priv->dev, "failed to enable PTP reference clock: %d\n", ret);
> +		return ret;
> +	}
> +
> +	if (!(priv->dma_cap.time_stamp || priv->dma_cap.atime_stamp))

!a && !b reads better IMHO

> +		return -EOPNOTSUPP;
> +
> +	value = STMMAC_HWTS_ACTIVE;
> +	stmmac_config_hw_tstamping(priv, priv->ptpaddr, value);
> +
> +	/* program Sub Second Increment reg */
> +	stmmac_config_sub_second_increment(priv,
> +			priv->ptpaddr, priv->plat->clk_ptp_rate,
> +			xmac, &sec_inc);

Now that this code is not indented as much any more please align the
continuation lines under the opening bracket.

> +	temp = div_u64(1000000000ULL, sec_inc);
> +
> +	/* Store sub second increment and flags for later use */
> +	priv->sub_second_inc = sec_inc;
> +	priv->systime_flags = value;
> +
> +	/* calculate default added value:
> +	 * formula is :
> +	 * addend = (2^32)/freq_div_ratio;
> +	 * where, freq_div_ratio = 1e9ns/sec_inc
> +	 */
> +	temp = (u64)(temp << 32);
> +	priv->default_addend = div_u64(temp, priv->plat->clk_ptp_rate);
> +	stmmac_config_addend(priv, priv->ptpaddr, priv->default_addend);
> +
> +	/* initialize system time */
> +	ktime_get_real_ts64(&now);
> +
> +	/* lower 32 bits of tv_sec are safe until y2106 */
> +	stmmac_init_systime(priv, priv->ptpaddr,
> +			(u32)now.tv_sec, now.tv_nsec);

ditto

> +
> +	return 0;
> +}
> +
>  /**
>   *  stmmac_mac_flow_ctrl - Configure flow control in all queues
>   *  @priv: driver private structure
> @@ -2713,15 +2751,17 @@ static int stmmac_hw_setup(struct net_device *dev, bool init_ptp)
>  	stmmac_mmc_setup(priv);
>  
>  	if (init_ptp) {
> -		ret = clk_prepare_enable(priv->plat->clk_ptp_ref);
> -		if (ret < 0)
> -			netdev_warn(priv->dev, "failed to enable PTP reference clock: %d\n", ret);
> -
> -		ret = stmmac_init_ptp(priv);
> -		if (ret == -EOPNOTSUPP)
> -			netdev_warn(priv->dev, "PTP not supported by HW\n");
> -		else if (ret)
> -			netdev_warn(priv->dev, "PTP init failed\n");
> +		ret = stmmac_init_hwtstamp(priv);
> +		if (ret) {
> +			netdev_warn(priv->dev, "HW Timestamping init failed: %pe\n",
> +					ERR_PTR(ret));

why convert to ERR_PTR and use %pe and not just %d?

also continuation misaligned

> +		} else {
> +			ret = stmmac_init_ptp(priv);
> +			if (ret == -EOPNOTSUPP)
> +				netdev_warn(priv->dev, "PTP not supported by HW\n");
> +			else if (ret)
> +				netdev_warn(priv->dev, "PTP init failed\n");
> +		}
>  	}
>  
>  	priv->eee_tw_timer = STMMAC_DEFAULT_TWT_LS;
> @@ -5290,8 +5330,7 @@ int stmmac_resume(struct device *dev)
>  		/* enable the clk previously disabled */
>  		clk_prepare_enable(priv->plat->stmmac_clk);
>  		clk_prepare_enable(priv->plat->pclk);
> -		if (priv->plat->clk_ptp_ref)
> -			clk_prepare_enable(priv->plat->clk_ptp_ref);
> +		stmmac_init_hwtstamp(priv);

This was optional, now you always init?

>  		/* reset the phy so that it's ready */
>  		if (priv->mii)
>  			stmmac_mdio_reset(priv->mii);
> 
> base-commit: 3db1a3fa98808aa90f95ec3e0fa2fc7abf28f5c9
Richard Cochran Dec. 17, 2020, 2:22 a.m. UTC | #2
On Wed, Dec 16, 2020 at 05:13:34PM -0800, Jakub Kicinski wrote:
> On Wed, 16 Dec 2020 12:32:38 +0100 Holger Assmann wrote:
> > As it is, valid SIOCSHWTSTAMP ioctl calls - i.e. enable/disable time
> > stamping or changing filter settings - lead to synchronization of the
> > NIC's hardware clock with CLOCK_REALTIME. This might be necessary
> > during system initialization, but at runtime, when the PTP clock has
> > already been synchronized to a grand master, a reset of the timestamp
> > settings might result in a clock jump.

+1 for keeping the PHC time continuous.

> Please remember to CC Richard, the PTP maintainer.

+1 to that, too!

Thanks,
Richard
Ahmad Fatoum Dec. 17, 2020, 8:25 a.m. UTC | #3
Hello,

On 17.12.20 02:13, Jakub Kicinski wrote:
>> +			netdev_warn(priv->dev, "HW Timestamping init failed: %pe\n",
>> +					ERR_PTR(ret));
> 
> why convert to ERR_PTR and use %pe and not just %d?

To get a symbolic error name if support is compiled in (note the `e' after %p).

> 
> also continuation misaligned
> 
>> +		} else {
>> +			ret = stmmac_init_ptp(priv);
>> +			if (ret == -EOPNOTSUPP)
>> +				netdev_warn(priv->dev, "PTP not supported by HW\n");
>> +			else if (ret)
>> +				netdev_warn(priv->dev, "PTP init failed\n");
>> +		}
>>  	}
>>  
>>  	priv->eee_tw_timer = STMMAC_DEFAULT_TWT_LS;
>> @@ -5290,8 +5330,7 @@ int stmmac_resume(struct device *dev)
>>  		/* enable the clk previously disabled */
>>  		clk_prepare_enable(priv->plat->stmmac_clk);
>>  		clk_prepare_enable(priv->plat->pclk);
>> -		if (priv->plat->clk_ptp_ref)
>> -			clk_prepare_enable(priv->plat->clk_ptp_ref);
>> +		stmmac_init_hwtstamp(priv);
> 
> This was optional, now you always init?

Indeed, omitting the if condition here will lead to a needless warning on every reset.

Cheers,
Ahmad

> 
>>  		/* reset the phy so that it's ready */
>>  		if (priv->mii)
>>  			stmmac_mdio_reset(priv->mii);
>>
>> base-commit: 3db1a3fa98808aa90f95ec3e0fa2fc7abf28f5c9
> 
>
Jakub Kicinski Dec. 17, 2020, 5:59 p.m. UTC | #4
On Thu, 17 Dec 2020 09:25:48 +0100 Ahmad Fatoum wrote:
> On 17.12.20 02:13, Jakub Kicinski wrote:
> >> +			netdev_warn(priv->dev, "HW Timestamping init failed: %pe\n",
> >> +					ERR_PTR(ret));  
> > 
> > why convert to ERR_PTR and use %pe and not just %d?  
> 
> To get a symbolic error name if support is compiled in (note the `e' after %p).

Cool, GTK. Kind of weird we there is no equivalent int decorator, tho.
Do you happen to know why?
Ahmad Fatoum Dec. 17, 2020, 7:58 p.m. UTC | #5
On 17.12.20 18:59, Jakub Kicinski wrote:
> On Thu, 17 Dec 2020 09:25:48 +0100 Ahmad Fatoum wrote:
>> On 17.12.20 02:13, Jakub Kicinski wrote:
>>>> +			netdev_warn(priv->dev, "HW Timestamping init failed: %pe\n",
>>>> +					ERR_PTR(ret));  
>>>
>>> why convert to ERR_PTR and use %pe and not just %d?  
>>
>> To get a symbolic error name if support is compiled in (note the `e' after %p).
> 
> Cool, GTK. Kind of weird we there is no equivalent int decorator, tho.
> Do you happen to know why?
New format-specifiers should be using %p<extension>, which is already established,
said the reviewers:

https://lore.kernel.org/lkml/20200120085508.25522-1-u.kleine-koenig@pengutronix.de/
kernel test robot Dec. 27, 2020, 7:08 a.m. UTC | #6
Hi Holger,

Thank you for the patch! Perhaps something to improve:

[auto build test WARNING on 3db1a3fa98808aa90f95ec3e0fa2fc7abf28f5c9]

url:    https://github.com/0day-ci/linux/commits/Holger-Assmann/net-stmmac-retain-PTP-clock-at-hwtstamp_set/20201216-194127
base:    3db1a3fa98808aa90f95ec3e0fa2fc7abf28f5c9
config: arm-randconfig-r021-20201221 (attached as .config)
compiler: arm-linux-gnueabi-gcc (GCC) 9.3.0
reproduce (this is a W=1 build):
        wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross
        chmod +x ~/bin/make.cross
        # https://github.com/0day-ci/linux/commit/303da978c0e8ad80e7577245b7c399f601a29b7a
        git remote add linux-review https://github.com/0day-ci/linux
        git fetch --no-tags linux-review Holger-Assmann/net-stmmac-retain-PTP-clock-at-hwtstamp_set/20201216-194127
        git checkout 303da978c0e8ad80e7577245b7c399f601a29b7a
        # save the attached .config to linux build tree
        COMPILER_INSTALL_PATH=$HOME/0day COMPILER=gcc-9.3.0 make.cross ARCH=arm 

If you fix the issue, kindly add following tag as appropriate
Reported-by: kernel test robot <lkp@intel.com>

All warnings (new ones prefixed by >>):

   drivers/net/ethernet/stmicro/stmmac/stmmac_main.c: In function 'stmmac_hwtstamp_set':
>> drivers/net/ethernet/stmicro/stmmac/stmmac_main.c:528:7: warning: variable 'xmac' set but not used [-Wunused-but-set-variable]
     528 |  bool xmac;
         |       ^~~~


vim +/xmac +528 drivers/net/ethernet/stmicro/stmmac/stmmac_main.c

891434b18ec0a21 Rayagond Kokatanur 2013-03-26  503  
891434b18ec0a21 Rayagond Kokatanur 2013-03-26  504  /**
d6228b7cdd6e790 Artem Panfilov     2019-01-20  505   *  stmmac_hwtstamp_set - control hardware timestamping.
891434b18ec0a21 Rayagond Kokatanur 2013-03-26  506   *  @dev: device pointer.
8d45e42babb1c7b LABBE Corentin     2017-02-08  507   *  @ifr: An IOCTL specific structure, that can contain a pointer to
891434b18ec0a21 Rayagond Kokatanur 2013-03-26  508   *  a proprietary structure used to pass information to the driver.
891434b18ec0a21 Rayagond Kokatanur 2013-03-26  509   *  Description:
891434b18ec0a21 Rayagond Kokatanur 2013-03-26  510   *  This function configures the MAC to enable/disable both outgoing(TX)
891434b18ec0a21 Rayagond Kokatanur 2013-03-26  511   *  and incoming(RX) packets time stamping based on user input.
891434b18ec0a21 Rayagond Kokatanur 2013-03-26  512   *  Return Value:
891434b18ec0a21 Rayagond Kokatanur 2013-03-26  513   *  0 on success and an appropriate -ve integer on failure.
891434b18ec0a21 Rayagond Kokatanur 2013-03-26  514   */
d6228b7cdd6e790 Artem Panfilov     2019-01-20  515  static int stmmac_hwtstamp_set(struct net_device *dev, struct ifreq *ifr)
891434b18ec0a21 Rayagond Kokatanur 2013-03-26  516  {
891434b18ec0a21 Rayagond Kokatanur 2013-03-26  517  	struct stmmac_priv *priv = netdev_priv(dev);
891434b18ec0a21 Rayagond Kokatanur 2013-03-26  518  	struct hwtstamp_config config;
891434b18ec0a21 Rayagond Kokatanur 2013-03-26  519  	u32 ptp_v2 = 0;
891434b18ec0a21 Rayagond Kokatanur 2013-03-26  520  	u32 tstamp_all = 0;
891434b18ec0a21 Rayagond Kokatanur 2013-03-26  521  	u32 ptp_over_ipv4_udp = 0;
891434b18ec0a21 Rayagond Kokatanur 2013-03-26  522  	u32 ptp_over_ipv6_udp = 0;
891434b18ec0a21 Rayagond Kokatanur 2013-03-26  523  	u32 ptp_over_ethernet = 0;
891434b18ec0a21 Rayagond Kokatanur 2013-03-26  524  	u32 snap_type_sel = 0;
891434b18ec0a21 Rayagond Kokatanur 2013-03-26  525  	u32 ts_master_en = 0;
891434b18ec0a21 Rayagond Kokatanur 2013-03-26  526  	u32 ts_event_en = 0;
891434b18ec0a21 Rayagond Kokatanur 2013-03-26  527  	u32 value = 0;
7d9e6c5afab6bfb Jose Abreu         2018-08-08 @528  	bool xmac;
7d9e6c5afab6bfb Jose Abreu         2018-08-08  529  
7d9e6c5afab6bfb Jose Abreu         2018-08-08  530  	xmac = priv->plat->has_gmac4 || priv->plat->has_xgmac;
891434b18ec0a21 Rayagond Kokatanur 2013-03-26  531  
891434b18ec0a21 Rayagond Kokatanur 2013-03-26  532  	if (!(priv->dma_cap.time_stamp || priv->adv_ts)) {
891434b18ec0a21 Rayagond Kokatanur 2013-03-26  533  		netdev_alert(priv->dev, "No support for HW time stamping\n");
891434b18ec0a21 Rayagond Kokatanur 2013-03-26  534  		priv->hwts_tx_en = 0;
891434b18ec0a21 Rayagond Kokatanur 2013-03-26  535  		priv->hwts_rx_en = 0;
891434b18ec0a21 Rayagond Kokatanur 2013-03-26  536  
891434b18ec0a21 Rayagond Kokatanur 2013-03-26  537  		return -EOPNOTSUPP;
891434b18ec0a21 Rayagond Kokatanur 2013-03-26  538  	}
891434b18ec0a21 Rayagond Kokatanur 2013-03-26  539  
891434b18ec0a21 Rayagond Kokatanur 2013-03-26  540  	if (copy_from_user(&config, ifr->ifr_data,
d6228b7cdd6e790 Artem Panfilov     2019-01-20  541  			   sizeof(config)))
891434b18ec0a21 Rayagond Kokatanur 2013-03-26  542  		return -EFAULT;
891434b18ec0a21 Rayagond Kokatanur 2013-03-26  543  
38ddc59d65b6d97 LABBE Corentin     2016-11-16  544  	netdev_dbg(priv->dev, "%s config flags:0x%x, tx_type:0x%x, rx_filter:0x%x\n",
891434b18ec0a21 Rayagond Kokatanur 2013-03-26  545  		   __func__, config.flags, config.tx_type, config.rx_filter);
891434b18ec0a21 Rayagond Kokatanur 2013-03-26  546  
891434b18ec0a21 Rayagond Kokatanur 2013-03-26  547  	/* reserved for future extensions */
891434b18ec0a21 Rayagond Kokatanur 2013-03-26  548  	if (config.flags)
891434b18ec0a21 Rayagond Kokatanur 2013-03-26  549  		return -EINVAL;
891434b18ec0a21 Rayagond Kokatanur 2013-03-26  550  
5f3da3281932a79 Ben Hutchings      2013-11-14  551  	if (config.tx_type != HWTSTAMP_TX_OFF &&
5f3da3281932a79 Ben Hutchings      2013-11-14  552  	    config.tx_type != HWTSTAMP_TX_ON)
891434b18ec0a21 Rayagond Kokatanur 2013-03-26  553  		return -ERANGE;
891434b18ec0a21 Rayagond Kokatanur 2013-03-26  554  
891434b18ec0a21 Rayagond Kokatanur 2013-03-26  555  	if (priv->adv_ts) {
891434b18ec0a21 Rayagond Kokatanur 2013-03-26  556  		switch (config.rx_filter) {
891434b18ec0a21 Rayagond Kokatanur 2013-03-26  557  		case HWTSTAMP_FILTER_NONE:
ceb694997e1b5d4 Giuseppe CAVALLARO 2013-04-08  558  			/* time stamp no incoming packet at all */
891434b18ec0a21 Rayagond Kokatanur 2013-03-26  559  			config.rx_filter = HWTSTAMP_FILTER_NONE;
891434b18ec0a21 Rayagond Kokatanur 2013-03-26  560  			break;
891434b18ec0a21 Rayagond Kokatanur 2013-03-26  561  
891434b18ec0a21 Rayagond Kokatanur 2013-03-26  562  		case HWTSTAMP_FILTER_PTP_V1_L4_EVENT:
ceb694997e1b5d4 Giuseppe CAVALLARO 2013-04-08  563  			/* PTP v1, UDP, any kind of event packet */
891434b18ec0a21 Rayagond Kokatanur 2013-03-26  564  			config.rx_filter = HWTSTAMP_FILTER_PTP_V1_L4_EVENT;
7d8e249f393a1ac Ilias Apalodimas   2019-02-05  565  			/* 'xmac' hardware can support Sync, Pdelay_Req and
7d8e249f393a1ac Ilias Apalodimas   2019-02-05  566  			 * Pdelay_resp by setting bit14 and bits17/16 to 01
7d8e249f393a1ac Ilias Apalodimas   2019-02-05  567  			 * This leaves Delay_Req timestamps out.
7d8e249f393a1ac Ilias Apalodimas   2019-02-05  568  			 * Enable all events *and* general purpose message
7d8e249f393a1ac Ilias Apalodimas   2019-02-05  569  			 * timestamping
7d8e249f393a1ac Ilias Apalodimas   2019-02-05  570  			 */
891434b18ec0a21 Rayagond Kokatanur 2013-03-26  571  			snap_type_sel = PTP_TCR_SNAPTYPSEL_1;
891434b18ec0a21 Rayagond Kokatanur 2013-03-26  572  			ptp_over_ipv4_udp = PTP_TCR_TSIPV4ENA;
891434b18ec0a21 Rayagond Kokatanur 2013-03-26  573  			ptp_over_ipv6_udp = PTP_TCR_TSIPV6ENA;
891434b18ec0a21 Rayagond Kokatanur 2013-03-26  574  			break;
891434b18ec0a21 Rayagond Kokatanur 2013-03-26  575  
891434b18ec0a21 Rayagond Kokatanur 2013-03-26  576  		case HWTSTAMP_FILTER_PTP_V1_L4_SYNC:
ceb694997e1b5d4 Giuseppe CAVALLARO 2013-04-08  577  			/* PTP v1, UDP, Sync packet */
891434b18ec0a21 Rayagond Kokatanur 2013-03-26  578  			config.rx_filter = HWTSTAMP_FILTER_PTP_V1_L4_SYNC;
891434b18ec0a21 Rayagond Kokatanur 2013-03-26  579  			/* take time stamp for SYNC messages only */
891434b18ec0a21 Rayagond Kokatanur 2013-03-26  580  			ts_event_en = PTP_TCR_TSEVNTENA;
891434b18ec0a21 Rayagond Kokatanur 2013-03-26  581  
891434b18ec0a21 Rayagond Kokatanur 2013-03-26  582  			ptp_over_ipv4_udp = PTP_TCR_TSIPV4ENA;
891434b18ec0a21 Rayagond Kokatanur 2013-03-26  583  			ptp_over_ipv6_udp = PTP_TCR_TSIPV6ENA;
891434b18ec0a21 Rayagond Kokatanur 2013-03-26  584  			break;
891434b18ec0a21 Rayagond Kokatanur 2013-03-26  585  
891434b18ec0a21 Rayagond Kokatanur 2013-03-26  586  		case HWTSTAMP_FILTER_PTP_V1_L4_DELAY_REQ:
ceb694997e1b5d4 Giuseppe CAVALLARO 2013-04-08  587  			/* PTP v1, UDP, Delay_req packet */
891434b18ec0a21 Rayagond Kokatanur 2013-03-26  588  			config.rx_filter = HWTSTAMP_FILTER_PTP_V1_L4_DELAY_REQ;
891434b18ec0a21 Rayagond Kokatanur 2013-03-26  589  			/* take time stamp for Delay_Req messages only */
891434b18ec0a21 Rayagond Kokatanur 2013-03-26  590  			ts_master_en = PTP_TCR_TSMSTRENA;
891434b18ec0a21 Rayagond Kokatanur 2013-03-26  591  			ts_event_en = PTP_TCR_TSEVNTENA;
891434b18ec0a21 Rayagond Kokatanur 2013-03-26  592  
891434b18ec0a21 Rayagond Kokatanur 2013-03-26  593  			ptp_over_ipv4_udp = PTP_TCR_TSIPV4ENA;
891434b18ec0a21 Rayagond Kokatanur 2013-03-26  594  			ptp_over_ipv6_udp = PTP_TCR_TSIPV6ENA;
891434b18ec0a21 Rayagond Kokatanur 2013-03-26  595  			break;
891434b18ec0a21 Rayagond Kokatanur 2013-03-26  596  
891434b18ec0a21 Rayagond Kokatanur 2013-03-26  597  		case HWTSTAMP_FILTER_PTP_V2_L4_EVENT:
ceb694997e1b5d4 Giuseppe CAVALLARO 2013-04-08  598  			/* PTP v2, UDP, any kind of event packet */
891434b18ec0a21 Rayagond Kokatanur 2013-03-26  599  			config.rx_filter = HWTSTAMP_FILTER_PTP_V2_L4_EVENT;
891434b18ec0a21 Rayagond Kokatanur 2013-03-26  600  			ptp_v2 = PTP_TCR_TSVER2ENA;
891434b18ec0a21 Rayagond Kokatanur 2013-03-26  601  			/* take time stamp for all event messages */
891434b18ec0a21 Rayagond Kokatanur 2013-03-26  602  			snap_type_sel = PTP_TCR_SNAPTYPSEL_1;
891434b18ec0a21 Rayagond Kokatanur 2013-03-26  603  
891434b18ec0a21 Rayagond Kokatanur 2013-03-26  604  			ptp_over_ipv4_udp = PTP_TCR_TSIPV4ENA;
891434b18ec0a21 Rayagond Kokatanur 2013-03-26  605  			ptp_over_ipv6_udp = PTP_TCR_TSIPV6ENA;
891434b18ec0a21 Rayagond Kokatanur 2013-03-26  606  			break;
891434b18ec0a21 Rayagond Kokatanur 2013-03-26  607  
891434b18ec0a21 Rayagond Kokatanur 2013-03-26  608  		case HWTSTAMP_FILTER_PTP_V2_L4_SYNC:
ceb694997e1b5d4 Giuseppe CAVALLARO 2013-04-08  609  			/* PTP v2, UDP, Sync packet */
891434b18ec0a21 Rayagond Kokatanur 2013-03-26  610  			config.rx_filter = HWTSTAMP_FILTER_PTP_V2_L4_SYNC;
891434b18ec0a21 Rayagond Kokatanur 2013-03-26  611  			ptp_v2 = PTP_TCR_TSVER2ENA;
891434b18ec0a21 Rayagond Kokatanur 2013-03-26  612  			/* take time stamp for SYNC messages only */
891434b18ec0a21 Rayagond Kokatanur 2013-03-26  613  			ts_event_en = PTP_TCR_TSEVNTENA;
891434b18ec0a21 Rayagond Kokatanur 2013-03-26  614  
891434b18ec0a21 Rayagond Kokatanur 2013-03-26  615  			ptp_over_ipv4_udp = PTP_TCR_TSIPV4ENA;
891434b18ec0a21 Rayagond Kokatanur 2013-03-26  616  			ptp_over_ipv6_udp = PTP_TCR_TSIPV6ENA;
891434b18ec0a21 Rayagond Kokatanur 2013-03-26  617  			break;
891434b18ec0a21 Rayagond Kokatanur 2013-03-26  618  
891434b18ec0a21 Rayagond Kokatanur 2013-03-26  619  		case HWTSTAMP_FILTER_PTP_V2_L4_DELAY_REQ:
ceb694997e1b5d4 Giuseppe CAVALLARO 2013-04-08  620  			/* PTP v2, UDP, Delay_req packet */
891434b18ec0a21 Rayagond Kokatanur 2013-03-26  621  			config.rx_filter = HWTSTAMP_FILTER_PTP_V2_L4_DELAY_REQ;
891434b18ec0a21 Rayagond Kokatanur 2013-03-26  622  			ptp_v2 = PTP_TCR_TSVER2ENA;
891434b18ec0a21 Rayagond Kokatanur 2013-03-26  623  			/* take time stamp for Delay_Req messages only */
891434b18ec0a21 Rayagond Kokatanur 2013-03-26  624  			ts_master_en = PTP_TCR_TSMSTRENA;
891434b18ec0a21 Rayagond Kokatanur 2013-03-26  625  			ts_event_en = PTP_TCR_TSEVNTENA;
891434b18ec0a21 Rayagond Kokatanur 2013-03-26  626  
891434b18ec0a21 Rayagond Kokatanur 2013-03-26  627  			ptp_over_ipv4_udp = PTP_TCR_TSIPV4ENA;
891434b18ec0a21 Rayagond Kokatanur 2013-03-26  628  			ptp_over_ipv6_udp = PTP_TCR_TSIPV6ENA;
891434b18ec0a21 Rayagond Kokatanur 2013-03-26  629  			break;
891434b18ec0a21 Rayagond Kokatanur 2013-03-26  630  
891434b18ec0a21 Rayagond Kokatanur 2013-03-26  631  		case HWTSTAMP_FILTER_PTP_V2_EVENT:
ceb694997e1b5d4 Giuseppe CAVALLARO 2013-04-08  632  			/* PTP v2/802.AS1 any layer, any kind of event packet */
891434b18ec0a21 Rayagond Kokatanur 2013-03-26  633  			config.rx_filter = HWTSTAMP_FILTER_PTP_V2_EVENT;
891434b18ec0a21 Rayagond Kokatanur 2013-03-26  634  			ptp_v2 = PTP_TCR_TSVER2ENA;
891434b18ec0a21 Rayagond Kokatanur 2013-03-26  635  			snap_type_sel = PTP_TCR_SNAPTYPSEL_1;
f2fb6b6275eba9d Fugang Duan        2020-05-25  636  			if (priv->synopsys_id != DWMAC_CORE_5_10)
14f347334bf2320 Jose Abreu         2019-09-30  637  				ts_event_en = PTP_TCR_TSEVNTENA;
891434b18ec0a21 Rayagond Kokatanur 2013-03-26  638  			ptp_over_ipv4_udp = PTP_TCR_TSIPV4ENA;
891434b18ec0a21 Rayagond Kokatanur 2013-03-26  639  			ptp_over_ipv6_udp = PTP_TCR_TSIPV6ENA;
891434b18ec0a21 Rayagond Kokatanur 2013-03-26  640  			ptp_over_ethernet = PTP_TCR_TSIPENA;
891434b18ec0a21 Rayagond Kokatanur 2013-03-26  641  			break;
891434b18ec0a21 Rayagond Kokatanur 2013-03-26  642  
891434b18ec0a21 Rayagond Kokatanur 2013-03-26  643  		case HWTSTAMP_FILTER_PTP_V2_SYNC:
ceb694997e1b5d4 Giuseppe CAVALLARO 2013-04-08  644  			/* PTP v2/802.AS1, any layer, Sync packet */
891434b18ec0a21 Rayagond Kokatanur 2013-03-26  645  			config.rx_filter = HWTSTAMP_FILTER_PTP_V2_SYNC;
891434b18ec0a21 Rayagond Kokatanur 2013-03-26  646  			ptp_v2 = PTP_TCR_TSVER2ENA;
891434b18ec0a21 Rayagond Kokatanur 2013-03-26  647  			/* take time stamp for SYNC messages only */
891434b18ec0a21 Rayagond Kokatanur 2013-03-26  648  			ts_event_en = PTP_TCR_TSEVNTENA;
891434b18ec0a21 Rayagond Kokatanur 2013-03-26  649  
891434b18ec0a21 Rayagond Kokatanur 2013-03-26  650  			ptp_over_ipv4_udp = PTP_TCR_TSIPV4ENA;
891434b18ec0a21 Rayagond Kokatanur 2013-03-26  651  			ptp_over_ipv6_udp = PTP_TCR_TSIPV6ENA;
891434b18ec0a21 Rayagond Kokatanur 2013-03-26  652  			ptp_over_ethernet = PTP_TCR_TSIPENA;
891434b18ec0a21 Rayagond Kokatanur 2013-03-26  653  			break;
891434b18ec0a21 Rayagond Kokatanur 2013-03-26  654  
891434b18ec0a21 Rayagond Kokatanur 2013-03-26  655  		case HWTSTAMP_FILTER_PTP_V2_DELAY_REQ:
ceb694997e1b5d4 Giuseppe CAVALLARO 2013-04-08  656  			/* PTP v2/802.AS1, any layer, Delay_req packet */
891434b18ec0a21 Rayagond Kokatanur 2013-03-26  657  			config.rx_filter = HWTSTAMP_FILTER_PTP_V2_DELAY_REQ;
891434b18ec0a21 Rayagond Kokatanur 2013-03-26  658  			ptp_v2 = PTP_TCR_TSVER2ENA;
891434b18ec0a21 Rayagond Kokatanur 2013-03-26  659  			/* take time stamp for Delay_Req messages only */
891434b18ec0a21 Rayagond Kokatanur 2013-03-26  660  			ts_master_en = PTP_TCR_TSMSTRENA;
891434b18ec0a21 Rayagond Kokatanur 2013-03-26  661  			ts_event_en = PTP_TCR_TSEVNTENA;
891434b18ec0a21 Rayagond Kokatanur 2013-03-26  662  
891434b18ec0a21 Rayagond Kokatanur 2013-03-26  663  			ptp_over_ipv4_udp = PTP_TCR_TSIPV4ENA;
891434b18ec0a21 Rayagond Kokatanur 2013-03-26  664  			ptp_over_ipv6_udp = PTP_TCR_TSIPV6ENA;
891434b18ec0a21 Rayagond Kokatanur 2013-03-26  665  			ptp_over_ethernet = PTP_TCR_TSIPENA;
891434b18ec0a21 Rayagond Kokatanur 2013-03-26  666  			break;
891434b18ec0a21 Rayagond Kokatanur 2013-03-26  667  
e3412575488ac24 Miroslav Lichvar   2017-05-19  668  		case HWTSTAMP_FILTER_NTP_ALL:
891434b18ec0a21 Rayagond Kokatanur 2013-03-26  669  		case HWTSTAMP_FILTER_ALL:
ceb694997e1b5d4 Giuseppe CAVALLARO 2013-04-08  670  			/* time stamp any incoming packet */
891434b18ec0a21 Rayagond Kokatanur 2013-03-26  671  			config.rx_filter = HWTSTAMP_FILTER_ALL;
891434b18ec0a21 Rayagond Kokatanur 2013-03-26  672  			tstamp_all = PTP_TCR_TSENALL;
891434b18ec0a21 Rayagond Kokatanur 2013-03-26  673  			break;
891434b18ec0a21 Rayagond Kokatanur 2013-03-26  674  
891434b18ec0a21 Rayagond Kokatanur 2013-03-26  675  		default:
891434b18ec0a21 Rayagond Kokatanur 2013-03-26  676  			return -ERANGE;
891434b18ec0a21 Rayagond Kokatanur 2013-03-26  677  		}
891434b18ec0a21 Rayagond Kokatanur 2013-03-26  678  	} else {
891434b18ec0a21 Rayagond Kokatanur 2013-03-26  679  		switch (config.rx_filter) {
891434b18ec0a21 Rayagond Kokatanur 2013-03-26  680  		case HWTSTAMP_FILTER_NONE:
891434b18ec0a21 Rayagond Kokatanur 2013-03-26  681  			config.rx_filter = HWTSTAMP_FILTER_NONE;
891434b18ec0a21 Rayagond Kokatanur 2013-03-26  682  			break;
891434b18ec0a21 Rayagond Kokatanur 2013-03-26  683  		default:
891434b18ec0a21 Rayagond Kokatanur 2013-03-26  684  			/* PTP v1, UDP, any kind of event packet */
891434b18ec0a21 Rayagond Kokatanur 2013-03-26  685  			config.rx_filter = HWTSTAMP_FILTER_PTP_V1_L4_EVENT;
891434b18ec0a21 Rayagond Kokatanur 2013-03-26  686  			break;
891434b18ec0a21 Rayagond Kokatanur 2013-03-26  687  		}
891434b18ec0a21 Rayagond Kokatanur 2013-03-26  688  	}
891434b18ec0a21 Rayagond Kokatanur 2013-03-26  689  	priv->hwts_rx_en = ((config.rx_filter == HWTSTAMP_FILTER_NONE) ? 0 : 1);
5f3da3281932a79 Ben Hutchings      2013-11-14  690  	priv->hwts_tx_en = config.tx_type == HWTSTAMP_TX_ON;
891434b18ec0a21 Rayagond Kokatanur 2013-03-26  691  
891434b18ec0a21 Rayagond Kokatanur 2013-03-26  692  	if (!priv->hwts_tx_en && !priv->hwts_rx_en)
303da978c0e8ad8 Holger Assmann     2020-12-16  693  		stmmac_config_hw_tstamping(priv, priv->ptpaddr, STMMAC_HWTS_ACTIVE);
891434b18ec0a21 Rayagond Kokatanur 2013-03-26  694  	else {
303da978c0e8ad8 Holger Assmann     2020-12-16  695  		value = (STMMAC_HWTS_ACTIVE |
891434b18ec0a21 Rayagond Kokatanur 2013-03-26  696  			 tstamp_all | ptp_v2 | ptp_over_ethernet |
891434b18ec0a21 Rayagond Kokatanur 2013-03-26  697  			 ptp_over_ipv6_udp | ptp_over_ipv4_udp | ts_event_en |
891434b18ec0a21 Rayagond Kokatanur 2013-03-26  698  			 ts_master_en | snap_type_sel);
cc4c9001ce31e0c Jose Abreu         2018-04-16  699  		stmmac_config_hw_tstamping(priv, priv->ptpaddr, value);
891434b18ec0a21 Rayagond Kokatanur 2013-03-26  700  		
303da978c0e8ad8 Holger Assmann     2020-12-16  701  		/* Store flags for later use */
9a8a02c9d46dcd4 Jose Abreu         2018-05-31  702  		priv->systime_flags = value;
891434b18ec0a21 Rayagond Kokatanur 2013-03-26  703  	}
891434b18ec0a21 Rayagond Kokatanur 2013-03-26  704  
d6228b7cdd6e790 Artem Panfilov     2019-01-20  705  	memcpy(&priv->tstamp_config, &config, sizeof(config));
d6228b7cdd6e790 Artem Panfilov     2019-01-20  706  
891434b18ec0a21 Rayagond Kokatanur 2013-03-26  707  	return copy_to_user(ifr->ifr_data, &config,
d6228b7cdd6e790 Artem Panfilov     2019-01-20  708  			    sizeof(config)) ? -EFAULT : 0;
d6228b7cdd6e790 Artem Panfilov     2019-01-20  709  }
d6228b7cdd6e790 Artem Panfilov     2019-01-20  710  

---
0-DAY CI Kernel Test Service, Intel Corporation
https://lists.01.org/hyperkitty/list/kbuild-all@lists.01.org
Holger Assmann Jan. 11, 2021, 8:13 a.m. UTC | #7
On Thu, 17.12.20 um 02:13 Jakub Kicinski wrote:
> 
> Thanks for the patch, minor nits below.

Thanks for the Feedback! I will work it in for my v2.

>> +
>> +	if (!(priv->dma_cap.time_stamp || priv->dma_cap.atime_stamp))
> 
> !a && !b reads better IMHO

We've chosen this variant because it is already used this way in
stmmac_main (e.g. in stmmac_hwtstamp_set(), stmmac_hwtstamp_get(), or
stmmac_validate()).

>> @@ -5290,8 +5330,7 @@ int stmmac_resume(struct device *dev)
>>   		/* enable the clk previously disabled */
>>   		clk_prepare_enable(priv->plat->stmmac_clk);
>>   		clk_prepare_enable(priv->plat->pclk);
>> -		if (priv->plat->clk_ptp_ref)
>> -			clk_prepare_enable(priv->plat->clk_ptp_ref);
>> +		stmmac_init_hwtstamp(priv);
> 
> This was optional, now you always init?

This was not intended. Will be fixed in v2 to be optional again.

Regards,
Holger
diff mbox series

Patch

diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
index 5b1c12ff98c0..55f5e6cd1cad 100644
--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
+++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
@@ -46,6 +46,13 @@ 
 #include "dwxgmac2.h"
 #include "hwif.h"
 
+
+/* As long the interface is active, we keep the timestamping HW enabled with
+ * fine resolution and binary rollover. This avoid non-monotonic behavior
+ * when changing timestamp settings at runtime
+ * */
+#define STMMAC_HWTS_ACTIVE (PTP_TCR_TSENA | PTP_TCR_TSCFUPDT | PTP_TCR_TSCTRLSSR)
+
 #define	STMMAC_ALIGN(x)		ALIGN(ALIGN(x, SMP_CACHE_BYTES), 16)
 #define	TSO_MAX_BUFF_SIZE	(SZ_16K - 1)
 
@@ -509,8 +516,6 @@  static int stmmac_hwtstamp_set(struct net_device *dev, struct ifreq *ifr)
 {
 	struct stmmac_priv *priv = netdev_priv(dev);
 	struct hwtstamp_config config;
-	struct timespec64 now;
-	u64 temp = 0;
 	u32 ptp_v2 = 0;
 	u32 tstamp_all = 0;
 	u32 ptp_over_ipv4_udp = 0;
@@ -519,7 +524,6 @@  static int stmmac_hwtstamp_set(struct net_device *dev, struct ifreq *ifr)
 	u32 snap_type_sel = 0;
 	u32 ts_master_en = 0;
 	u32 ts_event_en = 0;
-	u32 sec_inc = 0;
 	u32 value = 0;
 	bool xmac;
 
@@ -686,39 +690,16 @@  static int stmmac_hwtstamp_set(struct net_device *dev, struct ifreq *ifr)
 	priv->hwts_tx_en = config.tx_type == HWTSTAMP_TX_ON;
 
 	if (!priv->hwts_tx_en && !priv->hwts_rx_en)
-		stmmac_config_hw_tstamping(priv, priv->ptpaddr, 0);
+		stmmac_config_hw_tstamping(priv, priv->ptpaddr, STMMAC_HWTS_ACTIVE);
 	else {
-		value = (PTP_TCR_TSENA | PTP_TCR_TSCFUPDT | PTP_TCR_TSCTRLSSR |
+		value = (STMMAC_HWTS_ACTIVE |
 			 tstamp_all | ptp_v2 | ptp_over_ethernet |
 			 ptp_over_ipv6_udp | ptp_over_ipv4_udp | ts_event_en |
 			 ts_master_en | snap_type_sel);
 		stmmac_config_hw_tstamping(priv, priv->ptpaddr, value);
-
-		/* program Sub Second Increment reg */
-		stmmac_config_sub_second_increment(priv,
-				priv->ptpaddr, priv->plat->clk_ptp_rate,
-				xmac, &sec_inc);
-		temp = div_u64(1000000000ULL, sec_inc);
-
-		/* Store sub second increment and flags for later use */
-		priv->sub_second_inc = sec_inc;
+		
+		/* Store flags for later use */
 		priv->systime_flags = value;
-
-		/* calculate default added value:
-		 * formula is :
-		 * addend = (2^32)/freq_div_ratio;
-		 * where, freq_div_ratio = 1e9ns/sec_inc
-		 */
-		temp = (u64)(temp << 32);
-		priv->default_addend = div_u64(temp, priv->plat->clk_ptp_rate);
-		stmmac_config_addend(priv, priv->ptpaddr, priv->default_addend);
-
-		/* initialize system time */
-		ktime_get_real_ts64(&now);
-
-		/* lower 32 bits of tv_sec are safe until y2106 */
-		stmmac_init_systime(priv, priv->ptpaddr,
-				(u32)now.tv_sec, now.tv_nsec);
 	}
 
 	memcpy(&priv->tstamp_config, &config, sizeof(config));
@@ -791,6 +772,63 @@  static void stmmac_release_ptp(struct stmmac_priv *priv)
 	stmmac_ptp_unregister(priv);
 }
 
+/**
+ * stmmac_init_hwtstamp - init Timestamping Hardware
+ * @priv: driver private structure
+ * Description: Initialize hardware for Timestamping use
+ * This is valid as long as the interface is open and not suspended.
+ * Will be rerun after resume from suspension.
+ */
+static int stmmac_init_hwtstamp(struct stmmac_priv *priv)
+{
+	bool xmac = priv->plat->has_gmac4 || priv->plat->has_xgmac;
+	struct timespec64 now;
+	u32 sec_inc = 0;
+	u64 temp = 0;
+	u32 value;
+	int ret;
+
+	ret = clk_prepare_enable(priv->plat->clk_ptp_ref);
+	if (ret < 0) {
+		netdev_warn(priv->dev, "failed to enable PTP reference clock: %d\n", ret);
+		return ret;
+	}
+
+	if (!(priv->dma_cap.time_stamp || priv->dma_cap.atime_stamp))
+		return -EOPNOTSUPP;
+
+	value = STMMAC_HWTS_ACTIVE;
+	stmmac_config_hw_tstamping(priv, priv->ptpaddr, value);
+
+	/* program Sub Second Increment reg */
+	stmmac_config_sub_second_increment(priv,
+			priv->ptpaddr, priv->plat->clk_ptp_rate,
+			xmac, &sec_inc);
+	temp = div_u64(1000000000ULL, sec_inc);
+
+	/* Store sub second increment and flags for later use */
+	priv->sub_second_inc = sec_inc;
+	priv->systime_flags = value;
+
+	/* calculate default added value:
+	 * formula is :
+	 * addend = (2^32)/freq_div_ratio;
+	 * where, freq_div_ratio = 1e9ns/sec_inc
+	 */
+	temp = (u64)(temp << 32);
+	priv->default_addend = div_u64(temp, priv->plat->clk_ptp_rate);
+	stmmac_config_addend(priv, priv->ptpaddr, priv->default_addend);
+
+	/* initialize system time */
+	ktime_get_real_ts64(&now);
+
+	/* lower 32 bits of tv_sec are safe until y2106 */
+	stmmac_init_systime(priv, priv->ptpaddr,
+			(u32)now.tv_sec, now.tv_nsec);
+
+	return 0;
+}
+
 /**
  *  stmmac_mac_flow_ctrl - Configure flow control in all queues
  *  @priv: driver private structure
@@ -2713,15 +2751,17 @@  static int stmmac_hw_setup(struct net_device *dev, bool init_ptp)
 	stmmac_mmc_setup(priv);
 
 	if (init_ptp) {
-		ret = clk_prepare_enable(priv->plat->clk_ptp_ref);
-		if (ret < 0)
-			netdev_warn(priv->dev, "failed to enable PTP reference clock: %d\n", ret);
-
-		ret = stmmac_init_ptp(priv);
-		if (ret == -EOPNOTSUPP)
-			netdev_warn(priv->dev, "PTP not supported by HW\n");
-		else if (ret)
-			netdev_warn(priv->dev, "PTP init failed\n");
+		ret = stmmac_init_hwtstamp(priv);
+		if (ret) {
+			netdev_warn(priv->dev, "HW Timestamping init failed: %pe\n",
+					ERR_PTR(ret));
+		} else {
+			ret = stmmac_init_ptp(priv);
+			if (ret == -EOPNOTSUPP)
+				netdev_warn(priv->dev, "PTP not supported by HW\n");
+			else if (ret)
+				netdev_warn(priv->dev, "PTP init failed\n");
+		}
 	}
 
 	priv->eee_tw_timer = STMMAC_DEFAULT_TWT_LS;
@@ -5290,8 +5330,7 @@  int stmmac_resume(struct device *dev)
 		/* enable the clk previously disabled */
 		clk_prepare_enable(priv->plat->stmmac_clk);
 		clk_prepare_enable(priv->plat->pclk);
-		if (priv->plat->clk_ptp_ref)
-			clk_prepare_enable(priv->plat->clk_ptp_ref);
+		stmmac_init_hwtstamp(priv);
 		/* reset the phy so that it's ready */
 		if (priv->mii)
 			stmmac_mdio_reset(priv->mii);