From patchwork Thu Apr 27 06:19:54 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Qiming Yang X-Patchwork-Id: 126590 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 85AA542A08; Thu, 27 Apr 2023 08:40:28 +0200 (CEST) Received: from mails.dpdk.org (localhost [127.0.0.1]) by mails.dpdk.org (Postfix) with ESMTP id 2DCCC42FD8; Thu, 27 Apr 2023 08:38:28 +0200 (CEST) Received: from mga01.intel.com (mga01.intel.com [192.55.52.88]) by mails.dpdk.org (Postfix) with ESMTP id 878C742FDE for ; Thu, 27 Apr 2023 08:38:26 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1682577506; x=1714113506; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=vZ9ro9fQXZYR2KiMMVikLsShm4W8AQDL0FQ/tzd0psU=; b=HZayea0csAvFhtCRupgYT2WsNdLVmQXTgQbXdz+WIE88Yp1wPcxnoCwA OqtngIhjrktqw335TmXGFn1pke1HTVD/aMYhTb8cxPs6pQb5eXe4wR+z8 XtC/4mRC5Rb0UXxzYoSOtxghRXuHBMskHWbZfVqjAptclF2L8hJLJTEUS wlFbcGipGS0SWG/UfpLZFYD71MMBzH0NcYoxQ52am0MEP0EvONcnwfgmn XVkPeyvy7HGJMQqE6nBmnHHCBsVt9dKv4+eF1wW5iRTDC6WvhiRGeil+U ODKQcsgJMh3G1EbDcjBw+8d4TQg/Wt/x7oGjfvSHdgxw0zUaAGEYO0MLC g==; X-IronPort-AV: E=McAfee;i="6600,9927,10692"; a="375324388" X-IronPort-AV: E=Sophos;i="5.99,230,1677571200"; d="scan'208";a="375324388" Received: from fmsmga002.fm.intel.com ([10.253.24.26]) by fmsmga101.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 26 Apr 2023 23:38:26 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=McAfee;i="6600,9927,10692"; a="805845867" X-IronPort-AV: E=Sophos;i="5.99,230,1677571200"; d="scan'208";a="805845867" Received: from dpdk-qiming3.sh.intel.com ([10.67.111.4]) by fmsmga002.fm.intel.com with ESMTP; 26 Apr 2023 23:38:23 -0700 From: Qiming Yang To: dev@dpdk.org Cc: qi.z.zhang@intel.com, Qiming Yang , Milena Olech Subject: [PATCH 23/30] net/ice/base: change method to get pca9575 handle Date: Thu, 27 Apr 2023 06:19:54 +0000 Message-Id: <20230427062001.478032-24-qiming.yang@intel.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20230427062001.478032-1-qiming.yang@intel.com> References: <20230427062001.478032-1-qiming.yang@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 More universal method for getting pca9575 handle is introduced. The first step is to look for CLK_MUX handle. Having that it is possible to find CLK_MUX GPIO pin. Provided data let check what is driving the pin - the expectation is that pca9575 node part number is returned. Signed-off-by: Milena Olech Signed-off-by: Qiming Yang --- drivers/net/ice/base/ice_adminq_cmd.h | 12 ++- drivers/net/ice/base/ice_ptp_hw.c | 125 ++++++++++++++++++++++---- 2 files changed, 120 insertions(+), 17 deletions(-) diff --git a/drivers/net/ice/base/ice_adminq_cmd.h b/drivers/net/ice/base/ice_adminq_cmd.h index c51054ecc1..29b123d900 100644 --- a/drivers/net/ice/base/ice_adminq_cmd.h +++ b/drivers/net/ice/base/ice_adminq_cmd.h @@ -1723,6 +1723,8 @@ struct ice_aqc_link_topo_params { #define ICE_AQC_LINK_TOPO_NODE_TYPE_CAGE 6 #define ICE_AQC_LINK_TOPO_NODE_TYPE_MEZZ 7 #define ICE_AQC_LINK_TOPO_NODE_TYPE_ID_EEPROM 8 +#define ICE_AQC_LINK_TOPO_NODE_TYPE_CLK_CTRL 9 +#define ICE_AQC_LINK_TOPO_NODE_TYPE_CLK_MUX 10 #define ICE_AQC_LINK_TOPO_NODE_TYPE_GPS 11 #define ICE_AQC_LINK_TOPO_NODE_CTX_S 4 #define ICE_AQC_LINK_TOPO_NODE_CTX_M \ @@ -1760,8 +1762,13 @@ struct ice_aqc_link_topo_addr { struct ice_aqc_get_link_topo { struct ice_aqc_link_topo_addr addr; u8 node_part_num; -#define ICE_ACQ_GET_LINK_TOPO_NODE_NR_PCA9575 0x21 -#define ICE_ACQ_GET_LINK_TOPO_NODE_NR_GEN_GPS 0x48 +#define ICE_ACQ_GET_LINK_TOPO_NODE_NR_PCA9575 0x21 +#define ICE_ACQ_GET_LINK_TOPO_NODE_NR_ZL30632_80032 0x24 +#define ICE_ACQ_GET_LINK_TOPO_NODE_NR_SI5383_5384 0x25 +#define ICE_ACQ_GET_LINK_TOPO_NODE_NR_E822_PHY 0x30 +#define ICE_ACQ_GET_LINK_TOPO_NODE_NR_C827 0x31 +#define ICE_ACQ_GET_LINK_TOPO_NODE_NR_GEN_CLK_MUX 0x47 +#define ICE_ACQ_GET_LINK_TOPO_NODE_NR_GEN_GPS 0x48 u8 rsvd[9]; }; @@ -1789,6 +1796,7 @@ struct ice_aqc_get_link_topo_pin { #define ICE_AQC_LINK_TOPO_IO_FUNC_RED_LED 12 #define ICE_AQC_LINK_TOPO_IO_FUNC_GREEN_LED 13 #define ICE_AQC_LINK_TOPO_IO_FUNC_BLUE_LED 14 +#define ICE_AQC_LINK_TOPO_IO_FUNC_CLK_IN 20 #define ICE_AQC_LINK_TOPO_INPUT_IO_TYPE_S 5 #define ICE_AQC_LINK_TOPO_INPUT_IO_TYPE_M \ (0x7 << ICE_AQC_LINK_TOPO_INPUT_IO_TYPE_S) diff --git a/drivers/net/ice/base/ice_ptp_hw.c b/drivers/net/ice/base/ice_ptp_hw.c index cc6c1f3152..29840b2b91 100644 --- a/drivers/net/ice/base/ice_ptp_hw.c +++ b/drivers/net/ice/base/ice_ptp_hw.c @@ -1962,14 +1962,19 @@ ice_calc_fixed_tx_offset_e822(struct ice_hw *hw, enum ice_ptp_link_spd link_spd) * adjust Tx timestamps by. This is calculated by combining some known static * latency along with the Vernier offset computations done by hardware. * - * This function must be called only after the offset registers are valid, - * i.e. after the Vernier calibration wait has passed, to ensure that the PHY - * has measured the offset. + * This function will not return successfully until the Tx offset calculations + * have been completed, which requires waiting until at least one packet has + * been transmitted by the device. It is safe to call this function + * periodically until calibration succeeds, as it will only program the offset + * once. * * To avoid overflow, when calculating the offset based on the known static * latency values, we use measurements in 1/100th of a nanosecond, and divide * the TUs per second up front. This avoids overflow while allowing * calculation of the adjustment using integer arithmetic. + * + * Returns zero on success, ICE_ERR_NOT_READY if the hardware vernier offset + * calibration has not completed, or another error code on failure. */ enum ice_status ice_phy_cfg_tx_offset_e822(struct ice_hw *hw, u8 port) { @@ -1977,6 +1982,28 @@ enum ice_status ice_phy_cfg_tx_offset_e822(struct ice_hw *hw, u8 port) enum ice_ptp_fec_mode fec_mode; enum ice_status status; u64 total_offset, val; + u32 reg; + + /* Nothing to do if we've already programmed the offset */ + status = ice_read_phy_reg_e822(hw, port, P_REG_TX_OR, ®); + if (status) { + ice_debug(hw, ICE_DBG_PTP, "Failed to read TX_OR for port %u, status %d\n", + port, status); + return status; + } + + if (reg) + return ICE_SUCCESS; + + status = ice_read_phy_reg_e822(hw, port, P_REG_TX_OV_STATUS, ®); + 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 (!(reg & P_REG_TX_OV_STATUS_OV_M)) + return ICE_ERR_NOT_READY; status = ice_phy_get_speed_and_fec_e822(hw, port, &link_spd, &fec_mode); if (status) @@ -2030,6 +2057,7 @@ enum ice_status ice_phy_cfg_tx_offset_e822(struct ice_hw *hw, u8 port) if (status) return status; + ice_info(hw, "Port=%d Tx vernier offset calibration complete\n", port); return ICE_SUCCESS; } @@ -2236,6 +2264,11 @@ ice_calc_fixed_rx_offset_e822(struct ice_hw *hw, enum ice_ptp_link_spd link_spd) * measurements taken in hardware with some data about known fixed delay as * well as adjusting for multi-lane alignment delay. * + * This function will not return successfully until the Rx offset calculations + * have been completed, which requires waiting until at least one packet has + * been received by the device. It is safe to call this function periodically + * until calibration succeeds, as it will only program the offset once. + * * This function must be called only after the offset registers are valid, * i.e. after the Vernier calibration wait has passed, to ensure that the PHY * has measured the offset. @@ -2244,6 +2277,9 @@ ice_calc_fixed_rx_offset_e822(struct ice_hw *hw, enum ice_ptp_link_spd link_spd) * latency values, we use measurements in 1/100th of a nanosecond, and divide * the TUs per second up front. This avoids overflow while allowing * calculation of the adjustment using integer arithmetic. + * + * Returns zero on success, ICE_ERR_NOT_READY if the hardware vernier offset + * calibration has not completed, or another error code on failure. */ enum ice_status ice_phy_cfg_rx_offset_e822(struct ice_hw *hw, u8 port) { @@ -2251,6 +2287,28 @@ enum ice_status ice_phy_cfg_rx_offset_e822(struct ice_hw *hw, u8 port) enum ice_ptp_fec_mode fec_mode; u64 total_offset, pmd, val; enum ice_status status; + u32 reg; + + /* Nothing to do if we've already programmed the offset */ + status = ice_read_phy_reg_e822(hw, port, P_REG_RX_OR, ®); + if (status) { + ice_debug(hw, ICE_DBG_PTP, "Failed to read RX_OR for port %u, status %d\n", + port, status); + return status; + } + + if (reg) + return ICE_SUCCESS; + + status = ice_read_phy_reg_e822(hw, port, P_REG_RX_OV_STATUS, ®); + 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 (!(reg & P_REG_RX_OV_STATUS_OV_M)) + return ICE_ERR_NOT_READY; status = ice_phy_get_speed_and_fec_e822(hw, port, &link_spd, &fec_mode); if (status) @@ -2311,10 +2369,11 @@ enum ice_status ice_phy_cfg_rx_offset_e822(struct ice_hw *hw, u8 port) if (status) return status; + ice_info(hw, "Port=%d Rx vernier offset calibration complete\n", port); + return ICE_SUCCESS; } - /** * ice_ptp_clear_phy_offset_ready_e822 - Clear PHY TX_/RX_OFFSET_READY registers * @hw: pointer to the HW struct @@ -2424,7 +2483,8 @@ static enum ice_status ice_sync_phy_timer_e822(struct ice_hw *hw, u8 port) return ICE_ERR_NOT_READY; } - status = ice_read_phy_and_phc_time_e822(hw, port, &phy_time, &phc_time); + status = ice_read_phy_and_phc_time_e822(hw, port, &phy_time, + &phc_time); if (status) goto err_unlock; @@ -3175,17 +3235,18 @@ ice_get_phy_tx_tstamp_ready_e810(struct ice_hw *hw, u8 port, u64 *tstamp_ready) * @hw: pointer to the hw struct * @pca9575_handle: GPIO controller's handle * - * Find and return the GPIO controller's handle in the netlist. - * When found - the value will be cached in the hw structure and following calls - * will return cached value + * Find and return the GPIO controller's handle by checking what drives clock + * mux pin. When found - the value will be cached in the hw structure and + * following calls will return cached value. */ static enum ice_status ice_get_pca9575_handle(struct ice_hw *hw, u16 *pca9575_handle) { + u8 node_part_number, idx, node_type_ctx_clk_mux, node_part_num_clk_mux; + struct ice_aqc_get_link_topo_pin cmd_pin; + u16 node_handle, clock_mux_handle; struct ice_aqc_get_link_topo cmd; - u8 node_part_number, idx; enum ice_status status; - u16 node_handle; if (!hw || !pca9575_handle) return ICE_ERR_PARAM; @@ -3197,11 +3258,46 @@ ice_get_pca9575_handle(struct ice_hw *hw, u16 *pca9575_handle) } memset(&cmd, 0, sizeof(cmd)); + memset(&cmd_pin, 0, sizeof(cmd_pin)); + + node_type_ctx_clk_mux = (ICE_AQC_LINK_TOPO_NODE_TYPE_CLK_MUX << + ICE_AQC_LINK_TOPO_NODE_TYPE_S); + node_type_ctx_clk_mux |= (ICE_AQC_LINK_TOPO_NODE_CTX_GLOBAL << + ICE_AQC_LINK_TOPO_NODE_CTX_S); + node_part_num_clk_mux = ICE_ACQ_GET_LINK_TOPO_NODE_NR_GEN_CLK_MUX; - /* Set node type to GPIO controller */ + /* Look for CLOCK MUX handle in the netlist */ + status = ice_find_netlist_node(hw, node_type_ctx_clk_mux, + node_part_num_clk_mux, + &clock_mux_handle); + if (status) + return ICE_ERR_NOT_SUPPORTED; + + /* Take CLOCK MUX GPIO pin */ + cmd_pin.input_io_params = (ICE_AQC_LINK_TOPO_INPUT_IO_TYPE_GPIO << + ICE_AQC_LINK_TOPO_INPUT_IO_TYPE_S); + cmd_pin.input_io_params |= (ICE_AQC_LINK_TOPO_IO_FUNC_CLK_IN << + ICE_AQC_LINK_TOPO_INPUT_IO_FUNC_S); + cmd_pin.addr.handle = CPU_TO_LE16(clock_mux_handle); + cmd_pin.addr.topo_params.node_type_ctx = + (ICE_AQC_LINK_TOPO_NODE_TYPE_CLK_MUX << + ICE_AQC_LINK_TOPO_NODE_TYPE_S); + cmd_pin.addr.topo_params.node_type_ctx |= + (ICE_AQC_LINK_TOPO_NODE_CTX_PROVIDED << + ICE_AQC_LINK_TOPO_NODE_CTX_S); + + status = ice_aq_get_netlist_node_pin(hw, &cmd_pin, &node_handle); + if (status) + return ICE_ERR_NOT_SUPPORTED; + + /* Check what is driving the pin */ cmd.addr.topo_params.node_type_ctx = - (ICE_AQC_LINK_TOPO_NODE_TYPE_M & - ICE_AQC_LINK_TOPO_NODE_TYPE_GPIO_CTRL); + (ICE_AQC_LINK_TOPO_NODE_TYPE_GPIO_CTRL << + ICE_AQC_LINK_TOPO_NODE_TYPE_S); + cmd.addr.topo_params.node_type_ctx |= + (ICE_AQC_LINK_TOPO_NODE_CTX_GLOBAL << + ICE_AQC_LINK_TOPO_NODE_CTX_S); + cmd.addr.handle = CPU_TO_LE16(node_handle); #define SW_PCA9575_SFP_TOPO_IDX 2 #define SW_PCA9575_QSFP_TOPO_IDX 1 @@ -3215,13 +3311,12 @@ ice_get_pca9575_handle(struct ice_hw *hw, u16 *pca9575_handle) return ICE_ERR_NOT_SUPPORTED; cmd.addr.topo_params.index = idx; - status = ice_aq_get_netlist_node(hw, &cmd, &node_part_number, &node_handle); if (status) return ICE_ERR_NOT_SUPPORTED; - /* Verify if we found the right IO expander type */ + /* Verify if PCA9575 drives the pin */ if (node_part_number != ICE_ACQ_GET_LINK_TOPO_NODE_NR_PCA9575) return ICE_ERR_NOT_SUPPORTED;