From patchwork Mon Aug 15 07:31:37 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Qi Zhang X-Patchwork-Id: 115069 X-Patchwork-Delegate: qi.z.zhang@intel.com Return-Path: X-Original-To: patchwork@inbox.dpdk.org Delivered-To: patchwork@inbox.dpdk.org Received: from mails.dpdk.org (mails.dpdk.org [217.70.189.124]) by inbox.dpdk.org (Postfix) with ESMTP id C1D23A00C3; Mon, 15 Aug 2022 01:26:01 +0200 (CEST) Received: from [217.70.189.124] (localhost [127.0.0.1]) by mails.dpdk.org (Postfix) with ESMTP id 3C05142C71; Mon, 15 Aug 2022 01:23:27 +0200 (CEST) Received: from mga14.intel.com (mga14.intel.com [192.55.52.115]) by mails.dpdk.org (Postfix) with ESMTP id 977EB42CB2 for ; Mon, 15 Aug 2022 01:23:24 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1660519404; x=1692055404; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=v68MfeKfGXo/sMyUzpvUeYZKcXPbe3vzWW8WOnx7GBM=; b=IyeU//doloiypzITdP4SdamRdAndHE0zZogRphPpu5mVzDvyDGty39q1 r8GC1pk3rm+nX+Bc7W2s8DjR9c0H2f0t+588EwSUvH4yTKGPMsZRLHJog LeXi9u3BFptryXCCM0NXZ1UfL0RHIVTemPFSdj5sRpwEptOAIyOB5/Zeu QwTzlRPy3OOC6PifhlIoAk2GfLUETvP6WnSEWS2eN7ftnhVainkuNf/rn 6+1oxTNcmrPk+Mh/MJGAGRP9BPVS5zqswT//yXFLdqZQHMQHrCN39JuOW czRhEhe7pxgBkIcMXkH6Jiru7h/LXEM8Azg+C5JXCcnK1wWaz3c3ipBEJ w==; X-IronPort-AV: E=McAfee;i="6400,9594,10439"; a="291857987" X-IronPort-AV: E=Sophos;i="5.93,237,1654585200"; d="scan'208";a="291857987" Received: from orsmga008.jf.intel.com ([10.7.209.65]) by fmsmga103.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 14 Aug 2022 16:23:24 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.93,237,1654585200"; d="scan'208";a="635283220" Received: from dpdk-qzhan15-test02.sh.intel.com ([10.67.115.4]) by orsmga008.jf.intel.com with ESMTP; 14 Aug 2022 16:23:22 -0700 From: Qi Zhang To: qiming.yang@intel.com Cc: dev@dpdk.org, Qi Zhang , Karol Kolacinski Subject: [PATCH v2 41/70] net/ice/base: add low latency Tx timestamp read Date: Mon, 15 Aug 2022 03:31:37 -0400 Message-Id: <20220815073206.2917968-42-qi.z.zhang@intel.com> X-Mailer: git-send-email 2.31.1 In-Reply-To: <20220815073206.2917968-1-qi.z.zhang@intel.com> References: <20220815071306.2910599-1-qi.z.zhang@intel.com> <20220815073206.2917968-1-qi.z.zhang@intel.com> MIME-Version: 1.0 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 E810 products can support low latency Tx timestamp register read. Add a check for the device capability and use the new method if supported. Signed-off-by: Karol Kolacinski Signed-off-by: Qi Zhang --- drivers/net/ice/base/ice_common.c | 7 ++- drivers/net/ice/base/ice_ptp_hw.c | 95 +++++++++++++++++++++++++++---- drivers/net/ice/base/ice_ptp_hw.h | 12 +++- drivers/net/ice/base/ice_type.h | 2 + 4 files changed, 101 insertions(+), 15 deletions(-) diff --git a/drivers/net/ice/base/ice_common.c b/drivers/net/ice/base/ice_common.c index c90ae20c43..2014f8361d 100644 --- a/drivers/net/ice/base/ice_common.c +++ b/drivers/net/ice/base/ice_common.c @@ -2757,7 +2757,8 @@ ice_parse_1588_dev_caps(struct ice_hw *hw, struct ice_hw_dev_caps *dev_p, info->tmr1_owned = ((number & ICE_TS_TMR1_OWND_M) != 0); info->tmr1_ena = ((number & ICE_TS_TMR1_ENA_M) != 0); - info->ena_ports = logical_id; + info->ts_ll_read = ((number & ICE_TS_LL_TX_TS_READ_M) != 0); + info->tmr_own_map = phys_id; ice_debug(hw, ICE_DBG_INIT, "dev caps: ieee_1588 = %u\n", @@ -2774,8 +2775,8 @@ ice_parse_1588_dev_caps(struct ice_hw *hw, struct ice_hw_dev_caps *dev_p, info->tmr1_owned); ice_debug(hw, ICE_DBG_INIT, "dev caps: tmr1_ena = %u\n", info->tmr1_ena); - ice_debug(hw, ICE_DBG_INIT, "dev caps: ieee_1588 ena_ports = %u\n", - info->ena_ports); + ice_debug(hw, ICE_DBG_INIT, "dev caps: ts_ll_read = %u\n", + info->ts_ll_read); ice_debug(hw, ICE_DBG_INIT, "dev caps: tmr_own_map = %u\n", info->tmr_own_map); } diff --git a/drivers/net/ice/base/ice_ptp_hw.c b/drivers/net/ice/base/ice_ptp_hw.c index 7ed420be8e..712b7dedfb 100644 --- a/drivers/net/ice/base/ice_ptp_hw.c +++ b/drivers/net/ice/base/ice_ptp_hw.c @@ -4142,38 +4142,111 @@ ice_write_phy_reg_e810(struct ice_hw *hw, u32 addr, u32 val) } /** - * ice_read_phy_tstamp_e810 - Read a PHY timestamp out of the external PHY + * ice_read_phy_tstamp_ll_e810 - Read a PHY timestamp registers through the FW + * @hw: pointer to the HW struct + * @idx: the timestamp index to read + * @hi: 8 bit timestamp high value + * @lo: 32 bit timestamp low value + * + * Read a 8bit timestamp high value and 32 bit timestamp low value out of the + * timestamp block of the external PHY on the E810 device using the low latency + * timestamp read. + */ +static enum ice_status +ice_read_phy_tstamp_ll_e810(struct ice_hw *hw, u8 idx, u8 *hi, u32 *lo) +{ + u8 i; + + /* Write TS index to read to the PF register so the FW can read it */ + wr32(hw, PF_SB_ATQBAL, TS_LL_READ_TS_IDX(idx)); + + /* Read the register repeatedly until the FW provides us the TS */ + for (i = TS_LL_READ_RETRIES; i > 0; i--) { + u32 val = rd32(hw, PF_SB_ATQBAL); + + /* When the bit is cleared, the TS is ready in the register */ + if (!(val & TS_LL_READ_TS)) { + /* High 8 bit value of the TS is on the bits 16:23 */ + *hi = (u8)(val >> TS_LL_READ_TS_HIGH_S); + + /* Read the low 32 bit value and set the TS valid bit */ + *lo = rd32(hw, PF_SB_ATQBAH) | TS_VALID; + return ICE_SUCCESS; + } + + ice_usec_delay(10, false); + } + + /* FW failed to provide the TS in time */ + ice_debug(hw, ICE_DBG_PTP, "Failed to read PTP timestamp using low latency read\n"); + return ICE_ERR_NOT_READY; +} + +/** + * ice_read_phy_tstamp_sbq_e810 - Read a PHY timestamp registers through the sbq * @hw: pointer to the HW struct * @lport: the lport to read from * @idx: the timestamp index to read - * @tstamp: on return, the 40bit timestamp value + * @hi: 8 bit timestamp high value + * @lo: 32 bit timestamp low value * - * Read a 40bit timestamp value out of the timestamp block of the external PHY - * on the E810 device. + * Read a 8bit timestamp high value and 32 bit timestamp low value out of the + * timestamp block of the external PHY on the E810 device using sideband queue. */ static enum ice_status -ice_read_phy_tstamp_e810(struct ice_hw *hw, u8 lport, u8 idx, u64 *tstamp) +ice_read_phy_tstamp_sbq_e810(struct ice_hw *hw, u8 lport, u8 idx, u8 *hi, + u32 *lo) { + u32 hi_addr = TS_EXT(HIGH_TX_MEMORY_BANK_START, lport, idx); + u32 lo_addr = TS_EXT(LOW_TX_MEMORY_BANK_START, lport, idx); enum ice_status status; - u32 lo_addr, hi_addr, lo, hi; - - lo_addr = TS_EXT(LOW_TX_MEMORY_BANK_START, lport, idx); - hi_addr = TS_EXT(HIGH_TX_MEMORY_BANK_START, lport, idx); + u32 lo_val, hi_val; - status = ice_read_phy_reg_e810(hw, lo_addr, &lo); + status = ice_read_phy_reg_e810(hw, lo_addr, &lo_val); if (status) { ice_debug(hw, ICE_DBG_PTP, "Failed to read low PTP timestamp register, status %d\n", status); return status; } - status = ice_read_phy_reg_e810(hw, hi_addr, &hi); + status = ice_read_phy_reg_e810(hw, hi_addr, &hi_val); if (status) { ice_debug(hw, ICE_DBG_PTP, "Failed to read high PTP timestamp register, status %d\n", status); return status; } + *lo = lo_val; + *hi = (u8)hi_val; + + return ICE_SUCCESS; +} + +/** + * ice_read_phy_tstamp_e810 - Read a PHY timestamp out of the external PHY + * @hw: pointer to the HW struct + * @lport: the lport to read from + * @idx: the timestamp index to read + * @tstamp: on return, the 40bit timestamp value + * + * Read a 40bit timestamp value out of the timestamp block of the external PHY + * on the E810 device. + */ +static enum ice_status +ice_read_phy_tstamp_e810(struct ice_hw *hw, u8 lport, u8 idx, u64 *tstamp) +{ + enum ice_status status; + u32 lo = 0; + u8 hi = 0; + + if (hw->dev_caps.ts_dev_info.ts_ll_read) + status = ice_read_phy_tstamp_ll_e810(hw, idx, &hi, &lo); + else + status = ice_read_phy_tstamp_sbq_e810(hw, lport, idx, &hi, &lo); + + if (status) + return status; + /* For E810 devices, the timestamp is reported with the lower 32 bits * in the low register, and the upper 8 bits in the high register. */ diff --git a/drivers/net/ice/base/ice_ptp_hw.h b/drivers/net/ice/base/ice_ptp_hw.h index 1e016ef177..9fa17787df 100644 --- a/drivers/net/ice/base/ice_ptp_hw.h +++ b/drivers/net/ice/base/ice_ptp_hw.h @@ -476,8 +476,8 @@ enum ice_status ice_ptp_init_phy_cfg(struct ice_hw *hw); #define INCVAL_HIGH_M 0xFF /* Timestamp block macros */ +#define TS_VALID BIT(0) #define TS_LOW_M 0xFFFFFFFF -#define TS_HIGH_M 0xFF #define TS_HIGH_S 32 #define TS_PHY_LOW_M 0xFF @@ -487,6 +487,16 @@ enum ice_status ice_ptp_init_phy_cfg(struct ice_hw *hw); #define BYTES_PER_IDX_ADDR_L_U 8 #define BYTES_PER_IDX_ADDR_L 4 +/* Tx timestamp low latency read definitions */ +#define TS_LL_READ_RETRIES 200 +#define TS_LL_READ_TS BIT(31) +#define TS_LL_READ_TS_IDX_S 24 +#define TS_LL_READ_TS_IDX_M MAKEMASK(0x3F, 0) +#define TS_LL_READ_TS_IDX(__idx) (TS_LL_READ_TS | \ + (((__idx) & TS_LL_READ_TS_IDX_M) << \ + TS_LL_READ_TS_IDX_S)) +#define TS_LL_READ_TS_HIGH_S 16 + /* Internal PHY timestamp address */ #define TS_L(a, idx) ((a) + ((idx) * BYTES_PER_IDX_ADDR_L_U)) #define TS_H(a, idx) ((a) + ((idx) * BYTES_PER_IDX_ADDR_L_U + \ diff --git a/drivers/net/ice/base/ice_type.h b/drivers/net/ice/base/ice_type.h index 5c7cc06e0c..cdfef47e94 100644 --- a/drivers/net/ice/base/ice_type.h +++ b/drivers/net/ice/base/ice_type.h @@ -651,6 +651,7 @@ struct ice_ts_func_info { #define ICE_TS_DEV_ENA_M BIT(24) #define ICE_TS_TMR0_ENA_M BIT(25) #define ICE_TS_TMR1_ENA_M BIT(26) +#define ICE_TS_LL_TX_TS_READ_M BIT(28) struct ice_ts_dev_info { /* Device specific info */ @@ -663,6 +664,7 @@ struct ice_ts_dev_info { u8 ena; u8 tmr0_ena; u8 tmr1_ena; + u8 ts_ll_read; }; /* Function specific capabilities */