DPDK patches and discussions
 help / color / mirror / Atom feed
From: Simei Su <simei.su@intel.com>
To: qi.z.zhang@intel.com
Cc: dev@dpdk.org, haiyue.wang@intel.com, Simei Su <simei.su@intel.com>
Subject: [dpdk-dev] [PATCH v3] net/ice: enable Rx timestamp on Flex Descriptor
Date: Sun, 26 Sep 2021 15:53:15 +0800	[thread overview]
Message-ID: <20210926075315.93630-1-simei.su@intel.com> (raw)
In-Reply-To: <20210926063904.28200-1-simei.su@intel.com>

Use the dynamic mbuf to register timestamp field and flag.
The ice has the feature to dump Rx timestamp value into dynamic
mbuf field by flex descriptor. This feature is turned on by dev
config "enable-rx-timestamp". Currently, it's only supported
under scalar path.

Signed-off-by: Simei Su <simei.su@intel.com>
---
v3:
* Define ice_tstamp_convert_32b_64b() as a static inline function in ice_rxtx.h.

v2:
* Refine release notes.
* Merge two helper functions into one.
* Remove one field in ice_rx_queue structure.

 doc/guides/rel_notes/release_21_11.rst |  3 +-
 drivers/net/ice/ice_ethdev.c           |  6 +++-
 drivers/net/ice/ice_rxtx.c             | 59 ++++++++++++++++++++++++++++++++++
 drivers/net/ice/ice_rxtx.h             | 33 +++++++++++++++++++
 drivers/net/ice/ice_rxtx_vec_common.h  |  3 ++
 5 files changed, 102 insertions(+), 2 deletions(-)

diff --git a/doc/guides/rel_notes/release_21_11.rst b/doc/guides/rel_notes/release_21_11.rst
index 19356ac..0bbe82c 100644
--- a/doc/guides/rel_notes/release_21_11.rst
+++ b/doc/guides/rel_notes/release_21_11.rst
@@ -75,7 +75,8 @@ New Features
 
 * **Updated Intel ice driver.**
 
-  Added 1PPS out support by a devargs.
+  * Added 1PPS out support by a devargs.
+  * Added DEV_RX_OFFLOAD_TIMESTAMP support.
 
 * **Updated Marvell cnxk ethdev driver.**
 
diff --git a/drivers/net/ice/ice_ethdev.c b/drivers/net/ice/ice_ethdev.c
index e24a3b6..534af03 100644
--- a/drivers/net/ice/ice_ethdev.c
+++ b/drivers/net/ice/ice_ethdev.c
@@ -31,6 +31,9 @@
 #define ICE_HW_DEBUG_MASK_ARG     "hw_debug_mask"
 #define ICE_ONE_PPS_OUT_ARG       "pps_out"
 
+uint64_t ice_timestamp_dynflag;
+int ice_timestamp_dynfield_offset = -1;
+
 static const char * const ice_valid_args[] = {
 	ICE_SAFE_MODE_SUPPORT_ARG,
 	ICE_PIPELINE_MODE_SUPPORT_ARG,
@@ -3652,7 +3655,8 @@ ice_dev_info_get(struct rte_eth_dev *dev, struct rte_eth_dev_info *dev_info)
 			DEV_RX_OFFLOAD_QINQ_STRIP |
 			DEV_RX_OFFLOAD_OUTER_IPV4_CKSUM |
 			DEV_RX_OFFLOAD_VLAN_EXTEND |
-			DEV_RX_OFFLOAD_RSS_HASH;
+			DEV_RX_OFFLOAD_RSS_HASH |
+			DEV_RX_OFFLOAD_TIMESTAMP;
 		dev_info->tx_offload_capa |=
 			DEV_TX_OFFLOAD_QINQ_INSERT |
 			DEV_TX_OFFLOAD_IPV4_CKSUM |
diff --git a/drivers/net/ice/ice_rxtx.c b/drivers/net/ice/ice_rxtx.c
index 5d7ab4f..a043df2 100644
--- a/drivers/net/ice/ice_rxtx.c
+++ b/drivers/net/ice/ice_rxtx.c
@@ -302,6 +302,18 @@ ice_program_hw_rx_queue(struct ice_rx_queue *rxq)
 		}
 	}
 
+	if (rxq->offloads & DEV_RX_OFFLOAD_TIMESTAMP) {
+		/* Register mbuf field and flag for Rx timestamp */
+		err = rte_mbuf_dyn_rx_timestamp_register(
+				&ice_timestamp_dynfield_offset,
+				&ice_timestamp_dynflag);
+		if (err != 0) {
+			PMD_INIT_LOG(ERR,
+				"Cannot register mbuf field/flag for timestamp");
+			return -EINVAL;
+		}
+	}
+
 	memset(&rx_ctx, 0, sizeof(rx_ctx));
 
 	rx_ctx.base = rxq->rx_ring_dma / ICE_QUEUE_BASE_ADDR_UNIT;
@@ -354,6 +366,9 @@ ice_program_hw_rx_queue(struct ice_rx_queue *rxq)
 	regval |= (0x03 << QRXFLXP_CNTXT_RXDID_PRIO_S) &
 		QRXFLXP_CNTXT_RXDID_PRIO_M;
 
+	if (rxq->offloads & DEV_RX_OFFLOAD_TIMESTAMP)
+		regval |= QRXFLXP_CNTXT_TS_M;
+
 	ICE_WRITE_REG(hw, QRXFLXP_CNTXT(rxq->reg_idx), regval);
 
 	err = ice_clear_rxq_ctx(hw, rxq->reg_idx);
@@ -1546,6 +1561,9 @@ ice_rx_scan_hw_ring(struct ice_rx_queue *rxq)
 	int32_t i, j, nb_rx = 0;
 	uint64_t pkt_flags = 0;
 	uint32_t *ptype_tbl = rxq->vsi->adapter->ptype_tbl;
+	struct ice_vsi *vsi = rxq->vsi;
+	struct ice_hw *hw = ICE_VSI_TO_HW(vsi);
+	uint64_t ts_ns;
 
 	rxdp = &rxq->rx_ring[rxq->rx_tail];
 	rxep = &rxq->sw_ring[rxq->rx_tail];
@@ -1589,6 +1607,17 @@ ice_rx_scan_hw_ring(struct ice_rx_queue *rxq)
 			ice_rxd_to_vlan_tci(mb, &rxdp[j]);
 			rxq->rxd_to_pkt_fields(rxq, mb, &rxdp[j]);
 
+			if (rxq->offloads & DEV_RX_OFFLOAD_TIMESTAMP) {
+				ts_ns = ice_tstamp_convert_32b_64b(hw,
+					rte_le_to_cpu_32(rxdp[j].wb.flex_ts.ts_high));
+				if (ice_timestamp_dynflag > 0) {
+					*RTE_MBUF_DYNFIELD(mb,
+						ice_timestamp_dynfield_offset,
+						rte_mbuf_timestamp_t *) = ts_ns;
+					mb->ol_flags |= ice_timestamp_dynflag;
+				}
+			}
+
 			mb->ol_flags |= pkt_flags;
 		}
 
@@ -1772,6 +1801,9 @@ ice_recv_scattered_pkts(void *rx_queue,
 	uint64_t dma_addr;
 	uint64_t pkt_flags;
 	uint32_t *ptype_tbl = rxq->vsi->adapter->ptype_tbl;
+	struct ice_vsi *vsi = rxq->vsi;
+	struct ice_hw *hw = ICE_VSI_TO_HW(vsi);
+	uint64_t ts_ns;
 
 	while (nb_rx < nb_pkts) {
 		rxdp = &rx_ring[rx_id];
@@ -1882,6 +1914,18 @@ ice_recv_scattered_pkts(void *rx_queue,
 		ice_rxd_to_vlan_tci(first_seg, &rxd);
 		rxq->rxd_to_pkt_fields(rxq, first_seg, &rxd);
 		pkt_flags = ice_rxd_error_to_pkt_flags(rx_stat_err0);
+
+		if (rxq->offloads & DEV_RX_OFFLOAD_TIMESTAMP) {
+			ts_ns = ice_tstamp_convert_32b_64b(hw,
+				rte_le_to_cpu_32(rxd.wb.flex_ts.ts_high));
+			if (ice_timestamp_dynflag > 0) {
+				*RTE_MBUF_DYNFIELD(first_seg,
+					ice_timestamp_dynfield_offset,
+					rte_mbuf_timestamp_t *) = ts_ns;
+				first_seg->ol_flags |= ice_timestamp_dynflag;
+			}
+		}
+
 		first_seg->ol_flags |= pkt_flags;
 		/* Prefetch data of first segment, if configured to do so. */
 		rte_prefetch0(RTE_PTR_ADD(first_seg->buf_addr,
@@ -2237,6 +2281,9 @@ ice_recv_pkts(void *rx_queue,
 	uint64_t dma_addr;
 	uint64_t pkt_flags;
 	uint32_t *ptype_tbl = rxq->vsi->adapter->ptype_tbl;
+	struct ice_vsi *vsi = rxq->vsi;
+	struct ice_hw *hw = ICE_VSI_TO_HW(vsi);
+	uint64_t ts_ns;
 
 	while (nb_rx < nb_pkts) {
 		rxdp = &rx_ring[rx_id];
@@ -2288,6 +2335,18 @@ ice_recv_pkts(void *rx_queue,
 		ice_rxd_to_vlan_tci(rxm, &rxd);
 		rxq->rxd_to_pkt_fields(rxq, rxm, &rxd);
 		pkt_flags = ice_rxd_error_to_pkt_flags(rx_stat_err0);
+
+		if (rxq->offloads & DEV_RX_OFFLOAD_TIMESTAMP) {
+			ts_ns = ice_tstamp_convert_32b_64b(hw,
+				rte_le_to_cpu_32(rxd.wb.flex_ts.ts_high));
+			if (ice_timestamp_dynflag > 0) {
+				*RTE_MBUF_DYNFIELD(rxm,
+					ice_timestamp_dynfield_offset,
+					rte_mbuf_timestamp_t *) = ts_ns;
+				rxm->ol_flags |= ice_timestamp_dynflag;
+			}
+		}
+
 		rxm->ol_flags |= pkt_flags;
 		/* copy old mbuf to rx_pkts */
 		rx_pkts[nb_rx++] = rxm;
diff --git a/drivers/net/ice/ice_rxtx.h b/drivers/net/ice/ice_rxtx.h
index b10db08..4c8b6f7 100644
--- a/drivers/net/ice/ice_rxtx.h
+++ b/drivers/net/ice/ice_rxtx.h
@@ -40,6 +40,9 @@
 
 #define ICE_RXDID_COMMS_OVS	22
 
+extern uint64_t ice_timestamp_dynflag;
+extern int ice_timestamp_dynfield_offset;
+
 typedef void (*ice_rx_release_mbufs_t)(struct ice_rx_queue *rxq);
 typedef void (*ice_tx_release_mbufs_t)(struct ice_tx_queue *txq);
 typedef void (*ice_rxd_to_pkt_fields_t)(struct ice_rx_queue *rxq,
@@ -311,4 +314,34 @@ void ice_fdir_rx_parsing_enable(struct ice_adapter *ad, bool on)
 	}
 }
 
+/* Helper function to convert a 32b nanoseconds timestamp to 64b. */
+static inline
+uint64_t ice_tstamp_convert_32b_64b(struct ice_hw *hw, uint32_t in_timestamp)
+{
+	const uint64_t mask = 0xFFFFFFFF;
+	uint32_t hi, lo, lo2, delta;
+	uint64_t time, ns;
+
+	lo = ICE_READ_REG(hw, GLTSYN_TIME_L(0));
+	hi = ICE_READ_REG(hw, GLTSYN_TIME_H(0));
+	lo2 = ICE_READ_REG(hw, GLTSYN_TIME_L(0));
+
+	if (lo2 < lo) {
+		lo = ICE_READ_REG(hw, GLTSYN_TIME_L(0));
+		hi = ICE_READ_REG(hw, GLTSYN_TIME_H(0));
+	}
+
+	time = ((uint64_t)hi << 32) | lo;
+
+	delta = (in_timestamp - (uint32_t)(time & mask));
+	if (delta > (mask / 2)) {
+		delta = ((uint32_t)(time & mask) - in_timestamp);
+		ns = time - delta;
+	} else {
+		ns = time + delta;
+	}
+
+	return ns;
+}
+
 #endif /* _ICE_RXTX_H_ */
diff --git a/drivers/net/ice/ice_rxtx_vec_common.h b/drivers/net/ice/ice_rxtx_vec_common.h
index 2d8ef7d..5b52505 100644
--- a/drivers/net/ice/ice_rxtx_vec_common.h
+++ b/drivers/net/ice/ice_rxtx_vec_common.h
@@ -287,6 +287,9 @@ ice_rx_vec_queue_default(struct ice_rx_queue *rxq)
 	if (rxq->proto_xtr != PROTO_XTR_NONE)
 		return -1;
 
+	if (rxq->offloads & DEV_RX_OFFLOAD_TIMESTAMP)
+		return -1;
+
 	if (rxq->offloads & ICE_RX_VECTOR_OFFLOAD)
 		return ICE_VECTOR_OFFLOAD_PATH;
 
-- 
2.9.5


  reply	other threads:[~2021-09-26  8:02 UTC|newest]

Thread overview: 8+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2021-09-18  6:56 [dpdk-dev] [PATCH] " Simei Su
2021-09-24  5:25 ` Zhang, Qi Z
2021-09-24  9:13   ` Su, Simei
2021-09-26  6:39 ` [dpdk-dev] [PATCH v2] " Simei Su
2021-09-26  7:53   ` Simei Su [this message]
2021-09-26 14:04     ` [dpdk-dev] [PATCH v4] " Simei Su
2021-09-27  7:01       ` Zhang, Qi Z
2021-09-28  3:35         ` Zhang, Qi Z

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20210926075315.93630-1-simei.su@intel.com \
    --to=simei.su@intel.com \
    --cc=dev@dpdk.org \
    --cc=haiyue.wang@intel.com \
    --cc=qi.z.zhang@intel.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
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).