diff mbox series

[2/2] net/hns3: support IEEE 1588 PTP

Message ID 1616748961-11239-3-git-send-email-humin29@huawei.com (mailing list archive)
State Superseded
Delegated to: Ferruh Yigit
Headers show
Series Support PTP for hns3 PMD | expand

Checks

Context Check Description
ci/iol-testing success Testing PASS
ci/iol-mellanox-Performance success Performance Testing PASS
ci/iol-abi-testing success Testing PASS
ci/iol-intel-Performance success Performance Testing PASS
ci/intel-Testing success Testing PASS
ci/Intel-compilation success Compilation OK
ci/checkpatch success coding style OK

Commit Message

Min Hu (Connor) March 26, 2021, 8:56 a.m. UTC
Add hns3 support for new ethdev APIs to enable and read IEEE1588/
802.1AS PTP timestamps.

Signed-off-by: Min Hu (Connor) <humin29@huawei.com>
---
 doc/guides/nics/features/hns3.ini |   2 +
 doc/guides/nics/hns3.rst          |   1 +
 drivers/net/hns3/hns3_cmd.h       |  33 +++++
 drivers/net/hns3/hns3_ethdev.c    |  59 +++++++-
 drivers/net/hns3/hns3_ethdev.h    |  25 ++++
 drivers/net/hns3/hns3_ptp.c       | 294 ++++++++++++++++++++++++++++++++++++++
 drivers/net/hns3/hns3_regs.h      |  25 ++++
 drivers/net/hns3/hns3_rxtx.c      |  56 +++++++-
 drivers/net/hns3/hns3_rxtx.h      |  12 ++
 drivers/net/hns3/hns3_rxtx_vec.c  |  19 ++-
 drivers/net/hns3/meson.build      |   3 +-
 11 files changed, 516 insertions(+), 13 deletions(-)
 create mode 100644 drivers/net/hns3/hns3_ptp.c

Comments

Ferruh Yigit March 30, 2021, 1:59 p.m. UTC | #1
On 3/26/2021 8:56 AM, Min Hu (Connor) wrote:
> Add hns3 support for new ethdev APIs to enable and read IEEE1588/
> 802.1AS PTP timestamps.
> 
> Signed-off-by: Min Hu (Connor) <humin29@huawei.com>
> ---
>   doc/guides/nics/features/hns3.ini |   2 +
>   doc/guides/nics/hns3.rst          |   1 +
>   drivers/net/hns3/hns3_cmd.h       |  33 +++++
>   drivers/net/hns3/hns3_ethdev.c    |  59 +++++++-
>   drivers/net/hns3/hns3_ethdev.h    |  25 ++++
>   drivers/net/hns3/hns3_ptp.c       | 294 ++++++++++++++++++++++++++++++++++++++
>   drivers/net/hns3/hns3_regs.h      |  25 ++++
>   drivers/net/hns3/hns3_rxtx.c      |  56 +++++++-
>   drivers/net/hns3/hns3_rxtx.h      |  12 ++
>   drivers/net/hns3/hns3_rxtx_vec.c  |  19 ++-
>   drivers/net/hns3/meson.build      |   3 +-
>   11 files changed, 516 insertions(+), 13 deletions(-)
>   create mode 100644 drivers/net/hns3/hns3_ptp.c
> 
> diff --git a/doc/guides/nics/features/hns3.ini b/doc/guides/nics/features/hns3.ini
> index 3988be4..502bfe7 100644
> --- a/doc/guides/nics/features/hns3.ini
> +++ b/doc/guides/nics/features/hns3.ini
> @@ -43,6 +43,8 @@ Stats per queue      = Y
>   FW version           = Y
>   Registers dump       = Y
>   Module EEPROM dump   = Y
> +Timesync             = Y
> +Timestamp offload    = Y
>   Multiprocess aware   = Y
>   Linux                = Y
>   ARMv8                = Y
> diff --git a/doc/guides/nics/hns3.rst b/doc/guides/nics/hns3.rst
> index ccd2f6f..3366562 100644
> --- a/doc/guides/nics/hns3.rst
> +++ b/doc/guides/nics/hns3.rst
> @@ -37,6 +37,7 @@ Features of the HNS3 PMD are:
>   - MTU update
>   - NUMA support
>   - Generic flow API
> +- IEEE1588/802.1AS timestamping
>   
>   Prerequisites
>   -------------
> diff --git a/drivers/net/hns3/hns3_cmd.h b/drivers/net/hns3/hns3_cmd.h
> index e704d0c..abc853b 100644
> --- a/drivers/net/hns3/hns3_cmd.h
> +++ b/drivers/net/hns3/hns3_cmd.h
> @@ -123,6 +123,12 @@ enum hns3_opcode_type {
>   	HNS3_OPC_CLEAR_MAC_TNL_INT      = 0x0312,
>   	HNS3_OPC_CONFIG_FEC_MODE        = 0x031A,
>   
> +#ifdef RTE_LIBRTE_IEEE1588
> +	/* PTP command */
> +	HNS3_OPC_PTP_INT_EN             = 0x0501,
> +	HNS3_OPC_CFG_PTP_MODE           = 0x0507,
> +#endif
> +

Hi Connor,

Does it needs to be a compile time configuration? What happens if it is always 
enabled, or controlled by device argument?
Ferruh Yigit March 30, 2021, 2:12 p.m. UTC | #2
On 3/26/2021 8:56 AM, Min Hu (Connor) wrote:
> Add hns3 support for new ethdev APIs to enable and read IEEE1588/
> 802.1AS PTP timestamps.
> 
> Signed-off-by: Min Hu (Connor) <humin29@huawei.com>
> ---
>   doc/guides/nics/features/hns3.ini |   2 +
>   doc/guides/nics/hns3.rst          |   1 +
>   drivers/net/hns3/hns3_cmd.h       |  33 +++++
>   drivers/net/hns3/hns3_ethdev.c    |  59 +++++++-
>   drivers/net/hns3/hns3_ethdev.h    |  25 ++++
>   drivers/net/hns3/hns3_ptp.c       | 294 ++++++++++++++++++++++++++++++++++++++
>   drivers/net/hns3/hns3_regs.h      |  25 ++++
>   drivers/net/hns3/hns3_rxtx.c      |  56 +++++++-
>   drivers/net/hns3/hns3_rxtx.h      |  12 ++
>   drivers/net/hns3/hns3_rxtx_vec.c  |  19 ++-
>   drivers/net/hns3/meson.build      |   3 +-

Can you please update release notes too?
Min Hu (Connor) March 31, 2021, 2:35 a.m. UTC | #3
在 2021/3/30 21:59, Ferruh Yigit 写道:
> On 3/26/2021 8:56 AM, Min Hu (Connor) wrote:
>> Add hns3 support for new ethdev APIs to enable and read IEEE1588/
>> 802.1AS PTP timestamps.
>>
>> Signed-off-by: Min Hu (Connor) <humin29@huawei.com>
>> ---
>>   doc/guides/nics/features/hns3.ini |   2 +
>>   doc/guides/nics/hns3.rst          |   1 +
>>   drivers/net/hns3/hns3_cmd.h       |  33 +++++
>>   drivers/net/hns3/hns3_ethdev.c    |  59 +++++++-
>>   drivers/net/hns3/hns3_ethdev.h    |  25 ++++
>>   drivers/net/hns3/hns3_ptp.c       | 294 
>> ++++++++++++++++++++++++++++++++++++++
>>   drivers/net/hns3/hns3_regs.h      |  25 ++++
>>   drivers/net/hns3/hns3_rxtx.c      |  56 +++++++-
>>   drivers/net/hns3/hns3_rxtx.h      |  12 ++
>>   drivers/net/hns3/hns3_rxtx_vec.c  |  19 ++-
>>   drivers/net/hns3/meson.build      |   3 +-
>>   11 files changed, 516 insertions(+), 13 deletions(-)
>>   create mode 100644 drivers/net/hns3/hns3_ptp.c
>>
>> diff --git a/doc/guides/nics/features/hns3.ini 
>> b/doc/guides/nics/features/hns3.ini
>> index 3988be4..502bfe7 100644
>> --- a/doc/guides/nics/features/hns3.ini
>> +++ b/doc/guides/nics/features/hns3.ini
>> @@ -43,6 +43,8 @@ Stats per queue      = Y
>>   FW version           = Y
>>   Registers dump       = Y
>>   Module EEPROM dump   = Y
>> +Timesync             = Y
>> +Timestamp offload    = Y
>>   Multiprocess aware   = Y
>>   Linux                = Y
>>   ARMv8                = Y
>> diff --git a/doc/guides/nics/hns3.rst b/doc/guides/nics/hns3.rst
>> index ccd2f6f..3366562 100644
>> --- a/doc/guides/nics/hns3.rst
>> +++ b/doc/guides/nics/hns3.rst
>> @@ -37,6 +37,7 @@ Features of the HNS3 PMD are:
>>   - MTU update
>>   - NUMA support
>>   - Generic flow API
>> +- IEEE1588/802.1AS timestamping
>>   Prerequisites
>>   -------------
>> diff --git a/drivers/net/hns3/hns3_cmd.h b/drivers/net/hns3/hns3_cmd.h
>> index e704d0c..abc853b 100644
>> --- a/drivers/net/hns3/hns3_cmd.h
>> +++ b/drivers/net/hns3/hns3_cmd.h
>> @@ -123,6 +123,12 @@ enum hns3_opcode_type {
>>       HNS3_OPC_CLEAR_MAC_TNL_INT      = 0x0312,
>>       HNS3_OPC_CONFIG_FEC_MODE        = 0x031A,
>> +#ifdef RTE_LIBRTE_IEEE1588
>> +    /* PTP command */
>> +    HNS3_OPC_PTP_INT_EN             = 0x0501,
>> +    HNS3_OPC_CFG_PTP_MODE           = 0x0507,
>> +#endif
>> +
> 
> Hi Connor,
> 
> Does it needs to be a compile time configuration? What happens if it is 
> always enabled, or controlled by device argument?
> .
Hi Ferruh,
	Firstly the "RTE_LIBRTE_IEEE1588" origins from the config file in DPDK. 
Almost every nic driver use this macro in compile time.
	For me, I think using this macro give one option for users to
decide if his APPs contains this module. For example, in loT field,
some microprocessor has small memory or small disk, So the APPs should 
be as small as possible. So, if user does not need "PTP", the APPs no
need to contain it.
	Well, another top, if is always enabled, for HNS3 PMD, it will
work well for our nic. If user want to use "PTP", just call API. If user
does not use it, it also doesn't matter. But we advise that if user
don't need this function, just turn it off.
	Thanks.
Min Hu (Connor) March 31, 2021, 2:38 a.m. UTC | #4
在 2021/3/30 22:12, Ferruh Yigit 写道:
> On 3/26/2021 8:56 AM, Min Hu (Connor) wrote:
>> Add hns3 support for new ethdev APIs to enable and read IEEE1588/
>> 802.1AS PTP timestamps.
>>
>> Signed-off-by: Min Hu (Connor) <humin29@huawei.com>
>> ---
>>   doc/guides/nics/features/hns3.ini |   2 +
>>   doc/guides/nics/hns3.rst          |   1 +
>>   drivers/net/hns3/hns3_cmd.h       |  33 +++++
>>   drivers/net/hns3/hns3_ethdev.c    |  59 +++++++-
>>   drivers/net/hns3/hns3_ethdev.h    |  25 ++++
>>   drivers/net/hns3/hns3_ptp.c       | 294 
>> ++++++++++++++++++++++++++++++++++++++
>>   drivers/net/hns3/hns3_regs.h      |  25 ++++
>>   drivers/net/hns3/hns3_rxtx.c      |  56 +++++++-
>>   drivers/net/hns3/hns3_rxtx.h      |  12 ++
>>   drivers/net/hns3/hns3_rxtx_vec.c  |  19 ++-
>>   drivers/net/hns3/meson.build      |   3 +-
> 
> Can you please update release notes too?
> 
Will update doc/guides/rel_notes/release_21_05.rst
in v2
Thanks
> .
Thomas Monjalon March 31, 2021, 7:28 a.m. UTC | #5
31/03/2021 04:35, Min Hu (Connor):
> 在 2021/3/30 21:59, Ferruh Yigit 写道:
> > On 3/26/2021 8:56 AM, Min Hu (Connor) wrote:
> >> Add hns3 support for new ethdev APIs to enable and read IEEE1588/
> >> 802.1AS PTP timestamps.
> >>
> >> Signed-off-by: Min Hu (Connor) <humin29@huawei.com>
> >> --- a/drivers/net/hns3/hns3_cmd.h
> >> +++ b/drivers/net/hns3/hns3_cmd.h
> >> @@ -123,6 +123,12 @@ enum hns3_opcode_type {
> >>       HNS3_OPC_CLEAR_MAC_TNL_INT      = 0x0312,
> >>       HNS3_OPC_CONFIG_FEC_MODE        = 0x031A,
> >> +#ifdef RTE_LIBRTE_IEEE1588
> >> +    /* PTP command */
> >> +    HNS3_OPC_PTP_INT_EN             = 0x0501,
> >> +    HNS3_OPC_CFG_PTP_MODE           = 0x0507,
> >> +#endif
> >> +
> > 
> > Hi Connor,
> > 
> > Does it needs to be a compile time configuration? What happens if it is 
> > always enabled, or controlled by device argument?
> > .
> Hi Ferruh,
> 	Firstly the "RTE_LIBRTE_IEEE1588" origins from the config file in DPDK. 
> Almost every nic driver use this macro in compile time.
> 	For me, I think using this macro give one option for users to
> decide if his APPs contains this module. For example, in loT field,
> some microprocessor has small memory or small disk, So the APPs should 
> be as small as possible. So, if user does not need "PTP", the APPs no
> need to contain it.
> 	Well, another top, if is always enabled, for HNS3 PMD, it will
> work well for our nic. If user want to use "PTP", just call API. If user
> does not use it, it also doesn't matter. But we advise that if user
> don't need this function, just turn it off.
> 	Thanks.

Disabling at compile-time does not reduce the footprint significantly.
RTE_LIBRTE_IEEE1588 should disappear, so I advise not using it
in new code. Instead, you could enable/disable at runtime if needed.
Ferruh Yigit March 31, 2021, 9:26 a.m. UTC | #6
On 3/31/2021 8:28 AM, Thomas Monjalon wrote:
> 31/03/2021 04:35, Min Hu (Connor):
>> 在 2021/3/30 21:59, Ferruh Yigit 写道:
>>> On 3/26/2021 8:56 AM, Min Hu (Connor) wrote:
>>>> Add hns3 support for new ethdev APIs to enable and read IEEE1588/
>>>> 802.1AS PTP timestamps.
>>>>
>>>> Signed-off-by: Min Hu (Connor) <humin29@huawei.com>
>>>> --- a/drivers/net/hns3/hns3_cmd.h
>>>> +++ b/drivers/net/hns3/hns3_cmd.h
>>>> @@ -123,6 +123,12 @@ enum hns3_opcode_type {
>>>>        HNS3_OPC_CLEAR_MAC_TNL_INT      = 0x0312,
>>>>        HNS3_OPC_CONFIG_FEC_MODE        = 0x031A,
>>>> +#ifdef RTE_LIBRTE_IEEE1588
>>>> +    /* PTP command */
>>>> +    HNS3_OPC_PTP_INT_EN             = 0x0501,
>>>> +    HNS3_OPC_CFG_PTP_MODE           = 0x0507,
>>>> +#endif
>>>> +
>>>
>>> Hi Connor,
>>>
>>> Does it needs to be a compile time configuration? What happens if it is
>>> always enabled, or controlled by device argument?
>>> .
>> Hi Ferruh,
>> 	Firstly the "RTE_LIBRTE_IEEE1588" origins from the config file in DPDK.
>> Almost every nic driver use this macro in compile time.
>> 	For me, I think using this macro give one option for users to
>> decide if his APPs contains this module. For example, in loT field,
>> some microprocessor has small memory or small disk, So the APPs should
>> be as small as possible. So, if user does not need "PTP", the APPs no
>> need to contain it.
>> 	Well, another top, if is always enabled, for HNS3 PMD, it will
>> work well for our nic. If user want to use "PTP", just call API. If user
>> does not use it, it also doesn't matter. But we advise that if user
>> don't need this function, just turn it off.
>> 	Thanks.
> 
> Disabling at compile-time does not reduce the footprint significantly.
> RTE_LIBRTE_IEEE1588 should disappear, so I advise not using it
> in new code. Instead, you could enable/disable at runtime if needed.
> 

I am aware that 'RTE_LIBRTE_IEEE1588' already exists and used by some drivers, 
but as you said they are from times we had a config option for it, for the new 
support I believe it is better to have runtime configuration.

And I agree with Thomas that it shouldn't increase the footprint much to always 
compile the support in, if you have numbers please share.
Min Hu (Connor) March 31, 2021, 11 a.m. UTC | #7
在 2021/3/31 17:26, Ferruh Yigit 写道:
> On 3/31/2021 8:28 AM, Thomas Monjalon wrote:
>> 31/03/2021 04:35, Min Hu (Connor):
>>> 在 2021/3/30 21:59, Ferruh Yigit 写道:
>>>> On 3/26/2021 8:56 AM, Min Hu (Connor) wrote:
>>>>> Add hns3 support for new ethdev APIs to enable and read IEEE1588/
>>>>> 802.1AS PTP timestamps.
>>>>>
>>>>> Signed-off-by: Min Hu (Connor) <humin29@huawei.com>
>>>>> --- a/drivers/net/hns3/hns3_cmd.h
>>>>> +++ b/drivers/net/hns3/hns3_cmd.h
>>>>> @@ -123,6 +123,12 @@ enum hns3_opcode_type {
>>>>>        HNS3_OPC_CLEAR_MAC_TNL_INT      = 0x0312,
>>>>>        HNS3_OPC_CONFIG_FEC_MODE        = 0x031A,
>>>>> +#ifdef RTE_LIBRTE_IEEE1588
>>>>> +    /* PTP command */
>>>>> +    HNS3_OPC_PTP_INT_EN             = 0x0501,
>>>>> +    HNS3_OPC_CFG_PTP_MODE           = 0x0507,
>>>>> +#endif
>>>>> +
>>>>
>>>> Hi Connor,
>>>>
>>>> Does it needs to be a compile time configuration? What happens if it is
>>>> always enabled, or controlled by device argument?
>>>> .
>>> Hi Ferruh,
>>>     Firstly the "RTE_LIBRTE_IEEE1588" origins from the config file in 
>>> DPDK.
>>> Almost every nic driver use this macro in compile time.
>>>     For me, I think using this macro give one option for users to
>>> decide if his APPs contains this module. For example, in loT field,
>>> some microprocessor has small memory or small disk, So the APPs should
>>> be as small as possible. So, if user does not need "PTP", the APPs no
>>> need to contain it.
>>>     Well, another top, if is always enabled, for HNS3 PMD, it will
>>> work well for our nic. If user want to use "PTP", just call API. If user
>>> does not use it, it also doesn't matter. But we advise that if user
>>> don't need this function, just turn it off.
>>>     Thanks.
>>
>> Disabling at compile-time does not reduce the footprint significantly.
>> RTE_LIBRTE_IEEE1588 should disappear, so I advise not using it
>> in new code. Instead, you could enable/disable at runtime if needed.
>>
> 
> I am aware that 'RTE_LIBRTE_IEEE1588' already exists and used by some 
> drivers, but as you said they are from times we had a config option for 
> it, for the new support I believe it is better to have runtime 
> configuration.
> 
> And I agree with Thomas that it shouldn't increase the footprint much to 
> always compile the support in, if you have numbers please share.
> 
Well, thanks Thomas, Ferruh,
If there is no help to reduce the footprint significantly, I agree to
delete "RTE_LIBRTE_IEEE1588". As for runtime config, there is no need to
enable or disable PTP. Because We support the function, if user want to 
use it, just call related APIs, if not, don't use it.

So, I will delete the "RTE_LIBRTE_IEEE1588" in v3, what's your opinion?
.
diff mbox series

Patch

diff --git a/doc/guides/nics/features/hns3.ini b/doc/guides/nics/features/hns3.ini
index 3988be4..502bfe7 100644
--- a/doc/guides/nics/features/hns3.ini
+++ b/doc/guides/nics/features/hns3.ini
@@ -43,6 +43,8 @@  Stats per queue      = Y
 FW version           = Y
 Registers dump       = Y
 Module EEPROM dump   = Y
+Timesync             = Y
+Timestamp offload    = Y
 Multiprocess aware   = Y
 Linux                = Y
 ARMv8                = Y
diff --git a/doc/guides/nics/hns3.rst b/doc/guides/nics/hns3.rst
index ccd2f6f..3366562 100644
--- a/doc/guides/nics/hns3.rst
+++ b/doc/guides/nics/hns3.rst
@@ -37,6 +37,7 @@  Features of the HNS3 PMD are:
 - MTU update
 - NUMA support
 - Generic flow API
+- IEEE1588/802.1AS timestamping
 
 Prerequisites
 -------------
diff --git a/drivers/net/hns3/hns3_cmd.h b/drivers/net/hns3/hns3_cmd.h
index e704d0c..abc853b 100644
--- a/drivers/net/hns3/hns3_cmd.h
+++ b/drivers/net/hns3/hns3_cmd.h
@@ -123,6 +123,12 @@  enum hns3_opcode_type {
 	HNS3_OPC_CLEAR_MAC_TNL_INT      = 0x0312,
 	HNS3_OPC_CONFIG_FEC_MODE        = 0x031A,
 
+#ifdef RTE_LIBRTE_IEEE1588
+	/* PTP command */
+	HNS3_OPC_PTP_INT_EN             = 0x0501,
+	HNS3_OPC_CFG_PTP_MODE           = 0x0507,
+#endif
+
 	/* PFC/Pause commands */
 	HNS3_OPC_CFG_MAC_PAUSE_EN       = 0x0701,
 	HNS3_OPC_CFG_PFC_PAUSE_EN       = 0x0702,
@@ -969,6 +975,33 @@  struct hns3_query_ssu_cmd {
 	uint32_t oq_drop_cnt;
 	uint32_t rev1[2];
 };
+#ifdef RTE_LIBRTE_IEEE1588
+#define HNS3_PTP_ENABLE_B               0
+#define HNS3_PTP_TX_ENABLE_B            1
+#define HNS3_PTP_RX_ENABLE_B            2
+
+#define HNS3_PTP_TYPE_S                 0
+#define HNS3_PTP_TYPE_M                (0x3 << HNS3_PTP_TYPE_S)
+
+#define ALL_PTP_V2_TYPE                 0xF
+#define HNS3_PTP_MESSAGE_TYPE_S         0
+#define HNS3_PTP_MESSAGE_TYPE_M        (0xF << HNS3_PTP_MESSAGE_TYPE_S)
+
+#define PTP_TYPE_L2_V2_TYPE             0
+
+struct hns3_ptp_mode_cfg_cmd {
+	uint8_t enable;
+	uint8_t ptp_type;
+	uint8_t v2_message_type_1;
+	uint8_t v2_message_type_0;
+	uint8_t rsv[20];
+};
+
+struct hns3_ptp_int_cmd {
+	uint8_t int_en;
+	uint8_t rsvd[23];
+};
+#endif
 
 #define HNS3_MAX_TQP_NUM_HIP08_PF	64
 #define HNS3_DEFAULT_TX_BUF		0x4000    /* 16k  bytes */
diff --git a/drivers/net/hns3/hns3_ethdev.c b/drivers/net/hns3/hns3_ethdev.c
index b985447..11b9065 100644
--- a/drivers/net/hns3/hns3_ethdev.c
+++ b/drivers/net/hns3/hns3_ethdev.c
@@ -58,6 +58,10 @@  enum hns3_evt_cause {
 	HNS3_VECTOR0_EVENT_RST,
 	HNS3_VECTOR0_EVENT_MBX,
 	HNS3_VECTOR0_EVENT_ERR,
+
+#ifdef RTE_LIBRTE_IEEE1588
+	HNS3_VECTOR0_EVENT_PTP,
+#endif
 	HNS3_VECTOR0_EVENT_OTHER,
 };
 
@@ -202,6 +206,14 @@  hns3_check_event_cause(struct hns3_adapter *hns, uint32_t *clearval)
 		goto out;
 	}
 
+#ifdef RTE_LIBRTE_IEEE1588
+	/* Check for vector0 1588 event source */
+	if (BIT(HNS3_VECTOR0_1588_INT_B) & vector0_int_stats) {
+		val = BIT(HNS3_VECTOR0_1588_INT_B);
+		ret = HNS3_VECTOR0_EVENT_PTP;
+		goto out;
+	}
+#endif
 	/* check for vector0 msix event source */
 	if (vector0_int_stats & HNS3_VECTOR0_REG_MSIX_MASK ||
 	    hw_err_src_reg & HNS3_RAS_REG_NFE_MASK) {
@@ -227,10 +239,22 @@  hns3_check_event_cause(struct hns3_adapter *hns, uint32_t *clearval)
 	return ret;
 }
 
+static bool
+hns3_is_1588_event_type(uint32_t event_type)
+{
+#ifdef RTE_LIBRTE_IEEE1588
+	return (event_type == HNS3_VECTOR0_EVENT_PTP);
+#else
+	RTE_SET_USED(event_type);
+	return false;
+#endif
+}
+
 static void
 hns3_clear_event_cause(struct hns3_hw *hw, uint32_t event_type, uint32_t regclr)
 {
-	if (event_type == HNS3_VECTOR0_EVENT_RST)
+	if (event_type == HNS3_VECTOR0_EVENT_RST ||
+	    hns3_is_1588_event_type(event_type))
 		hns3_write_dev(hw, HNS3_MISC_RESET_STS_REG, regclr);
 	else if (event_type == HNS3_VECTOR0_EVENT_MBX)
 		hns3_write_dev(hw, HNS3_VECTOR0_CMDQ_SRC_REG, regclr);
@@ -253,6 +277,11 @@  hns3_clear_all_event_cause(struct hns3_hw *hw)
 			       BIT(HNS3_VECTOR0_GLOBALRESET_INT_B) |
 			       BIT(HNS3_VECTOR0_CORERESET_INT_B));
 	hns3_clear_event_cause(hw, HNS3_VECTOR0_EVENT_MBX, 0);
+
+#ifdef RTE_LIBRTE_IEEE1588
+	hns3_clear_event_cause(hw, HNS3_VECTOR0_EVENT_PTP,
+				BIT(HNS3_VECTOR0_1588_INT_B));
+#endif
 }
 
 static void
@@ -2467,6 +2496,11 @@  hns3_dev_configure(struct rte_eth_dev *dev)
 	if (ret)
 		goto cfg_err;
 
+#ifdef RTE_LIBRTE_IEEE1588
+	ret = hns3_mbuf_dyn_rx_timestamp_register(dev, conf);
+	if (ret)
+		goto cfg_err;
+#endif
 	ret = hns3_dev_configure_vlan(dev);
 	if (ret)
 		goto cfg_err;
@@ -2640,6 +2674,9 @@  hns3_dev_infos_get(struct rte_eth_dev *eth_dev, struct rte_eth_dev_info *info)
 		info->dev_capa = RTE_ETH_DEV_CAPA_RUNTIME_RX_QUEUE_SETUP |
 				 RTE_ETH_DEV_CAPA_RUNTIME_TX_QUEUE_SETUP;
 
+	if (hns3_dev_ptp_supported(hw))
+		info->rx_offload_capa |= DEV_RX_OFFLOAD_TIMESTAMP;
+
 	info->rx_desc_lim = (struct rte_eth_desc_lim) {
 		.nb_max = HNS3_MAX_RING_DESC,
 		.nb_min = HNS3_MIN_RING_DESC,
@@ -4933,6 +4970,11 @@  hns3_init_pf(struct rte_eth_dev *eth_dev)
 		goto err_intr_callback_register;
 	}
 
+#ifdef RTE_LIBRTE_IEEE1588
+	ret = hns3_ptp_init(hw);
+	if (ret)
+		goto err_get_config;
+#endif
 	/* Enable interrupt */
 	rte_intr_enable(&pci_dev->intr_handle);
 	hns3_pf_enable_irq0(hw);
@@ -5950,6 +5992,12 @@  hns3_restore_conf(struct hns3_adapter *hns)
 	if (ret)
 		goto err_promisc;
 
+#ifdef RTE_LIBRTE_IEEE1588
+	ret = hns3_restore_ptp(hns);
+	if (ret)
+		goto err_promisc;
+#endif
+
 	ret = hns3_restore_rx_interrupt(hw);
 	if (ret)
 		goto err_promisc;
@@ -6654,6 +6702,15 @@  static const struct eth_dev_ops hns3_eth_dev_ops = {
 	.fec_set                = hns3_fec_set,
 	.tm_ops_get             = hns3_tm_ops_get,
 	.tx_done_cleanup        = hns3_tx_done_cleanup,
+#ifdef RTE_LIBRTE_IEEE1588
+	.timesync_enable            = hns3_timesync_enable,
+	.timesync_disable           = hns3_timesync_disable,
+	.timesync_read_rx_timestamp = hns3_timesync_read_rx_timestamp,
+	.timesync_read_tx_timestamp = hns3_timesync_read_tx_timestamp,
+	.timesync_adjust_time       = hns3_timesync_adjust_time,
+	.timesync_read_time         = hns3_timesync_read_time,
+	.timesync_write_time        = hns3_timesync_write_time,
+#endif
 };
 
 static const struct hns3_reset_ops hns3_reset_ops = {
diff --git a/drivers/net/hns3/hns3_ethdev.h b/drivers/net/hns3/hns3_ethdev.h
index f69e2d8..4ce192c 100644
--- a/drivers/net/hns3/hns3_ethdev.h
+++ b/drivers/net/hns3/hns3_ethdev.h
@@ -731,6 +731,13 @@  struct hns3_pf {
 	bool support_sfp_query;
 	uint32_t fec_mode; /* current FEC mode for ethdev */
 
+#ifdef RTE_LIBRTE_IEEE1588
+	bool ptp_enable;
+
+	/* Stores timestamp of last received packet on dev */
+	uint64_t rx_timestamp;
+#endif
+
 	struct hns3_vtag_cfg vtag_config;
 	LIST_HEAD(vlan_tbl, hns3_user_vlan_table) vlan_list;
 
@@ -982,6 +989,24 @@  void hns3vf_update_link_status(struct hns3_hw *hw, uint8_t link_status,
 			  uint32_t link_speed, uint8_t link_duplex);
 void hns3_parse_devargs(struct rte_eth_dev *dev);
 
+#ifdef RTE_LIBRTE_IEEE1588
+int hns3_restore_ptp(struct hns3_adapter *hns);
+int hns3_mbuf_dyn_rx_timestamp_register(struct rte_eth_dev *dev,
+				    struct rte_eth_conf *conf);
+int hns3_ptp_init(struct hns3_hw *hw);
+int hns3_timesync_enable(struct rte_eth_dev *dev);
+int hns3_timesync_disable(struct rte_eth_dev *dev);
+int hns3_timesync_read_rx_timestamp(struct rte_eth_dev *dev,
+				struct timespec *timestamp,
+				uint32_t flags __rte_unused);
+int hns3_timesync_read_tx_timestamp(struct rte_eth_dev *dev,
+				struct timespec *timestamp);
+int hns3_timesync_read_time(struct rte_eth_dev *dev, struct timespec *ts);
+int hns3_timesync_write_time(struct rte_eth_dev *dev,
+			const struct timespec *ts);
+int hns3_timesync_adjust_time(struct rte_eth_dev *dev, int64_t delta);
+#endif
+
 static inline bool
 is_reset_pending(struct hns3_adapter *hns)
 {
diff --git a/drivers/net/hns3/hns3_ptp.c b/drivers/net/hns3/hns3_ptp.c
new file mode 100644
index 0000000..d7e18c1
--- /dev/null
+++ b/drivers/net/hns3/hns3_ptp.c
@@ -0,0 +1,294 @@ 
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(c) 2021-2021 Hisilicon Limited.
+ */
+
+#include <ethdev_pci.h>
+#include <rte_io.h>
+#include <rte_time.h>
+
+#include "hns3_ethdev.h"
+#include "hns3_regs.h"
+#include "hns3_logs.h"
+
+#ifdef RTE_LIBRTE_IEEE1588
+uint64_t hns3_timestamp_rx_dynflag;
+int hns3_timestamp_dynfield_offset = -1;
+
+int
+hns3_mbuf_dyn_rx_timestamp_register(struct rte_eth_dev *dev,
+				    struct rte_eth_conf *conf)
+{
+	struct hns3_adapter *hns = dev->data->dev_private;
+	struct hns3_hw *hw = &hns->hw;
+	int ret;
+
+	if (!(conf->rxmode.offloads & DEV_RX_OFFLOAD_TIMESTAMP))
+		return 0;
+
+	ret = rte_mbuf_dyn_rx_timestamp_register
+			(&hns3_timestamp_dynfield_offset,
+			 &hns3_timestamp_rx_dynflag);
+	if (ret) {
+		hns3_err(hw,
+			"failed to register Rx timestamp field/flag");
+		return ret;
+	}
+
+	return 0;
+}
+
+static int
+hns3_ptp_int_en(struct hns3_hw *hw, bool en)
+{
+	struct hns3_ptp_int_cmd *req;
+	struct hns3_cmd_desc desc;
+	int ret;
+
+	req = (struct hns3_ptp_int_cmd *)desc.data;
+	hns3_cmd_setup_basic_desc(&desc, HNS3_OPC_PTP_INT_EN, false);
+	req->int_en = en ? 1 : 0;
+
+	ret = hns3_cmd_send(hw, &desc, 1);
+	if (ret)
+		hns3_err(hw,
+			"failed to %s ptp interrupt, ret = %d\n",
+			en ? "enable" : "disable", ret);
+
+	return ret;
+}
+
+int
+hns3_ptp_init(struct hns3_hw *hw)
+{
+	int ret;
+
+	if (!hns3_dev_ptp_supported(hw))
+		return 0;
+
+	ret = hns3_ptp_int_en(hw, true);
+	if (ret)
+		return ret;
+
+	/* Start PTP timer */
+	hns3_write_dev(hw, HNS3_CFG_TIME_CYC_EN, 1);
+
+	return 0;
+}
+
+static int
+hns3_timesync_configure(struct hns3_adapter *hns, bool en)
+{
+	struct hns3_ptp_mode_cfg_cmd *req;
+	struct hns3_hw *hw = &hns->hw;
+	struct hns3_pf *pf = &hns->pf;
+	struct hns3_cmd_desc desc;
+	int val;
+	int ret;
+
+	hns3_cmd_setup_basic_desc(&desc, HNS3_OPC_CFG_PTP_MODE, false);
+
+	req = (struct hns3_ptp_mode_cfg_cmd *)desc.data;
+
+	val = en ? 1 : 0;
+	hns3_set_bit(req->enable, HNS3_PTP_ENABLE_B, val);
+	hns3_set_bit(req->enable, HNS3_PTP_TX_ENABLE_B, val);
+	hns3_set_bit(req->enable, HNS3_PTP_RX_ENABLE_B, val);
+
+	if (en) {
+		hns3_set_field(req->ptp_type, HNS3_PTP_TYPE_M, HNS3_PTP_TYPE_S,
+			       PTP_TYPE_L2_V2_TYPE);
+		hns3_set_field(req->v2_message_type_1, HNS3_PTP_MESSAGE_TYPE_M,
+			       HNS3_PTP_MESSAGE_TYPE_S, ALL_PTP_V2_TYPE);
+	}
+
+	ret = hns3_cmd_send(hw, &desc, 1);
+	if (ret) {
+		hns3_err(hw, "configure PTP time failed, en = %d, ret = %d",
+			 en, ret);
+		return ret;
+	}
+
+	pf->ptp_enable = en;
+
+	return 0;
+}
+
+int
+hns3_timesync_enable(struct rte_eth_dev *dev)
+{
+	struct hns3_adapter *hns = dev->data->dev_private;
+	struct hns3_hw *hw = &hns->hw;
+	struct hns3_pf *pf = &hns->pf;
+	int ret;
+
+	if (!hns3_dev_ptp_supported(hw))
+		return -ENOTSUP;
+
+	if (pf->ptp_enable)
+		return 0;
+
+	rte_spinlock_lock(&hw->lock);
+	ret = hns3_timesync_configure(hns, true);
+	rte_spinlock_unlock(&hw->lock);
+	return ret;
+}
+
+int
+hns3_timesync_disable(struct rte_eth_dev *dev)
+{
+	struct hns3_adapter *hns = dev->data->dev_private;
+	struct hns3_hw *hw = &hns->hw;
+	struct hns3_pf *pf = &hns->pf;
+	int ret;
+
+	if (!hns3_dev_ptp_supported(hw))
+		return -ENOTSUP;
+
+	if (!pf->ptp_enable)
+		return 0;
+
+	rte_spinlock_lock(&hw->lock);
+	ret = hns3_timesync_configure(hns, false);
+	rte_spinlock_unlock(&hw->lock);
+
+	return ret;
+}
+
+int
+hns3_timesync_read_rx_timestamp(struct rte_eth_dev *dev,
+				struct timespec *timestamp,
+				uint32_t flags __rte_unused)
+{
+#define TIME_RX_STAMP_NS_MASK 0x3FFFFFFF
+	struct hns3_adapter *hns = dev->data->dev_private;
+	struct hns3_hw *hw = &hns->hw;
+	struct hns3_pf *pf = &hns->pf;
+	uint64_t ns, sec;
+
+	if (!hns3_dev_ptp_supported(hw))
+		return -ENOTSUP;
+
+	ns = pf->rx_timestamp & TIME_RX_STAMP_NS_MASK;
+	sec = upper_32_bits(pf->rx_timestamp);
+
+	ns += sec * NSEC_PER_SEC;
+	*timestamp = rte_ns_to_timespec(ns);
+
+	return 0;
+}
+
+int
+hns3_timesync_read_tx_timestamp(struct rte_eth_dev *dev,
+				struct timespec *timestamp)
+{
+#define TIME_TX_STAMP_NS_MASK 0x3FFFFFFF
+#define TIME_TX_STAMP_VALID   24
+#define TIME_TX_STAMP_CNT_MASK 0x7
+	struct hns3_adapter *hns = dev->data->dev_private;
+	struct hns3_hw *hw = &hns->hw;
+	uint64_t sec;
+	uint64_t tmp;
+	uint64_t ns;
+	int ts_cnt;
+
+	if (!hns3_dev_ptp_supported(hw))
+		return -ENOTSUP;
+
+	ts_cnt = hns3_read_dev(hw, HNS3_TX_1588_BACK_TSP_CNT) &
+			TIME_TX_STAMP_CNT_MASK;
+	if (ts_cnt == 0)
+		return -EINVAL;
+
+	ns = hns3_read_dev(hw, HNS3_TX_1588_TSP_BACK_0) & TIME_TX_STAMP_NS_MASK;
+	sec = hns3_read_dev(hw, HNS3_TX_1588_TSP_BACK_1);
+	tmp = hns3_read_dev(hw, HNS3_TX_1588_TSP_BACK_2) & 0xFFFF;
+	sec = (tmp << 32) | sec;
+
+	ns += sec * NSEC_PER_SEC;
+
+	*timestamp = rte_ns_to_timespec(ns);
+
+	/* Clear current timestamp hardware stores */
+	hns3_read_dev(hw, HNS3_TX_1588_SEQID_BACK);
+
+	return 0;
+}
+
+int
+hns3_timesync_read_time(struct rte_eth_dev *dev, struct timespec *ts)
+{
+	struct hns3_hw *hw = HNS3_DEV_PRIVATE_TO_HW(dev->data->dev_private);
+	uint64_t ns, sec;
+
+	if (!hns3_dev_ptp_supported(hw))
+		return -ENOTSUP;
+
+	sec = hns3_read_dev(hw, HNS3_CURR_TIME_OUT_L);
+	sec |= (uint64_t)(hns3_read_dev(hw, HNS3_CURR_TIME_OUT_H) & 0xFFFF)
+		<< 32;
+
+	ns = hns3_read_dev(hw, HNS3_CURR_TIME_OUT_NS);
+	ns += sec * NSEC_PER_SEC;
+	*ts = rte_ns_to_timespec(ns);
+
+	return 0;
+}
+
+int
+hns3_timesync_write_time(struct rte_eth_dev *dev, const struct timespec *ts)
+{
+	struct hns3_hw *hw = HNS3_DEV_PRIVATE_TO_HW(dev->data->dev_private);
+	uint64_t sec = ts->tv_sec;
+	uint64_t ns = ts->tv_nsec;
+
+	if (!hns3_dev_ptp_supported(hw))
+		return -ENOTSUP;
+
+	/* Set the timecounters to a new value. */
+	hns3_write_dev(hw, HNS3_CFG_TIME_SYNC_H, upper_32_bits(sec));
+	hns3_write_dev(hw, HNS3_CFG_TIME_SYNC_M, lower_32_bits(sec));
+	hns3_write_dev(hw, HNS3_CFG_TIME_SYNC_L, lower_32_bits(ns));
+	hns3_write_dev(hw, HNS3_CFG_TIME_SYNC_RDY, 1);
+
+	return 0;
+}
+
+int
+hns3_timesync_adjust_time(struct rte_eth_dev *dev, int64_t delta)
+{
+#define TIME_SYNC_L_MASK 0x7FFFFFFF
+#define SYMBOL_BIT_OFFSET 31
+	struct hns3_hw *hw = HNS3_DEV_PRIVATE_TO_HW(dev->data->dev_private);
+	struct timespec cur_time;
+	uint64_t ns;
+
+	if (!hns3_dev_ptp_supported(hw))
+		return -ENOTSUP;
+
+	(void)hns3_timesync_read_time(dev, &cur_time);
+	ns = rte_timespec_to_ns((const struct timespec *)&cur_time);
+	cur_time = rte_ns_to_timespec(ns + delta);
+	(void)hns3_timesync_write_time(dev, (const struct timespec *)&cur_time);
+
+	return 0;
+}
+
+int
+hns3_restore_ptp(struct hns3_adapter *hns)
+{
+	struct hns3_pf *pf = &hns->pf;
+	struct hns3_hw *hw = &hns->hw;
+	bool en = pf->ptp_enable;
+	int ret;
+
+	if (!hns3_dev_ptp_supported(hw))
+		return 0;
+
+	ret = hns3_timesync_configure(hns, en);
+	if (ret)
+		hns3_err(hw, "restore PTP enable state(%d) failed, ret = %d",
+			 en, ret);
+
+	return ret;
+}
+#endif
diff --git a/drivers/net/hns3/hns3_regs.h b/drivers/net/hns3/hns3_regs.h
index e141fe1..58a20ca 100644
--- a/drivers/net/hns3/hns3_regs.h
+++ b/drivers/net/hns3/hns3_regs.h
@@ -121,6 +121,31 @@ 
 #define HNS3_TQP_INTR_RL_DEFAULT		0
 #define HNS3_TQP_INTR_QL_DEFAULT		0
 
+#ifdef RTE_LIBRTE_IEEE1588
+/* Register bit for 1588 event */
+#define HNS3_VECTOR0_1588_INT_B	                0
+
+#define HNS3_PTP_BASE_ADDRESS			0x29000
+
+#define HNS3_TX_1588_SEQID_BACK			(HNS3_PTP_BASE_ADDRESS + 0x0)
+#define HNS3_TX_1588_TSP_BACK_0			(HNS3_PTP_BASE_ADDRESS + 0x4)
+#define HNS3_TX_1588_TSP_BACK_1			(HNS3_PTP_BASE_ADDRESS + 0x8)
+#define HNS3_TX_1588_TSP_BACK_2			(HNS3_PTP_BASE_ADDRESS + 0xc)
+
+#define HNS3_TX_1588_BACK_TSP_CNT		(HNS3_PTP_BASE_ADDRESS + 0x30)
+
+#define HNS3_CFG_TIME_SYNC_H			(HNS3_PTP_BASE_ADDRESS + 0x50)
+#define HNS3_CFG_TIME_SYNC_M			(HNS3_PTP_BASE_ADDRESS + 0x54)
+#define HNS3_CFG_TIME_SYNC_L			(HNS3_PTP_BASE_ADDRESS + 0x58)
+#define HNS3_CFG_TIME_SYNC_RDY			(HNS3_PTP_BASE_ADDRESS + 0x5c)
+
+#define HNS3_CFG_TIME_CYC_EN			(HNS3_PTP_BASE_ADDRESS + 0x70)
+
+#define HNS3_CURR_TIME_OUT_H			(HNS3_PTP_BASE_ADDRESS + 0x74)
+#define HNS3_CURR_TIME_OUT_L			(HNS3_PTP_BASE_ADDRESS + 0x78)
+#define HNS3_CURR_TIME_OUT_NS			(HNS3_PTP_BASE_ADDRESS + 0x7c)
+#endif
+
 /* gl_usec convert to hardware count, as writing each 1 represents 2us */
 #define HNS3_GL_USEC_TO_REG(gl_usec)		((gl_usec) >> 1)
 /* rl_usec convert to hardware count, as writing each 1 represents 4us */
diff --git a/drivers/net/hns3/hns3_rxtx.c b/drivers/net/hns3/hns3_rxtx.c
index feeb702..ceed302 100644
--- a/drivers/net/hns3/hns3_rxtx.c
+++ b/drivers/net/hns3/hns3_rxtx.c
@@ -2275,6 +2275,25 @@  hns3_rx_alloc_buffer(struct hns3_rx_queue *rxq)
 		return rte_mbuf_raw_alloc(rxq->mb_pool);
 }
 
+#ifdef RTE_LIBRTE_IEEE1588
+static inline void
+hns3_rx_ptp_timestamp_handle(struct hns3_rx_queue *rxq, struct rte_mbuf *mbuf,
+		  volatile struct hns3_desc *rxd)
+{
+	struct hns3_pf *pf = HNS3_DEV_PRIVATE_TO_PF(rxq->hns);
+	uint64_t timestamp = rte_le_to_cpu_64(rxd->timestamp);
+
+	mbuf->ol_flags |= PKT_RX_IEEE1588_PTP | PKT_RX_IEEE1588_TMST;
+	if (hns3_timestamp_rx_dynflag > 0) {
+		*RTE_MBUF_DYNFIELD(mbuf, hns3_timestamp_dynfield_offset,
+			rte_mbuf_timestamp_t *) = timestamp;
+		mbuf->ol_flags |= hns3_timestamp_rx_dynflag;
+	}
+
+	pf->rx_timestamp = timestamp;
+}
+#endif
+
 uint16_t
 hns3_recv_pkts(void *rx_queue, struct rte_mbuf **rx_pkts, uint16_t nb_pkts)
 {
@@ -2334,8 +2353,13 @@  hns3_recv_pkts(void *rx_queue, struct rte_mbuf **rx_pkts, uint16_t nb_pkts)
 		}
 
 		rxm = rxe->mbuf;
+		rxm->ol_flags = 0;
 		rxe->mbuf = nmb;
 
+#ifdef RTE_LIBRTE_IEEE1588
+		if (unlikely(bd_base_info & BIT(HNS3_RXD_TS_VLD_B)))
+			hns3_rx_ptp_timestamp_handle(rxq, rxm, rxdp);
+#endif
 		dma_addr = rte_mbuf_data_iova_default(nmb);
 		rxdp->addr = rte_cpu_to_le_64(dma_addr);
 		rxdp->rx.bd_base_info = 0;
@@ -2346,7 +2370,7 @@  hns3_recv_pkts(void *rx_queue, struct rte_mbuf **rx_pkts, uint16_t nb_pkts)
 		rxm->data_len = rxm->pkt_len;
 		rxm->port = rxq->port_id;
 		rxm->hash.rss = rte_le_to_cpu_32(rxd.rx.rss_hash);
-		rxm->ol_flags = PKT_RX_RSS_HASH;
+		rxm->ol_flags |= PKT_RX_RSS_HASH;
 		if (unlikely(bd_base_info & BIT(HNS3_RXD_LUM_B))) {
 			rxm->hash.fdir.hi =
 				rte_le_to_cpu_16(rxd.rx.fd_id);
@@ -2365,6 +2389,11 @@  hns3_recv_pkts(void *rx_queue, struct rte_mbuf **rx_pkts, uint16_t nb_pkts)
 
 		rxm->packet_type = hns3_rx_calc_ptype(rxq, l234_info, ol_info);
 
+#ifdef RTE_LIBRTE_IEEE1588
+		if (rxm->packet_type == RTE_PTYPE_L2_ETHER_TIMESYNC)
+			rxm->ol_flags |= PKT_RX_IEEE1588_PTP;
+#endif
+
 		if (likely(bd_base_info & BIT(HNS3_RXD_L3L4P_B)))
 			hns3_rx_set_cksum_flag(rxm, rxm->packet_type,
 					       cksum_err);
@@ -2952,7 +2981,7 @@  hns3_fill_per_desc(struct hns3_desc *desc, struct rte_mbuf *rxm)
 {
 	desc->addr = rte_mbuf_data_iova(rxm);
 	desc->tx.send_size = rte_cpu_to_le_16(rte_pktmbuf_data_len(rxm));
-	desc->tx.tp_fe_sc_vld_ra_ri = rte_cpu_to_le_16(BIT(HNS3_TXD_VLD_B));
+	desc->tx.tp_fe_sc_vld_ra_ri |= rte_cpu_to_le_16(BIT(HNS3_TXD_VLD_B));
 }
 
 static void
@@ -3000,6 +3029,12 @@  hns3_fill_first_desc(struct hns3_tx_queue *txq, struct hns3_desc *desc,
 					rte_cpu_to_le_32(BIT(HNS3_TXD_VLAN_B));
 		desc->tx.vlan_tag = rte_cpu_to_le_16(rxm->vlan_tci);
 	}
+
+#ifdef RTE_LIBRTE_IEEE1588
+	if (ol_flags & PKT_TX_IEEE1588_TMST)
+		desc->tx.tp_fe_sc_vld_ra_ri |=
+				rte_cpu_to_le_16(BIT(HNS3_TXD_TSYN_B));
+#endif
 }
 
 static inline int
@@ -3991,10 +4026,23 @@  hns3_tx_burst_mode_get(struct rte_eth_dev *dev, __rte_unused uint16_t queue_id,
 	return 0;
 }
 
+static bool
+hns3_tx_check_simple_support(struct rte_eth_dev *dev)
+{
+	uint64_t offloads = dev->data->dev_conf.txmode.offloads;
+
+#ifdef RTE_LIBRTE_IEEE1588
+	struct hns3_hw *hw = HNS3_DEV_PRIVATE_TO_HW(dev->data->dev_private);
+	if (hns3_dev_ptp_supported(hw))
+		return false;
+#endif
+
+	return (offloads == (offloads & DEV_TX_OFFLOAD_MBUF_FAST_FREE));
+}
+
 static eth_tx_burst_t
 hns3_get_tx_function(struct rte_eth_dev *dev, eth_tx_prep_t *prep)
 {
-	uint64_t offloads = dev->data->dev_conf.txmode.offloads;
 	struct hns3_adapter *hns = dev->data->dev_private;
 	bool vec_allowed, sve_allowed, simple_allowed;
 
@@ -4002,7 +4050,7 @@  hns3_get_tx_function(struct rte_eth_dev *dev, eth_tx_prep_t *prep)
 		      hns3_tx_check_vec_support(dev) == 0;
 	sve_allowed = vec_allowed && hns3_check_sve_support();
 	simple_allowed = hns->tx_simple_allowed &&
-			 offloads == (offloads & DEV_TX_OFFLOAD_MBUF_FAST_FREE);
+			 hns3_tx_check_simple_support(dev);
 
 	*prep = NULL;
 
diff --git a/drivers/net/hns3/hns3_rxtx.h b/drivers/net/hns3/hns3_rxtx.h
index f9b3048..74e5407 100644
--- a/drivers/net/hns3/hns3_rxtx.h
+++ b/drivers/net/hns3/hns3_rxtx.h
@@ -106,6 +106,8 @@ 
 #define HNS3_RXD_L3L4P_B			11
 #define HNS3_RXD_TSIND_S			12
 #define HNS3_RXD_TSIND_M			(0x7 << HNS3_RXD_TSIND_S)
+
+#define HNS3_RXD_TS_VLD_B			14
 #define HNS3_RXD_LKBK_B				15
 #define HNS3_RXD_GRO_SIZE_S			16
 #define HNS3_RXD_GRO_SIZE_M			(0x3fff << HNS3_RXD_GRO_SIZE_S)
@@ -200,6 +202,11 @@  enum hns3_pkt_tun_type {
 struct hns3_desc {
 	union {
 		uint64_t addr;
+
+#ifdef RTE_LIBRTE_IEEE1588
+		uint64_t timestamp;
+#endif
+
 		struct {
 			uint32_t addr0;
 			uint32_t addr1;
@@ -518,6 +525,11 @@  enum hns3_cksum_status {
 	HNS3_OUTER_L4_CKSUM_ERR = 8
 };
 
+#ifdef RTE_LIBRTE_IEEE1588
+extern uint64_t hns3_timestamp_rx_dynflag;
+extern int hns3_timestamp_dynfield_offset;
+#endif
+
 static inline int
 hns3_handle_bdinfo(struct hns3_rx_queue *rxq, struct rte_mbuf *rxm,
 		   uint32_t bd_base_info, uint32_t l234_info,
diff --git a/drivers/net/hns3/hns3_rxtx_vec.c b/drivers/net/hns3/hns3_rxtx_vec.c
index 2bc4372..4584d8a 100644
--- a/drivers/net/hns3/hns3_rxtx_vec.c
+++ b/drivers/net/hns3/hns3_rxtx_vec.c
@@ -18,6 +18,12 @@  hns3_tx_check_vec_support(struct rte_eth_dev *dev)
 {
 	struct rte_eth_txmode *txmode = &dev->data->dev_conf.txmode;
 
+#ifdef RTE_LIBRTE_IEEE1588
+	struct hns3_hw *hw = HNS3_DEV_PRIVATE_TO_HW(dev->data->dev_private);
+	if (hns3_dev_ptp_supported(hw))
+		return -ENOTSUP;
+#endif
+
 	/* Only support DEV_TX_OFFLOAD_MBUF_FAST_FREE */
 	if (txmode->offloads != DEV_TX_OFFLOAD_MBUF_FAST_FREE)
 		return -ENOTSUP;
@@ -167,7 +173,6 @@  hns3_rxq_vec_setup(struct hns3_rx_queue *rxq)
 	memset(rxq->offset_table, 0, sizeof(rxq->offset_table));
 }
 
-#ifndef RTE_LIBRTE_IEEE1588
 static int
 hns3_rxq_vec_check(struct hns3_rx_queue *rxq, void *arg)
 {
@@ -183,17 +188,21 @@  hns3_rxq_vec_check(struct hns3_rx_queue *rxq, void *arg)
 	RTE_SET_USED(arg);
 	return 0;
 }
-#endif
 
 int
 hns3_rx_check_vec_support(struct rte_eth_dev *dev)
 {
-#ifndef RTE_LIBRTE_IEEE1588
 	struct rte_fdir_conf *fconf = &dev->data->dev_conf.fdir_conf;
 	struct rte_eth_rxmode *rxmode = &dev->data->dev_conf.rxmode;
 	uint64_t offloads_mask = DEV_RX_OFFLOAD_TCP_LRO |
 				 DEV_RX_OFFLOAD_VLAN;
 
+#ifdef RTE_LIBRTE_IEEE1588
+	struct hns3_hw *hw = HNS3_DEV_PRIVATE_TO_HW(dev->data->dev_private);
+	if (hns3_dev_ptp_supported(hw))
+		return -ENOTSUP;
+#endif
+
 	if (dev->data->scattered_rx)
 		return -ENOTSUP;
 
@@ -207,8 +216,4 @@  hns3_rx_check_vec_support(struct rte_eth_dev *dev)
 		return -ENOTSUP;
 
 	return 0;
-#else
-	RTE_SET_USED(dev);
-	return -ENOTSUP;
-#endif
 }
diff --git a/drivers/net/hns3/meson.build b/drivers/net/hns3/meson.build
index f6aac69..6d78c33 100644
--- a/drivers/net/hns3/meson.build
+++ b/drivers/net/hns3/meson.build
@@ -26,7 +26,8 @@  sources = files('hns3_cmd.c',
 	'hns3_rxtx.c',
 	'hns3_stats.c',
 	'hns3_mp.c',
-	'hns3_tm.c')
+	'hns3_tm.c',
+	'hns3_ptp.c')
 
 deps += ['hash']