From patchwork Tue Aug 10 02:51:23 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Qi Zhang X-Patchwork-Id: 96750 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 5BAE4A0C54; Tue, 10 Aug 2021 04:49:49 +0200 (CEST) Received: from [217.70.189.124] (localhost [127.0.0.1]) by mails.dpdk.org (Postfix) with ESMTP id 51AD741170; Tue, 10 Aug 2021 04:49:02 +0200 (CEST) Received: from mga09.intel.com (mga09.intel.com [134.134.136.24]) by mails.dpdk.org (Postfix) with ESMTP id 19D96411BA for ; Tue, 10 Aug 2021 04:48:59 +0200 (CEST) X-IronPort-AV: E=McAfee;i="6200,9189,10070"; a="214808457" X-IronPort-AV: E=Sophos;i="5.84,309,1620716400"; d="scan'208";a="214808457" Received: from fmsmga008.fm.intel.com ([10.253.24.58]) by orsmga102.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 09 Aug 2021 19:48:59 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.84,309,1620716400"; d="scan'208";a="483823647" Received: from dpdk51.sh.intel.com ([10.67.111.142]) by fmsmga008.fm.intel.com with ESMTP; 09 Aug 2021 19:48:57 -0700 From: Qi Zhang To: qiming.yang@intel.com Cc: junfeng.guo@intel.com, dev@dpdk.org, Qi Zhang , Jacob Keller Date: Tue, 10 Aug 2021 10:51:23 +0800 Message-Id: <20210810025140.1698163-12-qi.z.zhang@intel.com> X-Mailer: git-send-email 2.26.2 In-Reply-To: <20210810025140.1698163-1-qi.z.zhang@intel.com> References: <20210810025140.1698163-1-qi.z.zhang@intel.com> MIME-Version: 1.0 Subject: [dpdk-dev] [PATCH 11/28] net/ice/base: add support for starting PHY in bypass mode 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 Sender: "dev" After starting the timestamping block, hardware begins calculating precise offsets through a process of vernier calibration. This process measures the effective phase offset of the various internal clocks used in the PHY. Once hardware completes these measurements, the P_REG_TX_OV_STATUS and P_REG_RX_OV_STATUS registers are updated to indicate that the hardware offset measurements are done. This process does not happen immediately, but requires that at least one packet be sent or received in order for the offset in that direction to be calculated. This poses a problem in some setups, because software expects the first packet sent to be timestamped. This most often occurs if the clock time is set by an application during startup. This set time command triggers a PHY restart. Because of this, the timestamping block is reset, and timestamps are not enabled until vernier calibration is complete. Since this process won't complete until at least one packet is sent through the PHY, timestamps of the very first packet sent will not be obtained. This can result in the application failing due to missing timestamps. To avoid this, allow starting the PHY in bypass mode. This mode enables timestamps immediately, and skips adding the precise offset measurement. This reduces the accuracy of the timestamp slightly, but ensures that we get a reasonable value for the first packet. The driver can continue monitoring the P_REG_TX_OV_STATUS and P_REG_RX_OV_STATUS registers and exit bypass mode once the total calibration is completed. In this way, once calibration is complete, the timestamps will have the precise offset, but we do not break applications which expect to be able to timestamp immediately. Signed-off-by: Jacob Keller Signed-off-by: Qi Zhang Acked-by: Junfeng Guo --- drivers/net/ice/base/ice_ptp_hw.c | 84 +++++++++++++++++++++++++++++++ drivers/net/ice/base/ice_ptp_hw.h | 1 + 2 files changed, 85 insertions(+) diff --git a/drivers/net/ice/base/ice_ptp_hw.c b/drivers/net/ice/base/ice_ptp_hw.c index bf6889029a..8ea75538fa 100644 --- a/drivers/net/ice/base/ice_ptp_hw.c +++ b/drivers/net/ice/base/ice_ptp_hw.c @@ -2572,6 +2572,90 @@ ice_start_phy_timer_e822(struct ice_hw *hw, u8 port, bool bypass) return ICE_SUCCESS; } +/** + * ice_phy_exit_bypass_e822 - Exit bypass mode, after vernier calculations + * @hw: pointer to the HW struct + * @port: the PHY port to configure + * + * After hardware finishes vernier calculations for the Tx and Rx offset, this + * function can be used to exit bypass mode by updating the total Tx and Rx + * offsets, and then disabling bypass. This will enable hardware to include + * the more precise offset calibrations, increasing precision of the generated + * timestamps. + * + * This cannot be done until hardware has measured the offsets, which requires + * waiting until at least one packet has been sent and received by the device. + */ +enum ice_status ice_phy_exit_bypass_e822(struct ice_hw *hw, u8 port) +{ + enum ice_status status; + u32 val; + + status = ice_read_phy_reg_e822(hw, port, P_REG_TX_OV_STATUS, &val); + if (status) { + ice_debug(hw, ICE_DBG_PTP, "Failed to read TX_OV_STATUS for port %u, status %d\n", + port, status); + return status; + } + + if (!(val & P_REG_TX_OV_STATUS_OV_M)) { + ice_debug(hw, ICE_DBG_PTP, "Tx offset is not yet valid for port %u\n", + port); + return ICE_ERR_NOT_READY; + } + + status = ice_read_phy_reg_e822(hw, port, P_REG_RX_OV_STATUS, &val); + if (status) { + ice_debug(hw, ICE_DBG_PTP, "Failed to read RX_OV_STATUS for port %u, status %d\n", + port, status); + return status; + } + + if (!(val & P_REG_TX_OV_STATUS_OV_M)) { + ice_debug(hw, ICE_DBG_PTP, "Rx offset is not yet valid for port %u\n", + port); + return ICE_ERR_NOT_READY; + } + + status = ice_phy_cfg_tx_offset_e822(hw, port); + if (status) { + ice_debug(hw, ICE_DBG_PTP, "Failed to program total Tx offset for port %u, status %d\n", + port, status); + return status; + } + + status = ice_phy_cfg_rx_offset_e822(hw, port); + if (status) { + ice_debug(hw, ICE_DBG_PTP, "Failed to program total Rx offset for port %u, status %d\n", + port, status); + return status; + } + + /* Exit bypass mode now that the offset has been updated */ + status = ice_read_phy_reg_e822(hw, port, P_REG_PS, &val); + if (status) { + ice_debug(hw, ICE_DBG_PTP, "Failed to read P_REG_PS for port %u, status %d\n", + port, status); + return status; + } + + if (!(val & P_REG_PS_BYPASS_MODE_M)) + ice_debug(hw, ICE_DBG_PTP, "Port %u not in bypass mode\n", + port); + + val &= ~P_REG_PS_BYPASS_MODE_M; + status = ice_write_phy_reg_e822(hw, port, P_REG_PS, val); + if (status) { + ice_debug(hw, ICE_DBG_PTP, "Failed to disable bypass for port %u, status %d\n", + port, status); + return status; + } + + ice_info(hw, "Exiting bypass mode on PHY port %u\n", port); + + return ICE_SUCCESS; +} + /* E810 functions * * The following functions operate on the E810 series devices which use diff --git a/drivers/net/ice/base/ice_ptp_hw.h b/drivers/net/ice/base/ice_ptp_hw.h index f2d87ca1e6..c804085095 100644 --- a/drivers/net/ice/base/ice_ptp_hw.h +++ b/drivers/net/ice/base/ice_ptp_hw.h @@ -218,6 +218,7 @@ enum ice_status ice_start_phy_timer_e822(struct ice_hw *hw, u8 port, bool bypass); enum ice_status ice_phy_cfg_tx_offset_e822(struct ice_hw *hw, u8 port); enum ice_status ice_phy_cfg_rx_offset_e822(struct ice_hw *hw, u8 port); +enum ice_status ice_phy_exit_bypass_e822(struct ice_hw *hw, u8 port); /* E810 family functions */ enum ice_status ice_ptp_init_phy_e810(struct ice_hw *hw);