[v4] net/ice: enable Rx timestamp on Flex Descriptor
Checks
Commit Message
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>
---
v4:
* Rebase code.
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 | 1 +
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, 101 insertions(+), 1 deletion(-)
Comments
> -----Original Message-----
> From: Su, Simei <simei.su@intel.com>
> Sent: Sunday, September 26, 2021 10:05 PM
> To: Zhang, Qi Z <qi.z.zhang@intel.com>
> Cc: dev@dpdk.org; Wang, Haiyue <haiyue.wang@intel.com>; Su, Simei
> <simei.su@intel.com>
> Subject: [PATCH v4] net/ice: enable Rx timestamp on Flex Descriptor
>
> 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>
Acked-by: Qi Zhang <qi.z.zhang@intel.com>
Applied to dpdk-next-net-intel.
Thanks
Qi
> -----Original Message-----
> From: dev <dev-bounces@dpdk.org> On Behalf Of Zhang, Qi Z
> Sent: Monday, September 27, 2021 3:02 PM
> To: Su, Simei <simei.su@intel.com>
> Cc: dev@dpdk.org; Wang, Haiyue <haiyue.wang@intel.com>
> Subject: Re: [dpdk-dev] [PATCH v4] net/ice: enable Rx timestamp on Flex
> Descriptor
>
>
>
> > -----Original Message-----
> > From: Su, Simei <simei.su@intel.com>
> > Sent: Sunday, September 26, 2021 10:05 PM
> > To: Zhang, Qi Z <qi.z.zhang@intel.com>
> > Cc: dev@dpdk.org; Wang, Haiyue <haiyue.wang@intel.com>; Su, Simei
> > <simei.su@intel.com>
> > Subject: [PATCH v4] net/ice: enable Rx timestamp on Flex Descriptor
> >
> > 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>
>
> Acked-by: Qi Zhang <qi.z.zhang@intel.com>
Seems the patch need update the ice.ini for new feature enabling.
As it has not been merged into next-net, so fix the gap by adding below in ice.ini in dpdk-next-net-intel.
Timestamp offload = P
>
> Applied to dpdk-next-net-intel.
>
> Thanks
> Qi
@@ -81,6 +81,7 @@ New Features
* Added 1PPS out support by a devargs.
* Added IPv4 and L4(TCP/UDP/SCTP) checksum hash support in RSS flow.
+ * Added DEV_RX_OFFLOAD_TIMESTAMP support.
* **Updated Marvell cnxk ethdev driver.**
@@ -32,6 +32,9 @@
#define ICE_ONE_PPS_OUT_ARG "pps_out"
#define ICE_RX_LOW_LATENCY_ARG "rx_low_latency"
+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,
@@ -3671,7 +3674,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 |
@@ -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) {
+ PMD_DRV_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;
@@ -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_ */
@@ -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;