From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mails.dpdk.org (mails.dpdk.org [217.70.189.124]) by inbox.dpdk.org (Postfix) with ESMTP id 2172EA054F; Mon, 5 Sep 2022 13:00:15 +0200 (CEST) Received: from [217.70.189.124] (localhost [127.0.0.1]) by mails.dpdk.org (Postfix) with ESMTP id AA5DA427F2; Mon, 5 Sep 2022 12:59:29 +0200 (CEST) Received: from mga03.intel.com (mga03.intel.com [134.134.136.65]) by mails.dpdk.org (Postfix) with ESMTP id 26A9A410E7 for ; Mon, 5 Sep 2022 12:59:27 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1662375568; x=1693911568; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=O//XKjNOY58y29+68DfafW/tq8k7rRxIUJnwoQiydgE=; b=ZQ/Duac/tQ97qZISlaEp7P5wpJFR8UGwWp4S+n0hfaBEKLd87CR09u24 mV3TeOlkA/uLWDP9xRsZBARJ6ufTBkEy2zhR592O4L803YYIaIFDO7h5e ImuX82AayLljv6XycJMpvfviaZzwKM9ZakZn5tcGFXJov3nspiLme035n YBEJCwQNDzGcxfnWxBwukoaYsL1Gz4KGXvuyO5XHV8sXUVA/zrDUzkobu FVvIyt5moOfgxOmqM/2Z91hYUYgd4vwnp7BH6EUYSXr54akLEW1qiRGlY F/Bl5v4EEaxeNESqfKGInpxa000w17dhhy2kQAHAkW+KvBlgyqEPmZBwm Q==; X-IronPort-AV: E=McAfee;i="6500,9779,10460"; a="297676368" X-IronPort-AV: E=Sophos;i="5.93,291,1654585200"; d="scan'208";a="297676368" Received: from fmsmga004.fm.intel.com ([10.253.24.48]) by orsmga103.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 05 Sep 2022 03:59:06 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.93,291,1654585200"; d="scan'208";a="682023984" Received: from dpdk-jf-ntb-v2.sh.intel.com ([10.67.118.246]) by fmsmga004.fm.intel.com with ESMTP; 05 Sep 2022 03:59:04 -0700 From: Junfeng Guo To: qi.z.zhang@intel.com, jingjing.wu@intel.com, beilei.xing@intel.com Cc: dev@dpdk.org, xiao.w.wang@intel.com, junfeng.guo@intel.com, Wenjing Qiao Subject: [PATCH v2 14/14] net/idpf: add support for timestamp offload Date: Mon, 5 Sep 2022 18:58:28 +0800 Message-Id: <20220905105828.3190335-15-junfeng.guo@intel.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20220905105828.3190335-1-junfeng.guo@intel.com> References: <20220803113104.1184059-1-junfeng.guo@intel.com> <20220905105828.3190335-1-junfeng.guo@intel.com> MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-BeenThere: dev@dpdk.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: DPDK patches and discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: dev-bounces@dpdk.org Add support for timestamp offload. Signed-off-by: Wenjing Qiao Signed-off-by: Junfeng Guo --- drivers/net/idpf/idpf_ethdev.h | 3 ++ drivers/net/idpf/idpf_rxtx.c | 79 ++++++++++++++++++++++++++++++ drivers/net/idpf/idpf_rxtx.h | 89 +++++++++++++++++++++++++++++++++- 3 files changed, 170 insertions(+), 1 deletion(-) diff --git a/drivers/net/idpf/idpf_ethdev.h b/drivers/net/idpf/idpf_ethdev.h index a32d5758ac..968e0e3cbf 100644 --- a/drivers/net/idpf/idpf_ethdev.h +++ b/drivers/net/idpf/idpf_ethdev.h @@ -184,6 +184,9 @@ struct idpf_adapter { bool tx_vec_allowed; bool rx_use_avx512; bool tx_use_avx512; + + /* For PTP */ + uint64_t time_hw; }; TAILQ_HEAD(idpf_adapter_list, idpf_adapter); diff --git a/drivers/net/idpf/idpf_rxtx.c b/drivers/net/idpf/idpf_rxtx.c index e31d202646..b0037eca08 100644 --- a/drivers/net/idpf/idpf_rxtx.c +++ b/drivers/net/idpf/idpf_rxtx.c @@ -10,6 +10,8 @@ #include "idpf_rxtx.h" #include "idpf_rxtx_vec_common.h" +static int idpf_timestamp_dynfield_offset = -1; + const uint32_t * idpf_dev_supported_ptypes_get(struct rte_eth_dev *dev __rte_unused) { @@ -965,6 +967,24 @@ idpf_tx_queue_setup(struct rte_eth_dev *dev, uint16_t queue_idx, socket_id, tx_conf); } +static int +idpf_register_ts_mbuf(struct idpf_rx_queue *rxq) +{ + int err; + if (rxq->offloads & RTE_ETH_RX_OFFLOAD_TIMESTAMP) { + /* Register mbuf field and flag for Rx timestamp */ + err = rte_mbuf_dyn_rx_timestamp_register( + &idpf_timestamp_dynfield_offset, + &idpf_timestamp_dynflag); + if (err) { + PMD_DRV_LOG(ERR, + "Cannot register mbuf field/flag for timestamp"); + return -EINVAL; + } + } + return 0; +} + static int idpf_alloc_single_rxq_mbufs(struct idpf_rx_queue *rxq) { @@ -992,6 +1012,10 @@ idpf_alloc_single_rxq_mbufs(struct idpf_rx_queue *rxq) rxd = &((volatile struct virtchnl2_singleq_rx_buf_desc *)(rxq->rx_ring))[i]; rxd->pkt_addr = dma_addr; rxd->hdr_addr = 0; +#ifndef RTE_LIBRTE_IDPF_16BYTE_RX_DESC + rxd->rsvd1 = 0; + rxd->rsvd2 = 0; +#endif rxq->sw_ring[i] = mbuf; } @@ -1057,6 +1081,13 @@ idpf_rx_queue_init(struct rte_eth_dev *dev, uint16_t rx_queue_id) return -EINVAL; } + err = idpf_register_ts_mbuf(rxq); + if (err) { + PMD_DRV_LOG(ERR, "fail to regidter timestamp mbuf %u", + rx_queue_id); + return -EIO; + } + if (!rxq->bufq1) { /* Single queue */ err = idpf_alloc_single_rxq_mbufs(rxq); @@ -1441,6 +1472,12 @@ idpf_splitq_recv_pkts(void *rx_queue, struct rte_mbuf **rx_pkts, nb_rx = 0; rxq = (struct idpf_rx_queue *)rx_queue; +#ifndef RTE_LIBRTE_IDPF_16BYTE_RX_DESC + uint64_t ts_ns; + struct iecm_hw *hw = &rxq->adapter->hw; + struct idpf_adapter *ad = rxq->adapter; +#endif + if (unlikely(!rxq) || unlikely(!rxq->q_started)) return nb_rx; @@ -1451,6 +1488,11 @@ idpf_splitq_recv_pkts(void *rx_queue, struct rte_mbuf **rx_pkts, (volatile struct virtchnl2_rx_flex_desc_adv_nic_3 *)rxq->rx_ring; ptype_tbl = rxq->adapter->ptype_tbl; +#ifndef RTE_LIBRTE_IDPF_16BYTE_RX_DESC + if (rxq->offloads & RTE_ETH_RX_OFFLOAD_TIMESTAMP) + rxq->hw_register_set = 1; +#endif + while (nb_rx < nb_pkts) { rx_desc = &rx_desc_ring[rx_id]; @@ -1507,6 +1549,19 @@ idpf_splitq_recv_pkts(void *rx_queue, struct rte_mbuf **rx_pkts, status_err0_qw1 = rx_desc->status_err0_qw1; pkt_flags = idpf_splitq_rx_csum_offload(status_err0_qw1); pkt_flags |= idpf_splitq_rx_rss_offload(rxm, rx_desc); +#ifndef RTE_LIBRTE_IDPF_16BYTE_RX_DESC + if (idpf_timestamp_dynflag > 0) { + /* timestamp */ + ts_ns = idpf_tstamp_convert_32b_64b(hw, ad, + rxq->hw_register_set, + rte_le_to_cpu_32(rx_desc->ts_high)); + rxq->hw_register_set = 0; + *RTE_MBUF_DYNFIELD(rxm, + idpf_timestamp_dynfield_offset, + rte_mbuf_timestamp_t *) = ts_ns; + rxm->ol_flags |= idpf_timestamp_dynflag; + } +#endif rxm->ol_flags |= pkt_flags; rx_pkts[nb_rx++] = rxm; @@ -1778,6 +1833,10 @@ idpf_singleq_recv_pkts(void *rx_queue, struct rte_mbuf **rx_pkts, nb_hold = 0; rxq = rx_queue; +#ifndef RTE_LIBRTE_IDPF_16BYTE_RX_DESC + uint64_t ts_ns; +#endif + if (unlikely(!rxq) || unlikely(!rxq->q_started)) return nb_rx; @@ -1785,6 +1844,13 @@ idpf_singleq_recv_pkts(void *rx_queue, struct rte_mbuf **rx_pkts, rx_ring = rxq->rx_ring; ptype_tbl = rxq->adapter->ptype_tbl; +#ifndef RTE_LIBRTE_IDPF_16BYTE_RX_DESC + struct iecm_hw *hw = &rxq->adapter->hw; + struct idpf_adapter *ad = rxq->adapter; + if (rxq->offloads & RTE_ETH_RX_OFFLOAD_TIMESTAMP) + rxq->hw_register_set = 1; +#endif + while (nb_rx < nb_pkts) { rxdp = &rx_ring[rx_id]; rx_status0 = rte_le_to_cpu_16(rxdp->flex_nic_wb.status_error0); @@ -1841,6 +1907,19 @@ idpf_singleq_recv_pkts(void *rx_queue, struct rte_mbuf **rx_pkts, rxm->packet_type = ptype_tbl[(uint8_t)(rte_cpu_to_le_16(rxd.flex_nic_wb.ptype_flex_flags0) & VIRTCHNL2_RX_FLEX_DESC_PTYPE_M)]; +#ifndef RTE_LIBRTE_IDPF_16BYTE_RX_DESC + if (idpf_timestamp_dynflag > 0) { + /* timestamp */ + ts_ns = idpf_tstamp_convert_32b_64b(hw, ad, + rxq->hw_register_set, + rte_le_to_cpu_32(rxdp->flex_nic_wb.flex_ts.ts_high)); + rxq->hw_register_set = 0; + *RTE_MBUF_DYNFIELD(rxm, + idpf_timestamp_dynfield_offset, + rte_mbuf_timestamp_t *) = ts_ns; + rxm->ol_flags |= idpf_timestamp_dynflag; + } +#endif rx_pkts[nb_rx++] = rxm; } rxq->rx_tail = rx_id; diff --git a/drivers/net/idpf/idpf_rxtx.h b/drivers/net/idpf/idpf_rxtx.h index decd0a98c2..6fcb441143 100644 --- a/drivers/net/idpf/idpf_rxtx.h +++ b/drivers/net/idpf/idpf_rxtx.h @@ -15,6 +15,41 @@ #include "base/virtchnl2_lan_desc.h" #include "idpf_ethdev.h" +/* MTS */ +#define GLTSYN_CMD_SYNC_0_0 (PF_TIMESYNC_BASE + 0x0) +#define PF_GLTSYN_SHTIME_0_0 (PF_TIMESYNC_BASE + 0x4) +#define PF_GLTSYN_SHTIME_L_0 (PF_TIMESYNC_BASE + 0x8) +#define PF_GLTSYN_SHTIME_H_0 (PF_TIMESYNC_BASE + 0xC) +#define GLTSYN_ART_L_0 (PF_TIMESYNC_BASE + 0x10) +#define GLTSYN_ART_H_0 (PF_TIMESYNC_BASE + 0x14) +#define PF_GLTSYN_SHTIME_0_1 (PF_TIMESYNC_BASE + 0x24) +#define PF_GLTSYN_SHTIME_L_1 (PF_TIMESYNC_BASE + 0x28) +#define PF_GLTSYN_SHTIME_H_1 (PF_TIMESYNC_BASE + 0x2C) +#define PF_GLTSYN_SHTIME_0_2 (PF_TIMESYNC_BASE + 0x44) +#define PF_GLTSYN_SHTIME_L_2 (PF_TIMESYNC_BASE + 0x48) +#define PF_GLTSYN_SHTIME_H_2 (PF_TIMESYNC_BASE + 0x4C) +#define PF_GLTSYN_SHTIME_0_3 (PF_TIMESYNC_BASE + 0x64) +#define PF_GLTSYN_SHTIME_L_3 (PF_TIMESYNC_BASE + 0x68) +#define PF_GLTSYN_SHTIME_H_3 (PF_TIMESYNC_BASE + 0x6C) + +#define PF_TIMESYNC_BAR4_BASE 0x0E400000 +#define GLTSYN_ENA (PF_TIMESYNC_BAR4_BASE + 0x90) +#define GLTSYN_CMD (PF_TIMESYNC_BAR4_BASE + 0x94) +#define GLTSYC_TIME_L (PF_TIMESYNC_BAR4_BASE + 0x104) +#define GLTSYC_TIME_H (PF_TIMESYNC_BAR4_BASE + 0x108) + +#define GLTSYN_CMD_SYNC_0_4 (PF_TIMESYNC_BAR4_BASE + 0x110) +#define PF_GLTSYN_SHTIME_L_4 (PF_TIMESYNC_BAR4_BASE + 0x118) +#define PF_GLTSYN_SHTIME_H_4 (PF_TIMESYNC_BAR4_BASE + 0x11C) +#define GLTSYN_INCVAL_L (PF_TIMESYNC_BAR4_BASE + 0x150) +#define GLTSYN_INCVAL_H (PF_TIMESYNC_BAR4_BASE + 0x154) +#define GLTSYN_SHADJ_L (PF_TIMESYNC_BAR4_BASE + 0x158) +#define GLTSYN_SHADJ_H (PF_TIMESYNC_BAR4_BASE + 0x15C) + +#define GLTSYN_CMD_SYNC_0_5 (PF_TIMESYNC_BAR4_BASE + 0x130) +#define PF_GLTSYN_SHTIME_L_5 (PF_TIMESYNC_BAR4_BASE + 0x138) +#define PF_GLTSYN_SHTIME_H_5 (PF_TIMESYNC_BAR4_BASE + 0x13C) + /* In QLEN must be whole number of 32 descriptors. */ #define IDPF_ALIGN_RING_DESC 32 #define IDPF_MIN_RING_DESC 32 @@ -66,6 +101,8 @@ (sizeof(struct virtchnl2_ptype) + \ (((p)->proto_id_count ? ((p)->proto_id_count - 1) : 0) * sizeof((p)->proto_id[0]))) +extern uint64_t idpf_timestamp_dynflag; + struct idpf_rx_queue { struct idpf_adapter *adapter; /* the adapter this queue belongs to */ struct rte_mempool *mp; /* mbuf pool to populate Rx ring */ @@ -231,5 +268,55 @@ void idpf_set_tx_function(struct rte_eth_dev *dev); const uint32_t *idpf_dev_supported_ptypes_get(struct rte_eth_dev *dev); -#endif /* _IDPF_RXTX_H_ */ +#define IDPF_TIMESYNC_REG_WRAP_GUARD_BAND 10000 +/* Helper function to convert a 32b nanoseconds timestamp to 64b. */ +static inline uint64_t +idpf_tstamp_convert_32b_64b(struct iecm_hw *hw, struct idpf_adapter *ad, + uint32_t flag, uint32_t in_timestamp) +{ +/* TODO: timestamp for ACC */ +#ifdef RTE_ARCH_ARM64 + return 0; +#endif /* RTE_ARCH_ARM64 */ + +#ifdef RTE_ARCH_X86_64 + const uint64_t mask = 0xFFFFFFFF; + uint32_t hi, lo, lo2, delta; + uint64_t ns; + + if (flag) { + IECM_WRITE_REG(hw, GLTSYN_CMD_SYNC_0_0, PF_GLTSYN_CMD_SYNC_SHTIME_EN_M); + IECM_WRITE_REG(hw, GLTSYN_CMD_SYNC_0_0, PF_GLTSYN_CMD_SYNC_EXEC_CMD_M | + PF_GLTSYN_CMD_SYNC_SHTIME_EN_M); + lo = IECM_READ_REG(hw, PF_GLTSYN_SHTIME_L_0); + hi = IECM_READ_REG(hw, PF_GLTSYN_SHTIME_H_0); + /* + * On typical system, the delta between lo and lo2 is ~1000ns, + * so 10000 seems a large-enough but not overly-big guard band. + */ + if (lo > (UINT32_MAX - IDPF_TIMESYNC_REG_WRAP_GUARD_BAND)) + lo2 = IECM_READ_REG(hw, PF_GLTSYN_SHTIME_L_0); + else + lo2 = lo; + + if (lo2 < lo) { + lo = IECM_READ_REG(hw, PF_GLTSYN_SHTIME_L_0); + hi = IECM_READ_REG(hw, PF_GLTSYN_SHTIME_H_0); + } + + ad->time_hw = ((uint64_t)hi << 32) | lo; + } + + delta = (in_timestamp - (uint32_t)(ad->time_hw & mask)); + if (delta > (mask / 2)) { + delta = ((uint32_t)(ad->time_hw & mask) - in_timestamp); + ns = ad->time_hw - delta; + } else { + ns = ad->time_hw + delta; + } + + return ns; +#endif /* RTE_ARCH_X86_64 */ +} +#endif /* _IDPF_RXTX_H_ */ -- 2.25.1