]> git.droids-corp.org - dpdk.git/commitdiff
net/ice: enable Rx timestamp on flex descriptor
authorSimei Su <simei.su@intel.com>
Sun, 26 Sep 2021 14:04:45 +0000 (22:04 +0800)
committerQi Zhang <qi.z.zhang@intel.com>
Tue, 28 Sep 2021 03:33:41 +0000 (05:33 +0200)
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>
doc/guides/nics/features/ice.ini
doc/guides/rel_notes/release_21_11.rst
drivers/net/ice/ice_ethdev.c
drivers/net/ice/ice_rxtx.c
drivers/net/ice/ice_rxtx.h
drivers/net/ice/ice_rxtx_vec_common.h

index e0667874b6cdfe6b01da68364691915df75d62c8..29f49290401f37329cfa3e0cfd230e5827f07dff 100644 (file)
@@ -28,6 +28,7 @@ VLAN offload         = Y
 QinQ offload         = P
 L3 checksum offload  = P
 L4 checksum offload  = P
+Timestamp offload    = P
 Inner L3 checksum    = P
 Inner L4 checksum    = P
 Packet type parsing  = Y
index b4ffec6a6384d434f3e13a14df7a19b0eac3ce42..0cae22e8dd6af7f7ed3bb83edb3a0f1282137865 100644 (file)
@@ -82,6 +82,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.**
 
index d2640901b4ed474cac02bc03f4115a76172733bd..611b0b3781f8184e42f74786b91845393050cf1d 100644 (file)
@@ -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 |
index 5d7ab4f047ee6730e5a0a51d06c03a0ca67d584c..bb751831b86f8737192195c2c9f7192fffb2892f 100644 (file)
@@ -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;
index b10db0874d20d58ace98a6becd054800b41db1b0..4c8b6f72c2c76ba1c671a5d95c6d3781694dfea4 100644 (file)
@@ -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_ */
index 2d8ef7dc8a93d5951f2666afa9f85c28fd030df5..5b5250565e3551f84cef8bee546397eb621d283b 100644 (file)
@@ -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;