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 6531545500; Wed, 26 Jun 2024 13:55:46 +0200 (CEST) Received: from mails.dpdk.org (localhost [127.0.0.1]) by mails.dpdk.org (Postfix) with ESMTP id 7E99243262; Wed, 26 Jun 2024 13:55:05 +0200 (CEST) Received: from mgamail.intel.com (mgamail.intel.com [198.175.65.9]) by mails.dpdk.org (Postfix) with ESMTP id E709F42E95 for ; Wed, 26 Jun 2024 13:43:13 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1719402194; x=1750938194; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=0T85yhIQsvZt6Np8HWKn05DMJKPOjgTA/L8HBkAIc5A=; b=mCawLitK6ukTObgWxPn1aPfuBZjVl6cUioIkeirwVqAiisvu5q2t8VCc a9twr2utBzADmvULln1RCrOI8x0akv5wGxhuLQxHK5uHqVjzrz/yF+ihM L05uSj6ii7z5Wmjxq292Yl5Kla5fhrPHP2kNXm94KWQdfiCXFch8eMIJz xuO4yvrSRR/Erhq72tk2xYmji5yxd+pXE9MisNKqJwwjOzh3BkitWwHuq mx2lvh73uunsg3P6c7PYM7hrqONMCpdZUeM0tMGmEOULwi9jQc6VncAtm 7+rAf1kfpjNDS9ZbP2VJLtUK15EnZuyDA7xyKEE9LBizB8HCQY9wvG4I2 g==; X-CSE-ConnectionGUID: OcVvHEUCSoyxqSJJMhJp9A== X-CSE-MsgGUID: smJSY/HXT7a1IhkNlFVVew== X-IronPort-AV: E=McAfee;i="6700,10204,11114"; a="38979291" X-IronPort-AV: E=Sophos;i="6.08,266,1712646000"; d="scan'208";a="38979291" Received: from orviesa010.jf.intel.com ([10.64.159.150]) by orvoesa101.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 26 Jun 2024 04:43:13 -0700 X-CSE-ConnectionGUID: aCAN7eGXQICqbTtiWLaEMQ== X-CSE-MsgGUID: y11eepMVQdGtrbyhnxevCA== X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="6.08,266,1712646000"; d="scan'208";a="43873454" Received: from unknown (HELO silpixa00401119.ir.intel.com) ([10.55.129.167]) by orviesa010.jf.intel.com with ESMTP; 26 Jun 2024 04:43:12 -0700 From: Anatoly Burakov To: dev@dpdk.org Cc: Michal Michalik , ian.stokes@intel.com, bruce.richardson@intel.com Subject: [PATCH v4 008/103] net/ice/base: implement initial PTP support for E830 Date: Wed, 26 Jun 2024 12:40:56 +0100 Message-ID: X-Mailer: git-send-email 2.43.0 In-Reply-To: References: 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 From: Michal Michalik The new series of devices supported by ice driver are E830 devices. This hardware supports the PTP feature very similar to E810 devices. The main difference besides some other register addresses is that in E830 we are able to read the TX timestamps memory directly from BARs (in E810 we used SBQ to read those). Note some workaround code for E830 functions and defines are added at this point but a full E830 Patch will add full functionality at a later stage. Signed-off-by: Michal Michalik Signed-off-by: Ian Stokes --- drivers/net/ice/base/ice_common.c | 22 ++++ drivers/net/ice/base/ice_common.h | 1 + drivers/net/ice/base/ice_devids.h | 18 +++ drivers/net/ice/base/ice_hw_autogen.h | 5 + drivers/net/ice/base/ice_ptp_hw.c | 165 +++++++++++++++++++++++++- drivers/net/ice/base/ice_ptp_hw.h | 11 +- drivers/net/ice/base/ice_type.h | 2 + 7 files changed, 218 insertions(+), 6 deletions(-) diff --git a/drivers/net/ice/base/ice_common.c b/drivers/net/ice/base/ice_common.c index 50c8a1b472..16107317d3 100644 --- a/drivers/net/ice/base/ice_common.c +++ b/drivers/net/ice/base/ice_common.c @@ -177,6 +177,17 @@ static int ice_set_mac_type(struct ice_hw *hw) case ICE_DEV_ID_E825C_SGMII: hw->mac_type = ICE_MAC_GENERIC_3K_E825; break; + case ICE_DEV_ID_E830_BACKPLANE: + case ICE_DEV_ID_E830_QSFP56: + case ICE_DEV_ID_E830_SFP: + case ICE_DEV_ID_E830C_BACKPLANE: + case ICE_DEV_ID_E830_XXV_BACKPLANE: + case ICE_DEV_ID_E830C_QSFP: + case ICE_DEV_ID_E830_XXV_QSFP: + case ICE_DEV_ID_E830C_SFP: + case ICE_DEV_ID_E830_XXV_SFP: + hw->mac_type = ICE_MAC_E830; + break; default: hw->mac_type = ICE_MAC_UNKNOWN; break; @@ -245,6 +256,17 @@ bool ice_is_e810t(struct ice_hw *hw) return false; } +/** + * ice_is_e830 + * @hw: pointer to the hardware structure + * + * returns true if the device is E830 based, false if not. + */ +bool ice_is_e830(struct ice_hw *hw) +{ + return hw->mac_type == ICE_MAC_E830; +} + /** * ice_is_e823 * @hw: pointer to the hardware structure diff --git a/drivers/net/ice/base/ice_common.h b/drivers/net/ice/base/ice_common.h index 18cbe590c6..ecfe55bd3a 100644 --- a/drivers/net/ice/base/ice_common.h +++ b/drivers/net/ice/base/ice_common.h @@ -265,6 +265,7 @@ void ice_print_rollback_msg(struct ice_hw *hw); bool ice_is_generic_mac(struct ice_hw *hw); bool ice_is_e810(struct ice_hw *hw); bool ice_is_e810t(struct ice_hw *hw); +bool ice_is_e830(struct ice_hw *hw); bool ice_is_e825c(struct ice_hw *hw); bool ice_is_e823(struct ice_hw *hw); int diff --git a/drivers/net/ice/base/ice_devids.h b/drivers/net/ice/base/ice_devids.h index 19478d2db1..49d642372a 100644 --- a/drivers/net/ice/base/ice_devids.h +++ b/drivers/net/ice/base/ice_devids.h @@ -15,6 +15,24 @@ #define ICE_DEV_ID_E823L_1GBE 0x124F /* Intel(R) Ethernet Connection E823-L for QSFP */ #define ICE_DEV_ID_E823L_QSFP 0x151D +/* Intel(R) Ethernet Controller E830-CC for backplane */ +#define ICE_DEV_ID_E830_BACKPLANE 0x12D1 +/* Intel(R) Ethernet Controller E830-CC for QSFP */ +#define ICE_DEV_ID_E830_QSFP56 0x12D2 +/* Intel(R) Ethernet Controller E830-CC for SFP */ +#define ICE_DEV_ID_E830_SFP 0x12D3 +/* Intel(R) Ethernet Controller E830-C for backplane */ +#define ICE_DEV_ID_E830C_BACKPLANE 0x12D5 +/* Intel(R) Ethernet Controller E830-XXV for backplane */ +#define ICE_DEV_ID_E830_XXV_BACKPLANE 0x12DC +/* Intel(R) Ethernet Controller E830-C for QSFP */ +#define ICE_DEV_ID_E830C_QSFP 0x12D8 +/* Intel(R) Ethernet Controller E830-XXV for QSFP */ +#define ICE_DEV_ID_E830_XXV_QSFP 0x12DD +/* Intel(R) Ethernet Controller E830-C for SFP */ +#define ICE_DEV_ID_E830C_SFP 0x12DA +/* Intel(R) Ethernet Controller E830-XXV for SFP */ +#define ICE_DEV_ID_E830_XXV_SFP 0x12DE /* Intel(R) Ethernet Controller E810-C for backplane */ #define ICE_DEV_ID_E810C_BACKPLANE 0x1591 /* Intel(R) Ethernet Controller E810-C for QSFP */ diff --git a/drivers/net/ice/base/ice_hw_autogen.h b/drivers/net/ice/base/ice_hw_autogen.h index 5215d71c70..fde5f9d86f 100644 --- a/drivers/net/ice/base/ice_hw_autogen.h +++ b/drivers/net/ice/base/ice_hw_autogen.h @@ -7,6 +7,11 @@ #ifndef _ICE_HW_AUTOGEN_H_ #define _ICE_HW_AUTOGEN_H_ +#define E830_PRTTSYN_TXTIME_H(_i) (0x001E5004 + ((_i) * 64)) /* _i=0...63 */ /* Reset Source: GLOBR */ +#define E830_PRTTSYN_TXTIME_L(_i) (0x001E5000 + ((_i) * 64)) /* _i=0...63 */ /* Reset Source: GLOBR */ +#define E830_PRTMAC_TS_TX_MEM_VALID_L 0x001E2000 /* Reset Source: GLOBR */ +#define E830_PRTMAC_TS_TX_MEM_VALID_H 0x001E2020 /* Reset Source: GLOBR */ + #define GL_HIDA(_i) (0x00082000 + ((_i) * 4)) #define GL_HIBA(_i) (0x00081000 + ((_i) * 4)) #define GL_HICR 0x00082040 diff --git a/drivers/net/ice/base/ice_ptp_hw.c b/drivers/net/ice/base/ice_ptp_hw.c index e83f4d5357..3d4e02a2f6 100644 --- a/drivers/net/ice/base/ice_ptp_hw.c +++ b/drivers/net/ice/base/ice_ptp_hw.c @@ -4920,17 +4920,18 @@ ice_ptp_prep_phy_adj_target_e810(struct ice_hw *hw, u32 target_time) } /** - * ice_ptp_port_cmd_e810 - Prepare all external PHYs for a timer command + * ice_ptp_port_cmd - Prepare all external PHYs for a timer command * @hw: pointer to HW struct * @cmd: Command to be sent to the port * @lock_sbq: true if the sideband queue lock must be acquired + * @eth_gltsyn_cmd_addr: address for ETH_GLTSYN_CMD register * * Prepare the external PHYs connected to this device for a timer sync * command. */ static int -ice_ptp_port_cmd_e810(struct ice_hw *hw, enum ice_ptp_tmr_cmd cmd, - bool lock_sbq) +ice_ptp_port_cmd(struct ice_hw *hw, enum ice_ptp_tmr_cmd cmd, + bool lock_sbq, u32 eth_gltsyn_cmd_addr) { int status; u32 cmd_val, val; @@ -4957,7 +4958,8 @@ ice_ptp_port_cmd_e810(struct ice_hw *hw, enum ice_ptp_tmr_cmd cmd, } /* Read, modify, write */ - status = ice_read_phy_reg_e810_lp(hw, ETH_GLTSYN_CMD, &val, lock_sbq); + status = ice_read_phy_reg_e810_lp(hw, eth_gltsyn_cmd_addr, &val, + lock_sbq); if (status) { ice_debug(hw, ICE_DBG_PTP, "Failed to read GLTSYN_CMD, status %d\n", status); @@ -4968,7 +4970,8 @@ ice_ptp_port_cmd_e810(struct ice_hw *hw, enum ice_ptp_tmr_cmd cmd, val &= ~TS_CMD_MASK_E810; val |= cmd_val; - status = ice_write_phy_reg_e810_lp(hw, ETH_GLTSYN_CMD, val, lock_sbq); + status = ice_write_phy_reg_e810_lp(hw, eth_gltsyn_cmd_addr, val, + lock_sbq); if (status) { ice_debug(hw, ICE_DBG_PTP, "Failed to write back GLTSYN_CMD, status %d\n", status); @@ -4978,6 +4981,38 @@ ice_ptp_port_cmd_e810(struct ice_hw *hw, enum ice_ptp_tmr_cmd cmd, return 0; } +/** + * ice_ptp_port_cmd_e810 - Prepare all external PHYs for a timer command + * @hw: pointer to HW struct + * @cmd: Command to be sent to the port + * @lock_sbq: true if the sideband queue lock must be acquired + * + * Prepare the external PHYs connected to this device for a timer sync + * command. + */ +static int +ice_ptp_port_cmd_e810(struct ice_hw *hw, enum ice_ptp_tmr_cmd cmd, + bool lock_sbq) +{ + return ice_ptp_port_cmd(hw, cmd, lock_sbq, E810_ETH_GLTSYN_CMD); +} + +/** + * ice_ptp_port_cmd_e830 - Prepare all external PHYs for a timer command + * @hw: pointer to HW struct + * @cmd: Command to be sent to the port + * @lock_sbq: true if the sideband queue lock must be acquired + * + * Prepare the external PHYs connected to this device for a timer sync + * command. + */ +static int +ice_ptp_port_cmd_e830(struct ice_hw *hw, enum ice_ptp_tmr_cmd cmd, + bool lock_sbq) +{ + return ice_ptp_port_cmd(hw, cmd, lock_sbq, E830_ETH_GLTSYN_CMD); +} + /* E810T SMA functions * * The following functions operate specifically on E810T hardware and are used @@ -5205,6 +5240,110 @@ bool ice_is_pca9575_present(struct ice_hw *hw) return false; } +/** + * ice_ptp_write_direct_incval_e830 - Prep PHY port increment value change + * @hw: pointer to HW struct + * @incval: The new 40bit increment value to prepare + * + * Prepare the PHY port for a new increment value by programming the PHC + * GLTSYN_INCVAL_L and GLTSYN_INCVAL_H registers. The actual change is + * completed by FW automatically. + */ +static int +ice_ptp_write_direct_incval_e830(struct ice_hw *hw, u64 incval) +{ + u32 high, low; + u8 tmr_idx; + + tmr_idx = hw->func_caps.ts_func_info.tmr_index_owned; + low = ICE_LO_DWORD(incval); + high = ICE_HI_DWORD(incval); + + wr32(hw, GLTSYN_INCVAL_L(tmr_idx), low); + wr32(hw, GLTSYN_INCVAL_H(tmr_idx), high); + + return 0; +} + +/** + * ice_ptp_write_direct_phc_time_e830 - Prepare PHY port with initial time + * @hw: Board private structure + * @time: Time to initialize the PHY port clock to + * + * Program the PHY port ETH_GLTSYN_SHTIME registers in preparation setting the + * initial clock time. The time will not actually be programmed until the + * driver issues an ICE_PTP_INIT_TIME command. + * + * The time value is the upper 32 bits of the PHY timer, usually in units of + * nominal nanoseconds. + */ +static int +ice_ptp_write_direct_phc_time_e830(struct ice_hw *hw, u64 time) +{ + u8 tmr_idx; + + tmr_idx = hw->func_caps.ts_func_info.tmr_index_owned; + + wr32(hw, GLTSYN_TIME_0(tmr_idx), 0); + wr32(hw, GLTSYN_TIME_L(tmr_idx), ICE_LO_DWORD(time)); + wr32(hw, GLTSYN_TIME_H(tmr_idx), ICE_HI_DWORD(time)); + + return 0; +} + +/** + * ice_read_phy_tstamp_e830 - 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 E830 device. + */ +static int +ice_read_phy_tstamp_e830(struct ice_hw *hw, u8 lport, u8 idx, u64 *tstamp) +{ + u32 hi_addr = E830_HIGH_TX_MEMORY_BANK(idx, lport); + u32 lo_addr = E830_LOW_TX_MEMORY_BANK(idx, lport); + u32 lo_val, hi_val, lo; + u8 hi; + + lo_val = rd32(hw, lo_addr); + hi_val = rd32(hw, hi_addr); + + lo = lo_val; + hi = (u8)hi_val; + + /* For E830 devices, the timestamp is reported with the lower 32 bits + * in the low register, and the upper 8 bits in the high register. + */ + *tstamp = ((u64)hi) << TS_HIGH_S | ((u64)lo & TS_LOW_M); + + return 0; +} + +/** + * ice_get_phy_tx_tstamp_ready_e830 - Read Tx memory status register + * @hw: pointer to the HW struct + * @port: the PHY port to read + * @tstamp_ready: contents of the Tx memory status register + * + */ +int +ice_get_phy_tx_tstamp_ready_e830(struct ice_hw *hw, u8 port, u64 *tstamp_ready) +{ + u64 hi; + u32 lo; + + lo = rd32(hw, E830_PRTMAC_TS_TX_MEM_VALID_L); + hi = (u64)rd32(hw, E830_PRTMAC_TS_TX_MEM_VALID_H) << 32; + + *tstamp_ready = hi | lo; + + return 0; +} + /* Device agnostic functions * * The following functions implement shared behavior common to both E822/E823 @@ -5285,6 +5424,9 @@ static int ice_ptp_tmr_cmd(struct ice_hw *hw, enum ice_ptp_tmr_cmd cmd, case ICE_PHY_ETH56G: status = ice_ptp_port_cmd_eth56g(hw, cmd, lock_sbq); break; + case ICE_PHY_E830: + status = ice_ptp_port_cmd_e830(hw, cmd, lock_sbq); + break; case ICE_PHY_E810: status = ice_ptp_port_cmd_e810(hw, cmd, lock_sbq); break; @@ -5330,6 +5472,10 @@ int ice_ptp_init_time(struct ice_hw *hw, u64 time) tmr_idx = hw->func_caps.ts_func_info.tmr_index_owned; /* Source timers */ + /* For E830 we don't need to use shadow registers, its automatic */ + if (ice_is_e830(hw)) + return ice_ptp_write_direct_phc_time_e830(hw, time); + wr32(hw, GLTSYN_SHTIME_L(tmr_idx), ICE_LO_DWORD(time)); wr32(hw, GLTSYN_SHTIME_H(tmr_idx), ICE_HI_DWORD(time)); wr32(hw, GLTSYN_SHTIME_0(tmr_idx), 0); @@ -5377,6 +5523,10 @@ int ice_ptp_write_incval(struct ice_hw *hw, u64 incval) tmr_idx = hw->func_caps.ts_func_info.tmr_index_owned; + /* For E830 we don't need to use shadow registers, its automatic */ + if (ice_is_e830(hw)) + return ice_ptp_write_direct_incval_e830(hw, incval); + /* Shadow Adjust */ wr32(hw, GLTSYN_SHADJ_L(tmr_idx), ICE_LO_DWORD(incval)); wr32(hw, GLTSYN_SHADJ_H(tmr_idx), ICE_HI_DWORD(incval)); @@ -5456,6 +5606,9 @@ int ice_ptp_adj_clock(struct ice_hw *hw, s32 adj, bool lock_sbq) case ICE_PHY_ETH56G: status = ice_ptp_prep_phy_adj_eth56g(hw, adj, lock_sbq); break; + case ICE_PHY_E830: + /* E830 sync PHYs automatically after setting GLTSYN_SHADJ */ + return 0; case ICE_PHY_E810: status = ice_ptp_prep_phy_adj_e810(hw, adj, lock_sbq); break; @@ -5571,6 +5724,8 @@ ice_read_phy_tstamp(struct ice_hw *hw, u8 block, u8 idx, u64 *tstamp) case ICE_PHY_ETH56G: status = ice_read_phy_tstamp_eth56g(hw, block, idx, tstamp); break; + case ICE_PHY_E830: + return ice_read_phy_tstamp_e830(hw, block, idx, tstamp); case ICE_PHY_E810: status = ice_read_phy_tstamp_e810(hw, block, idx, tstamp); break; diff --git a/drivers/net/ice/base/ice_ptp_hw.h b/drivers/net/ice/base/ice_ptp_hw.h index e2fb716186..ed359db6ee 100644 --- a/drivers/net/ice/base/ice_ptp_hw.h +++ b/drivers/net/ice/base/ice_ptp_hw.h @@ -178,6 +178,8 @@ int ice_cfg_cgu_bypass_mux_e825c(struct ice_hw *hw, u8 port_num, bool clock_1588, unsigned int ena); int ice_cfg_synce_ethdiv_e825c(struct ice_hw *hw, u8 *divider); +int +ice_get_phy_tx_tstamp_ready_e830(struct ice_hw *hw, u8 port, u64 *tstamp_ready); /** * ice_e822_time_ref - Get the current TIME_REF from capabilities @@ -482,7 +484,9 @@ int ice_ptp_init_phy_cfg(struct ice_hw *hw); #define ETH_GLTSYN_SHADJ_H(_i) (0x0300037C + ((_i) * 32)) /* E810 timer command register */ -#define ETH_GLTSYN_CMD 0x03000344 +#define E810_ETH_GLTSYN_CMD 0x03000344 +/* E830 timer command register */ +#define E830_ETH_GLTSYN_CMD 0x00088814 /* Source timer incval macros */ #define INCVAL_HIGH_M 0xFF @@ -522,6 +526,11 @@ int ice_ptp_init_phy_cfg(struct ice_hw *hw); #define LOW_TX_MEMORY_BANK_START 0x03090000 #define HIGH_TX_MEMORY_BANK_START 0x03090004 +#define E830_LOW_TX_MEMORY_BANK(slot, port) \ + (E830_PRTTSYN_TXTIME_L(slot) + 0x8 * (port)) +#define E830_HIGH_TX_MEMORY_BANK(slot, port) \ + (E830_PRTTSYN_TXTIME_H(slot) + 0x8 * (port)) + /* E810T PCA9575 IO controller registers */ #define ICE_PCA9575_P0_IN 0x0 #define ICE_PCA9575_P1_IN 0x1 diff --git a/drivers/net/ice/base/ice_type.h b/drivers/net/ice/base/ice_type.h index 48f892bfd3..99eb758eeb 100644 --- a/drivers/net/ice/base/ice_type.h +++ b/drivers/net/ice/base/ice_type.h @@ -204,6 +204,7 @@ enum ice_set_fc_aq_failures { enum ice_mac_type { ICE_MAC_UNKNOWN = 0, ICE_MAC_E810, + ICE_MAC_E830, ICE_MAC_GENERIC, ICE_MAC_GENERIC_3K, ICE_MAC_GENERIC_3K_E825, @@ -1233,6 +1234,7 @@ enum ice_phy_cfg { ICE_PHY_E810 = 1, ICE_PHY_E822, ICE_PHY_ETH56G, + ICE_PHY_E830, }; /* Port hardware description */ -- 2.43.0