DPDK patches and discussions
 help / color / mirror / Atom feed
* [dpdk-dev] [PATCH 0/2] Support PTP for hns3 PMD
@ 2021-03-26  8:55 Min Hu (Connor)
  2021-03-26  8:56 ` [dpdk-dev] [PATCH 1/2] net/hns3: fix code check warning Min Hu (Connor)
                   ` (3 more replies)
  0 siblings, 4 replies; 17+ messages in thread
From: Min Hu (Connor) @ 2021-03-26  8:55 UTC (permalink / raw)
  To: dev, ferruh.yigit

This set includes two patches, one patch is to fix
cyclomatic complexity, the other patch is to support
PTP, but depends on the first patch. So the two forms
one set of patches.

Min Hu (Connor) (2):
  net/hns3: fix code check warning
  net/hns3: support IEEE 1588 PTP

 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    | 120 ++++++++++++----
 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, 553 insertions(+), 37 deletions(-)
 create mode 100644 drivers/net/hns3/hns3_ptp.c

-- 
2.7.4


^ permalink raw reply	[flat|nested] 17+ messages in thread

* [dpdk-dev] [PATCH 1/2] net/hns3: fix code check warning
  2021-03-26  8:55 [dpdk-dev] [PATCH 0/2] Support PTP for hns3 PMD Min Hu (Connor)
@ 2021-03-26  8:56 ` Min Hu (Connor)
  2021-03-26  8:56 ` [dpdk-dev] [PATCH 2/2] net/hns3: support IEEE 1588 PTP Min Hu (Connor)
                   ` (2 subsequent siblings)
  3 siblings, 0 replies; 17+ messages in thread
From: Min Hu (Connor) @ 2021-03-26  8:56 UTC (permalink / raw)
  To: dev, ferruh.yigit

This patch fixed cyclomatic complexity about MTU
in device configure process.

Fixes: 1f5ca0b460cd ("net/hns3: support some device operations")
Cc: stable@dpdk.org

Signed-off-by: Min Hu (Connor) <humin29@huawei.com>
---
 drivers/net/hns3/hns3_ethdev.c | 61 +++++++++++++++++++++++++-----------------
 1 file changed, 37 insertions(+), 24 deletions(-)

diff --git a/drivers/net/hns3/hns3_ethdev.c b/drivers/net/hns3/hns3_ethdev.c
index b7bfac8..b985447 100644
--- a/drivers/net/hns3/hns3_ethdev.c
+++ b/drivers/net/hns3/hns3_ethdev.c
@@ -2373,6 +2373,40 @@ hns3_init_ring_with_vector(struct hns3_hw *hw)
 }
 
 static int
+hns3_refresh_mtu(struct rte_eth_dev *dev, struct rte_eth_conf *conf)
+{
+	struct hns3_adapter *hns = dev->data->dev_private;
+	struct hns3_hw *hw = &hns->hw;
+	uint32_t max_rx_pkt_len;
+	uint16_t mtu;
+	int ret;
+
+	if (!(conf->rxmode.offloads & DEV_RX_OFFLOAD_JUMBO_FRAME))
+		return 0;
+
+	/*
+	 * If jumbo frames are enabled, MTU needs to be refreshed
+	 * according to the maximum RX packet length.
+	 */
+	max_rx_pkt_len = conf->rxmode.max_rx_pkt_len;
+	if (max_rx_pkt_len > HNS3_MAX_FRAME_LEN ||
+	    max_rx_pkt_len <= HNS3_DEFAULT_FRAME_LEN) {
+		hns3_err(hw, "maximum Rx packet length must be greater than %u "
+			 "and no more than %u when jumbo frame enabled.",
+			 (uint16_t)HNS3_DEFAULT_FRAME_LEN,
+			 (uint16_t)HNS3_MAX_FRAME_LEN);
+		return -EINVAL;
+	}
+
+	mtu = (uint16_t)HNS3_PKTLEN_TO_MTU(max_rx_pkt_len);
+	ret = hns3_dev_mtu_set(dev, mtu);
+	if (ret)
+		return ret;
+	dev->data->mtu = mtu;
+
+	return 0;
+}
+static int
 hns3_dev_configure(struct rte_eth_dev *dev)
 {
 	struct hns3_adapter *hns = dev->data->dev_private;
@@ -2382,8 +2416,6 @@ hns3_dev_configure(struct rte_eth_dev *dev)
 	uint16_t nb_rx_q = dev->data->nb_rx_queues;
 	uint16_t nb_tx_q = dev->data->nb_tx_queues;
 	struct rte_eth_rss_conf rss_conf;
-	uint32_t max_rx_pkt_len;
-	uint16_t mtu;
 	bool gro_en;
 	int ret;
 
@@ -2431,28 +2463,9 @@ hns3_dev_configure(struct rte_eth_dev *dev)
 			goto cfg_err;
 	}
 
-	/*
-	 * If jumbo frames are enabled, MTU needs to be refreshed
-	 * according to the maximum RX packet length.
-	 */
-	if (conf->rxmode.offloads & DEV_RX_OFFLOAD_JUMBO_FRAME) {
-		max_rx_pkt_len = conf->rxmode.max_rx_pkt_len;
-		if (max_rx_pkt_len > HNS3_MAX_FRAME_LEN ||
-		    max_rx_pkt_len <= HNS3_DEFAULT_FRAME_LEN) {
-			hns3_err(hw, "maximum Rx packet length must be greater "
-				 "than %u and less than %u when jumbo frame enabled.",
-				 (uint16_t)HNS3_DEFAULT_FRAME_LEN,
-				 (uint16_t)HNS3_MAX_FRAME_LEN);
-			ret = -EINVAL;
-			goto cfg_err;
-		}
-
-		mtu = (uint16_t)HNS3_PKTLEN_TO_MTU(max_rx_pkt_len);
-		ret = hns3_dev_mtu_set(dev, mtu);
-		if (ret)
-			goto cfg_err;
-		dev->data->mtu = mtu;
-	}
+	ret = hns3_refresh_mtu(dev, conf);
+	if (ret)
+		goto cfg_err;
 
 	ret = hns3_dev_configure_vlan(dev);
 	if (ret)
-- 
2.7.4


^ permalink raw reply	[flat|nested] 17+ messages in thread

* [dpdk-dev] [PATCH 2/2] net/hns3: support IEEE 1588 PTP
  2021-03-26  8:55 [dpdk-dev] [PATCH 0/2] Support PTP for hns3 PMD Min Hu (Connor)
  2021-03-26  8:56 ` [dpdk-dev] [PATCH 1/2] net/hns3: fix code check warning Min Hu (Connor)
@ 2021-03-26  8:56 ` Min Hu (Connor)
  2021-03-30 13:59   ` Ferruh Yigit
  2021-03-30 14:12   ` Ferruh Yigit
  2021-03-31  7:01 ` [dpdk-dev] [PATCH v2 0/2] Support PTP for hns3 PMD Min Hu (Connor)
  2021-04-01 13:38 ` [dpdk-dev] [PATCH v3 0/2] Support PTP for hns3 PMD Min Hu (Connor)
  3 siblings, 2 replies; 17+ messages in thread
From: Min Hu (Connor) @ 2021-03-26  8:56 UTC (permalink / raw)
  To: dev, ferruh.yigit

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
+
 	/* 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']
 
-- 
2.7.4


^ permalink raw reply	[flat|nested] 17+ messages in thread

* Re: [dpdk-dev] [PATCH 2/2] net/hns3: support IEEE 1588 PTP
  2021-03-26  8:56 ` [dpdk-dev] [PATCH 2/2] net/hns3: support IEEE 1588 PTP Min Hu (Connor)
@ 2021-03-30 13:59   ` Ferruh Yigit
  2021-03-31  2:35     ` Min Hu (Connor)
  2021-03-30 14:12   ` Ferruh Yigit
  1 sibling, 1 reply; 17+ messages in thread
From: Ferruh Yigit @ 2021-03-30 13:59 UTC (permalink / raw)
  To: Min Hu (Connor), dev; +Cc: Andrew Rybchenko, Thomas Monjalon

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?

^ permalink raw reply	[flat|nested] 17+ messages in thread

* Re: [dpdk-dev] [PATCH 2/2] net/hns3: support IEEE 1588 PTP
  2021-03-26  8:56 ` [dpdk-dev] [PATCH 2/2] net/hns3: support IEEE 1588 PTP Min Hu (Connor)
  2021-03-30 13:59   ` Ferruh Yigit
@ 2021-03-30 14:12   ` Ferruh Yigit
  2021-03-31  2:38     ` Min Hu (Connor)
  1 sibling, 1 reply; 17+ messages in thread
From: Ferruh Yigit @ 2021-03-30 14:12 UTC (permalink / raw)
  To: Min Hu (Connor), dev

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?


^ permalink raw reply	[flat|nested] 17+ messages in thread

* Re: [dpdk-dev] [PATCH 2/2] net/hns3: support IEEE 1588 PTP
  2021-03-30 13:59   ` Ferruh Yigit
@ 2021-03-31  2:35     ` Min Hu (Connor)
  2021-03-31  7:28       ` Thomas Monjalon
  0 siblings, 1 reply; 17+ messages in thread
From: Min Hu (Connor) @ 2021-03-31  2:35 UTC (permalink / raw)
  To: Ferruh Yigit, dev; +Cc: Andrew Rybchenko, Thomas Monjalon



在 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.





^ permalink raw reply	[flat|nested] 17+ messages in thread

* Re: [dpdk-dev] [PATCH 2/2] net/hns3: support IEEE 1588 PTP
  2021-03-30 14:12   ` Ferruh Yigit
@ 2021-03-31  2:38     ` Min Hu (Connor)
  0 siblings, 0 replies; 17+ messages in thread
From: Min Hu (Connor) @ 2021-03-31  2:38 UTC (permalink / raw)
  To: Ferruh Yigit, dev



在 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
> .

^ permalink raw reply	[flat|nested] 17+ messages in thread

* [dpdk-dev] [PATCH v2 0/2] Support PTP for hns3 PMD
  2021-03-26  8:55 [dpdk-dev] [PATCH 0/2] Support PTP for hns3 PMD Min Hu (Connor)
  2021-03-26  8:56 ` [dpdk-dev] [PATCH 1/2] net/hns3: fix code check warning Min Hu (Connor)
  2021-03-26  8:56 ` [dpdk-dev] [PATCH 2/2] net/hns3: support IEEE 1588 PTP Min Hu (Connor)
@ 2021-03-31  7:01 ` Min Hu (Connor)
  2021-03-31  7:01   ` [dpdk-dev] [PATCH v2 1/2] net/hns3: fix code check warning Min Hu (Connor)
  2021-03-31  7:01   ` [dpdk-dev] [PATCH v2 2/2] net/hns3: support IEEE 1588 PTP Min Hu (Connor)
  2021-04-01 13:38 ` [dpdk-dev] [PATCH v3 0/2] Support PTP for hns3 PMD Min Hu (Connor)
  3 siblings, 2 replies; 17+ messages in thread
From: Min Hu (Connor) @ 2021-03-31  7:01 UTC (permalink / raw)
  To: dev; +Cc: ferruh.yigit

This set includes two patches, one patch is to fix
cyclomatic complexity, the other patch is to support
PTP, but depends on the first patch. So the two forms
one set of patches.

Min Hu (Connor) (2):
  net/hns3: fix code check warning
  net/hns3: support IEEE 1588 PTP

 doc/guides/nics/features/hns3.ini      |   2 +
 doc/guides/nics/hns3.rst               |   1 +
 doc/guides/rel_notes/release_21_05.rst |   1 +
 drivers/net/hns3/hns3_cmd.h            |  33 ++++
 drivers/net/hns3/hns3_ethdev.c         | 120 +++++++++++---
 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 +-
 12 files changed, 554 insertions(+), 37 deletions(-)
 create mode 100644 drivers/net/hns3/hns3_ptp.c

-- 
2.7.4


^ permalink raw reply	[flat|nested] 17+ messages in thread

* [dpdk-dev] [PATCH v2 1/2] net/hns3: fix code check warning
  2021-03-31  7:01 ` [dpdk-dev] [PATCH v2 0/2] Support PTP for hns3 PMD Min Hu (Connor)
@ 2021-03-31  7:01   ` Min Hu (Connor)
  2021-03-31  7:01   ` [dpdk-dev] [PATCH v2 2/2] net/hns3: support IEEE 1588 PTP Min Hu (Connor)
  1 sibling, 0 replies; 17+ messages in thread
From: Min Hu (Connor) @ 2021-03-31  7:01 UTC (permalink / raw)
  To: dev; +Cc: ferruh.yigit

This patch fixed cyclomatic complexity about MTU
in device configure process.

Fixes: 1f5ca0b460cd ("net/hns3: support some device operations")
Cc: stable@dpdk.org

Signed-off-by: Min Hu (Connor) <humin29@huawei.com>
---
 drivers/net/hns3/hns3_ethdev.c | 61 +++++++++++++++++++++++++-----------------
 1 file changed, 37 insertions(+), 24 deletions(-)

diff --git a/drivers/net/hns3/hns3_ethdev.c b/drivers/net/hns3/hns3_ethdev.c
index 4883cb7..5cc997d 100644
--- a/drivers/net/hns3/hns3_ethdev.c
+++ b/drivers/net/hns3/hns3_ethdev.c
@@ -2373,6 +2373,40 @@ hns3_init_ring_with_vector(struct hns3_hw *hw)
 }
 
 static int
+hns3_refresh_mtu(struct rte_eth_dev *dev, struct rte_eth_conf *conf)
+{
+	struct hns3_adapter *hns = dev->data->dev_private;
+	struct hns3_hw *hw = &hns->hw;
+	uint32_t max_rx_pkt_len;
+	uint16_t mtu;
+	int ret;
+
+	if (!(conf->rxmode.offloads & DEV_RX_OFFLOAD_JUMBO_FRAME))
+		return 0;
+
+	/*
+	 * If jumbo frames are enabled, MTU needs to be refreshed
+	 * according to the maximum RX packet length.
+	 */
+	max_rx_pkt_len = conf->rxmode.max_rx_pkt_len;
+	if (max_rx_pkt_len > HNS3_MAX_FRAME_LEN ||
+	    max_rx_pkt_len <= HNS3_DEFAULT_FRAME_LEN) {
+		hns3_err(hw, "maximum Rx packet length must be greater than %u "
+			 "and no more than %u when jumbo frame enabled.",
+			 (uint16_t)HNS3_DEFAULT_FRAME_LEN,
+			 (uint16_t)HNS3_MAX_FRAME_LEN);
+		return -EINVAL;
+	}
+
+	mtu = (uint16_t)HNS3_PKTLEN_TO_MTU(max_rx_pkt_len);
+	ret = hns3_dev_mtu_set(dev, mtu);
+	if (ret)
+		return ret;
+	dev->data->mtu = mtu;
+
+	return 0;
+}
+static int
 hns3_dev_configure(struct rte_eth_dev *dev)
 {
 	struct hns3_adapter *hns = dev->data->dev_private;
@@ -2382,8 +2416,6 @@ hns3_dev_configure(struct rte_eth_dev *dev)
 	uint16_t nb_rx_q = dev->data->nb_rx_queues;
 	uint16_t nb_tx_q = dev->data->nb_tx_queues;
 	struct rte_eth_rss_conf rss_conf;
-	uint32_t max_rx_pkt_len;
-	uint16_t mtu;
 	bool gro_en;
 	int ret;
 
@@ -2431,28 +2463,9 @@ hns3_dev_configure(struct rte_eth_dev *dev)
 			goto cfg_err;
 	}
 
-	/*
-	 * If jumbo frames are enabled, MTU needs to be refreshed
-	 * according to the maximum RX packet length.
-	 */
-	if (conf->rxmode.offloads & DEV_RX_OFFLOAD_JUMBO_FRAME) {
-		max_rx_pkt_len = conf->rxmode.max_rx_pkt_len;
-		if (max_rx_pkt_len > HNS3_MAX_FRAME_LEN ||
-		    max_rx_pkt_len <= HNS3_DEFAULT_FRAME_LEN) {
-			hns3_err(hw, "maximum Rx packet length must be greater "
-				 "than %u and less than %u when jumbo frame enabled.",
-				 (uint16_t)HNS3_DEFAULT_FRAME_LEN,
-				 (uint16_t)HNS3_MAX_FRAME_LEN);
-			ret = -EINVAL;
-			goto cfg_err;
-		}
-
-		mtu = (uint16_t)HNS3_PKTLEN_TO_MTU(max_rx_pkt_len);
-		ret = hns3_dev_mtu_set(dev, mtu);
-		if (ret)
-			goto cfg_err;
-		dev->data->mtu = mtu;
-	}
+	ret = hns3_refresh_mtu(dev, conf);
+	if (ret)
+		goto cfg_err;
 
 	ret = hns3_dev_configure_vlan(dev);
 	if (ret)
-- 
2.7.4


^ permalink raw reply	[flat|nested] 17+ messages in thread

* [dpdk-dev] [PATCH v2 2/2] net/hns3: support IEEE 1588 PTP
  2021-03-31  7:01 ` [dpdk-dev] [PATCH v2 0/2] Support PTP for hns3 PMD Min Hu (Connor)
  2021-03-31  7:01   ` [dpdk-dev] [PATCH v2 1/2] net/hns3: fix code check warning Min Hu (Connor)
@ 2021-03-31  7:01   ` Min Hu (Connor)
  1 sibling, 0 replies; 17+ messages in thread
From: Min Hu (Connor) @ 2021-03-31  7:01 UTC (permalink / raw)
  To: dev; +Cc: ferruh.yigit

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 +
 doc/guides/rel_notes/release_21_05.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 +-
 12 files changed, 517 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/doc/guides/rel_notes/release_21_05.rst b/doc/guides/rel_notes/release_21_05.rst
index a899818..202ca92 100644
--- a/doc/guides/rel_notes/release_21_05.rst
+++ b/doc/guides/rel_notes/release_21_05.rst
@@ -90,6 +90,7 @@ New Features
   * Added support for outer UDP checksum in Kunpeng930.
   * Added support for query Tx descriptor status.
   * Added support for query Rx descriptor status.
+  * Added support for IEEE 1588 PTP.
 
 * **Updated NXP DPAA driver.**
 
diff --git a/drivers/net/hns3/hns3_cmd.h b/drivers/net/hns3/hns3_cmd.h
index 30aca82..c9631e8 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,
@@ -975,6 +981,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 5cc997d..039c9b2 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,
@@ -4971,6 +5008,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);
@@ -5988,6 +6030,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;
@@ -6692,6 +6740,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 ac255a3..a360efb 100644
--- a/drivers/net/hns3/hns3_ethdev.h
+++ b/drivers/net/hns3/hns3_ethdev.h
@@ -750,6 +750,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;
 
@@ -1000,6 +1007,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 ce5d852..74ec131 100644
--- a/drivers/net/hns3/hns3_rxtx.c
+++ b/drivers/net/hns3/hns3_rxtx.c
@@ -2365,6 +2365,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)
 {
@@ -2424,8 +2443,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;
@@ -2436,7 +2460,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);
@@ -2455,6 +2479,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);
@@ -3043,7 +3072,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
@@ -3091,6 +3120,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
@@ -4149,10 +4184,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;
 
@@ -4160,7 +4208,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 6689397..ded5b0b 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;
@@ -534,6 +541,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']
 
-- 
2.7.4


^ permalink raw reply	[flat|nested] 17+ messages in thread

* Re: [dpdk-dev] [PATCH 2/2] net/hns3: support IEEE 1588 PTP
  2021-03-31  2:35     ` Min Hu (Connor)
@ 2021-03-31  7:28       ` Thomas Monjalon
  2021-03-31  9:26         ` Ferruh Yigit
  0 siblings, 1 reply; 17+ messages in thread
From: Thomas Monjalon @ 2021-03-31  7:28 UTC (permalink / raw)
  To: Ferruh Yigit, Min Hu (Connor); +Cc: dev, Andrew Rybchenko

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.



^ permalink raw reply	[flat|nested] 17+ messages in thread

* Re: [dpdk-dev] [PATCH 2/2] net/hns3: support IEEE 1588 PTP
  2021-03-31  7:28       ` Thomas Monjalon
@ 2021-03-31  9:26         ` Ferruh Yigit
  2021-03-31 11:00           ` Min Hu (Connor)
  0 siblings, 1 reply; 17+ messages in thread
From: Ferruh Yigit @ 2021-03-31  9:26 UTC (permalink / raw)
  To: Thomas Monjalon, Min Hu (Connor); +Cc: dev, Andrew Rybchenko

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.

^ permalink raw reply	[flat|nested] 17+ messages in thread

* Re: [dpdk-dev] [PATCH 2/2] net/hns3: support IEEE 1588 PTP
  2021-03-31  9:26         ` Ferruh Yigit
@ 2021-03-31 11:00           ` Min Hu (Connor)
  0 siblings, 0 replies; 17+ messages in thread
From: Min Hu (Connor) @ 2021-03-31 11:00 UTC (permalink / raw)
  To: Ferruh Yigit, Thomas Monjalon; +Cc: dev, Andrew Rybchenko



在 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?
.

^ permalink raw reply	[flat|nested] 17+ messages in thread

* [dpdk-dev] [PATCH v3 0/2] Support PTP for hns3 PMD
  2021-03-26  8:55 [dpdk-dev] [PATCH 0/2] Support PTP for hns3 PMD Min Hu (Connor)
                   ` (2 preceding siblings ...)
  2021-03-31  7:01 ` [dpdk-dev] [PATCH v2 0/2] Support PTP for hns3 PMD Min Hu (Connor)
@ 2021-04-01 13:38 ` Min Hu (Connor)
  2021-04-01 13:38   ` [dpdk-dev] [PATCH v3 1/2] net/hns3: fix code check warning Min Hu (Connor)
                     ` (2 more replies)
  3 siblings, 3 replies; 17+ messages in thread
From: Min Hu (Connor) @ 2021-04-01 13:38 UTC (permalink / raw)
  To: dev; +Cc: ferruh.yigit, thomas

This set includes two patches, one patch is to fix
cyclomatic complexity, the other patch is to support
PTP, but depends on the first patch. So the two forms
one set of patches.
---
v3:
* Delete "RTE_LIBRTE_IEEE1588".

v2:
* Add release doc for version 21.05.

Min Hu (Connor) (2):
  net/hns3: fix code check warning
  net/hns3: support IEEE 1588 PTP

 doc/guides/nics/features/hns3.ini      |   2 +
 doc/guides/nics/hns3.rst               |   1 +
 doc/guides/rel_notes/release_21_05.rst |   1 +
 drivers/net/hns3/hns3_cmd.h            |  30 ++++
 drivers/net/hns3/hns3_ethdev.c         | 100 ++++++++---
 drivers/net/hns3/hns3_ethdev.h         |  20 +++
 drivers/net/hns3/hns3_ptp.c            | 292 +++++++++++++++++++++++++++++++++
 drivers/net/hns3/hns3_regs.h           |  23 +++
 drivers/net/hns3/hns3_rxtx.c           |  47 +++++-
 drivers/net/hns3/hns3_rxtx.h           |   7 +
 drivers/net/hns3/hns3_rxtx_vec.c       |  15 +-
 drivers/net/hns3/meson.build           |   3 +-
 12 files changed, 505 insertions(+), 36 deletions(-)
 create mode 100644 drivers/net/hns3/hns3_ptp.c

-- 
2.7.4


^ permalink raw reply	[flat|nested] 17+ messages in thread

* [dpdk-dev] [PATCH v3 1/2] net/hns3: fix code check warning
  2021-04-01 13:38 ` [dpdk-dev] [PATCH v3 0/2] Support PTP for hns3 PMD Min Hu (Connor)
@ 2021-04-01 13:38   ` Min Hu (Connor)
  2021-04-01 13:38   ` [dpdk-dev] [PATCH v3 2/2] net/hns3: support IEEE 1588 PTP Min Hu (Connor)
  2021-04-01 16:41   ` [dpdk-dev] [PATCH v3 0/2] Support PTP for hns3 PMD Ferruh Yigit
  2 siblings, 0 replies; 17+ messages in thread
From: Min Hu (Connor) @ 2021-04-01 13:38 UTC (permalink / raw)
  To: dev; +Cc: ferruh.yigit, thomas

This patch fixed cyclomatic complexity about MTU
in device configure process.

Fixes: 1f5ca0b460cd ("net/hns3: support some device operations")
Cc: stable@dpdk.org

Signed-off-by: Min Hu (Connor) <humin29@huawei.com>
---
 drivers/net/hns3/hns3_ethdev.c | 61 +++++++++++++++++++++++++-----------------
 1 file changed, 37 insertions(+), 24 deletions(-)

diff --git a/drivers/net/hns3/hns3_ethdev.c b/drivers/net/hns3/hns3_ethdev.c
index 9c71808..bb71808 100644
--- a/drivers/net/hns3/hns3_ethdev.c
+++ b/drivers/net/hns3/hns3_ethdev.c
@@ -2373,6 +2373,40 @@ hns3_init_ring_with_vector(struct hns3_hw *hw)
 }
 
 static int
+hns3_refresh_mtu(struct rte_eth_dev *dev, struct rte_eth_conf *conf)
+{
+	struct hns3_adapter *hns = dev->data->dev_private;
+	struct hns3_hw *hw = &hns->hw;
+	uint32_t max_rx_pkt_len;
+	uint16_t mtu;
+	int ret;
+
+	if (!(conf->rxmode.offloads & DEV_RX_OFFLOAD_JUMBO_FRAME))
+		return 0;
+
+	/*
+	 * If jumbo frames are enabled, MTU needs to be refreshed
+	 * according to the maximum RX packet length.
+	 */
+	max_rx_pkt_len = conf->rxmode.max_rx_pkt_len;
+	if (max_rx_pkt_len > HNS3_MAX_FRAME_LEN ||
+	    max_rx_pkt_len <= HNS3_DEFAULT_FRAME_LEN) {
+		hns3_err(hw, "maximum Rx packet length must be greater than %u "
+			 "and no more than %u when jumbo frame enabled.",
+			 (uint16_t)HNS3_DEFAULT_FRAME_LEN,
+			 (uint16_t)HNS3_MAX_FRAME_LEN);
+		return -EINVAL;
+	}
+
+	mtu = (uint16_t)HNS3_PKTLEN_TO_MTU(max_rx_pkt_len);
+	ret = hns3_dev_mtu_set(dev, mtu);
+	if (ret)
+		return ret;
+	dev->data->mtu = mtu;
+
+	return 0;
+}
+static int
 hns3_dev_configure(struct rte_eth_dev *dev)
 {
 	struct hns3_adapter *hns = dev->data->dev_private;
@@ -2382,8 +2416,6 @@ hns3_dev_configure(struct rte_eth_dev *dev)
 	uint16_t nb_rx_q = dev->data->nb_rx_queues;
 	uint16_t nb_tx_q = dev->data->nb_tx_queues;
 	struct rte_eth_rss_conf rss_conf;
-	uint32_t max_rx_pkt_len;
-	uint16_t mtu;
 	bool gro_en;
 	int ret;
 
@@ -2431,28 +2463,9 @@ hns3_dev_configure(struct rte_eth_dev *dev)
 			goto cfg_err;
 	}
 
-	/*
-	 * If jumbo frames are enabled, MTU needs to be refreshed
-	 * according to the maximum RX packet length.
-	 */
-	if (conf->rxmode.offloads & DEV_RX_OFFLOAD_JUMBO_FRAME) {
-		max_rx_pkt_len = conf->rxmode.max_rx_pkt_len;
-		if (max_rx_pkt_len > HNS3_MAX_FRAME_LEN ||
-		    max_rx_pkt_len <= HNS3_DEFAULT_FRAME_LEN) {
-			hns3_err(hw, "maximum Rx packet length must be greater "
-				 "than %u and less than %u when jumbo frame enabled.",
-				 (uint16_t)HNS3_DEFAULT_FRAME_LEN,
-				 (uint16_t)HNS3_MAX_FRAME_LEN);
-			ret = -EINVAL;
-			goto cfg_err;
-		}
-
-		mtu = (uint16_t)HNS3_PKTLEN_TO_MTU(max_rx_pkt_len);
-		ret = hns3_dev_mtu_set(dev, mtu);
-		if (ret)
-			goto cfg_err;
-		dev->data->mtu = mtu;
-	}
+	ret = hns3_refresh_mtu(dev, conf);
+	if (ret)
+		goto cfg_err;
 
 	ret = hns3_dev_configure_vlan(dev);
 	if (ret)
-- 
2.7.4


^ permalink raw reply	[flat|nested] 17+ messages in thread

* [dpdk-dev] [PATCH v3 2/2] net/hns3: support IEEE 1588 PTP
  2021-04-01 13:38 ` [dpdk-dev] [PATCH v3 0/2] Support PTP for hns3 PMD Min Hu (Connor)
  2021-04-01 13:38   ` [dpdk-dev] [PATCH v3 1/2] net/hns3: fix code check warning Min Hu (Connor)
@ 2021-04-01 13:38   ` Min Hu (Connor)
  2021-04-01 16:41   ` [dpdk-dev] [PATCH v3 0/2] Support PTP for hns3 PMD Ferruh Yigit
  2 siblings, 0 replies; 17+ messages in thread
From: Min Hu (Connor) @ 2021-04-01 13:38 UTC (permalink / raw)
  To: dev; +Cc: ferruh.yigit, thomas

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 +
 doc/guides/rel_notes/release_21_05.rst |   1 +
 drivers/net/hns3/hns3_cmd.h            |  30 ++++
 drivers/net/hns3/hns3_ethdev.c         |  41 ++++-
 drivers/net/hns3/hns3_ethdev.h         |  20 +++
 drivers/net/hns3/hns3_ptp.c            | 292 +++++++++++++++++++++++++++++++++
 drivers/net/hns3/hns3_regs.h           |  23 +++
 drivers/net/hns3/hns3_rxtx.c           |  47 +++++-
 drivers/net/hns3/hns3_rxtx.h           |   7 +
 drivers/net/hns3/hns3_rxtx_vec.c       |  15 +-
 drivers/net/hns3/meson.build           |   3 +-
 12 files changed, 469 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/doc/guides/rel_notes/release_21_05.rst b/doc/guides/rel_notes/release_21_05.rst
index 873140b..2ffeb92 100644
--- a/doc/guides/rel_notes/release_21_05.rst
+++ b/doc/guides/rel_notes/release_21_05.rst
@@ -90,6 +90,7 @@ New Features
   * Added support for outer UDP checksum in Kunpeng930.
   * Added support for query Tx descriptor status.
   * Added support for query Rx descriptor status.
+  * Added support for IEEE 1588 PTP.
 
 * **Updated Intel iavf driver.**
 
diff --git a/drivers/net/hns3/hns3_cmd.h b/drivers/net/hns3/hns3_cmd.h
index 30aca82..5d1fb67 100644
--- a/drivers/net/hns3/hns3_cmd.h
+++ b/drivers/net/hns3/hns3_cmd.h
@@ -123,6 +123,10 @@ enum hns3_opcode_type {
 	HNS3_OPC_CLEAR_MAC_TNL_INT      = 0x0312,
 	HNS3_OPC_CONFIG_FEC_MODE        = 0x031A,
 
+	/* PTP command */
+	HNS3_OPC_PTP_INT_EN             = 0x0501,
+	HNS3_OPC_CFG_PTP_MODE           = 0x0507,
+
 	/* PFC/Pause commands */
 	HNS3_OPC_CFG_MAC_PAUSE_EN       = 0x0701,
 	HNS3_OPC_CFG_PFC_PAUSE_EN       = 0x0702,
@@ -976,6 +980,32 @@ struct hns3_query_ssu_cmd {
 	uint32_t rev1[2];
 };
 
+#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];
+};
+
 #define HNS3_MAX_TQP_NUM_HIP08_PF	64
 #define HNS3_DEFAULT_TX_BUF		0x4000    /* 16k  bytes */
 #define HNS3_TOTAL_PKT_BUF		0x108000  /* 1.03125M bytes */
diff --git a/drivers/net/hns3/hns3_ethdev.c b/drivers/net/hns3/hns3_ethdev.c
index bb71808..0e812bb 100644
--- a/drivers/net/hns3/hns3_ethdev.c
+++ b/drivers/net/hns3/hns3_ethdev.c
@@ -58,6 +58,7 @@ enum hns3_evt_cause {
 	HNS3_VECTOR0_EVENT_RST,
 	HNS3_VECTOR0_EVENT_MBX,
 	HNS3_VECTOR0_EVENT_ERR,
+	HNS3_VECTOR0_EVENT_PTP,
 	HNS3_VECTOR0_EVENT_OTHER,
 };
 
@@ -202,6 +203,13 @@ hns3_check_event_cause(struct hns3_adapter *hns, uint32_t *clearval)
 		goto out;
 	}
 
+	/* 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;
+	}
+
 	/* 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 +235,17 @@ hns3_check_event_cause(struct hns3_adapter *hns, uint32_t *clearval)
 	return ret;
 }
 
+static bool
+hns3_is_1588_event_type(uint32_t event_type)
+{
+	return (event_type == HNS3_VECTOR0_EVENT_PTP);
+}
+
 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 +268,8 @@ 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);
+	hns3_clear_event_cause(hw, HNS3_VECTOR0_EVENT_PTP,
+				BIT(HNS3_VECTOR0_1588_INT_B));
 }
 
 static void
@@ -2467,6 +2484,10 @@ hns3_dev_configure(struct rte_eth_dev *dev)
 	if (ret)
 		goto cfg_err;
 
+	ret = hns3_mbuf_dyn_rx_timestamp_register(dev, conf);
+	if (ret)
+		goto cfg_err;
+
 	ret = hns3_dev_configure_vlan(dev);
 	if (ret)
 		goto cfg_err;
@@ -2640,6 +2661,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,
@@ -4959,6 +4983,10 @@ hns3_init_pf(struct rte_eth_dev *eth_dev)
 		goto err_intr_callback_register;
 	}
 
+	ret = hns3_ptp_init(hw);
+	if (ret)
+		goto err_get_config;
+
 	/* Enable interrupt */
 	rte_intr_enable(&pci_dev->intr_handle);
 	hns3_pf_enable_irq0(hw);
@@ -5976,6 +6004,10 @@ hns3_restore_conf(struct hns3_adapter *hns)
 	if (ret)
 		goto err_promisc;
 
+	ret = hns3_restore_ptp(hns);
+	if (ret)
+		goto err_promisc;
+
 	ret = hns3_restore_rx_interrupt(hw);
 	if (ret)
 		goto err_promisc;
@@ -6680,6 +6712,13 @@ 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,
+	.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,
 };
 
 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 ac255a3..d23239d 100644
--- a/drivers/net/hns3/hns3_ethdev.h
+++ b/drivers/net/hns3/hns3_ethdev.h
@@ -750,6 +750,11 @@ struct hns3_pf {
 	bool support_sfp_query;
 	uint32_t fec_mode; /* current FEC mode for ethdev */
 
+	bool ptp_enable;
+
+	/* Stores timestamp of last received packet on dev */
+	uint64_t rx_timestamp;
+
 	struct hns3_vtag_cfg vtag_config;
 	LIST_HEAD(vlan_tbl, hns3_user_vlan_table) vlan_list;
 
@@ -999,6 +1004,21 @@ int hns3_dev_infos_get(struct rte_eth_dev *eth_dev,
 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);
+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);
 
 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..df84859
--- /dev/null
+++ b/drivers/net/hns3/hns3_ptp.c
@@ -0,0 +1,292 @@
+/* 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"
+
+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;
+}
diff --git a/drivers/net/hns3/hns3_regs.h b/drivers/net/hns3/hns3_regs.h
index e141fe1..c9e10be 100644
--- a/drivers/net/hns3/hns3_regs.h
+++ b/drivers/net/hns3/hns3_regs.h
@@ -121,6 +121,29 @@
 #define HNS3_TQP_INTR_RL_DEFAULT		0
 #define HNS3_TQP_INTR_QL_DEFAULT		0
 
+/* 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)
+
 /* 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 ce5d852..70cd2c2 100644
--- a/drivers/net/hns3/hns3_rxtx.c
+++ b/drivers/net/hns3/hns3_rxtx.c
@@ -2365,6 +2365,23 @@ hns3_rx_alloc_buffer(struct hns3_rx_queue *rxq)
 		return rte_mbuf_raw_alloc(rxq->mb_pool);
 }
 
+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;
+}
+
 uint16_t
 hns3_recv_pkts(void *rx_queue, struct rte_mbuf **rx_pkts, uint16_t nb_pkts)
 {
@@ -2424,8 +2441,12 @@ 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;
 
+		if (unlikely(bd_base_info & BIT(HNS3_RXD_TS_VLD_B)))
+			hns3_rx_ptp_timestamp_handle(rxq, rxm, rxdp);
+
 		dma_addr = rte_mbuf_data_iova_default(nmb);
 		rxdp->addr = rte_cpu_to_le_64(dma_addr);
 		rxdp->rx.bd_base_info = 0;
@@ -2436,7 +2457,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);
@@ -2455,6 +2476,9 @@ 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);
 
+		if (rxm->packet_type == RTE_PTYPE_L2_ETHER_TIMESYNC)
+			rxm->ol_flags |= PKT_RX_IEEE1588_PTP;
+
 		if (likely(bd_base_info & BIT(HNS3_RXD_L3L4P_B)))
 			hns3_rx_set_cksum_flag(rxm, rxm->packet_type,
 					       cksum_err);
@@ -3043,7 +3067,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
@@ -3091,6 +3115,10 @@ 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);
 	}
+
+	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));
 }
 
 static inline int
@@ -4149,10 +4177,21 @@ 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;
+
+	struct hns3_hw *hw = HNS3_DEV_PRIVATE_TO_HW(dev->data->dev_private);
+	if (hns3_dev_ptp_supported(hw))
+		return false;
+
+	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;
 
@@ -4160,7 +4199,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 6689397..eebbebf 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,8 @@ enum hns3_pkt_tun_type {
 struct hns3_desc {
 	union {
 		uint64_t addr;
+		uint64_t timestamp;
+
 		struct {
 			uint32_t addr0;
 			uint32_t addr1;
@@ -534,6 +538,9 @@ enum hns3_cksum_status {
 	HNS3_OUTER_L4_CKSUM_ERR = 8
 };
 
+extern uint64_t hns3_timestamp_rx_dynflag;
+extern int hns3_timestamp_dynfield_offset;
+
 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..030bfdb 100644
--- a/drivers/net/hns3/hns3_rxtx_vec.c
+++ b/drivers/net/hns3/hns3_rxtx_vec.c
@@ -18,6 +18,10 @@ hns3_tx_check_vec_support(struct rte_eth_dev *dev)
 {
 	struct rte_eth_txmode *txmode = &dev->data->dev_conf.txmode;
 
+	struct hns3_hw *hw = HNS3_DEV_PRIVATE_TO_HW(dev->data->dev_private);
+	if (hns3_dev_ptp_supported(hw))
+		return -ENOTSUP;
+
 	/* Only support DEV_TX_OFFLOAD_MBUF_FAST_FREE */
 	if (txmode->offloads != DEV_TX_OFFLOAD_MBUF_FAST_FREE)
 		return -ENOTSUP;
@@ -167,7 +171,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 +186,19 @@ 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;
 
+	struct hns3_hw *hw = HNS3_DEV_PRIVATE_TO_HW(dev->data->dev_private);
+	if (hns3_dev_ptp_supported(hw))
+		return -ENOTSUP;
+
 	if (dev->data->scattered_rx)
 		return -ENOTSUP;
 
@@ -207,8 +212,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']
 
-- 
2.7.4


^ permalink raw reply	[flat|nested] 17+ messages in thread

* Re: [dpdk-dev] [PATCH v3 0/2] Support PTP for hns3 PMD
  2021-04-01 13:38 ` [dpdk-dev] [PATCH v3 0/2] Support PTP for hns3 PMD Min Hu (Connor)
  2021-04-01 13:38   ` [dpdk-dev] [PATCH v3 1/2] net/hns3: fix code check warning Min Hu (Connor)
  2021-04-01 13:38   ` [dpdk-dev] [PATCH v3 2/2] net/hns3: support IEEE 1588 PTP Min Hu (Connor)
@ 2021-04-01 16:41   ` Ferruh Yigit
  2 siblings, 0 replies; 17+ messages in thread
From: Ferruh Yigit @ 2021-04-01 16:41 UTC (permalink / raw)
  To: Min Hu (Connor), dev; +Cc: thomas

On 4/1/2021 2:38 PM, Min Hu (Connor) wrote:
> This set includes two patches, one patch is to fix
> cyclomatic complexity, the other patch is to support
> PTP, but depends on the first patch. So the two forms
> one set of patches.
> ---
> v3:
> * Delete "RTE_LIBRTE_IEEE1588".
> 
> v2:
> * Add release doc for version 21.05.
> 
> Min Hu (Connor) (2):
>    net/hns3: fix code check warning
>    net/hns3: support IEEE 1588 PTP
> 

Series applied to dpdk-next-net/main, thanks.

^ permalink raw reply	[flat|nested] 17+ messages in thread

end of thread, other threads:[~2021-04-01 16:41 UTC | newest]

Thread overview: 17+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-03-26  8:55 [dpdk-dev] [PATCH 0/2] Support PTP for hns3 PMD Min Hu (Connor)
2021-03-26  8:56 ` [dpdk-dev] [PATCH 1/2] net/hns3: fix code check warning Min Hu (Connor)
2021-03-26  8:56 ` [dpdk-dev] [PATCH 2/2] net/hns3: support IEEE 1588 PTP Min Hu (Connor)
2021-03-30 13:59   ` Ferruh Yigit
2021-03-31  2:35     ` Min Hu (Connor)
2021-03-31  7:28       ` Thomas Monjalon
2021-03-31  9:26         ` Ferruh Yigit
2021-03-31 11:00           ` Min Hu (Connor)
2021-03-30 14:12   ` Ferruh Yigit
2021-03-31  2:38     ` Min Hu (Connor)
2021-03-31  7:01 ` [dpdk-dev] [PATCH v2 0/2] Support PTP for hns3 PMD Min Hu (Connor)
2021-03-31  7:01   ` [dpdk-dev] [PATCH v2 1/2] net/hns3: fix code check warning Min Hu (Connor)
2021-03-31  7:01   ` [dpdk-dev] [PATCH v2 2/2] net/hns3: support IEEE 1588 PTP Min Hu (Connor)
2021-04-01 13:38 ` [dpdk-dev] [PATCH v3 0/2] Support PTP for hns3 PMD Min Hu (Connor)
2021-04-01 13:38   ` [dpdk-dev] [PATCH v3 1/2] net/hns3: fix code check warning Min Hu (Connor)
2021-04-01 13:38   ` [dpdk-dev] [PATCH v3 2/2] net/hns3: support IEEE 1588 PTP Min Hu (Connor)
2021-04-01 16:41   ` [dpdk-dev] [PATCH v3 0/2] Support PTP for hns3 PMD Ferruh Yigit

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).