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 9B36C45501; Wed, 26 Jun 2024 14:02:27 +0200 (CEST) Received: from mails.dpdk.org (localhost [127.0.0.1]) by mails.dpdk.org (Postfix) with ESMTP id 3BCE243441; Wed, 26 Jun 2024 13:56:16 +0200 (CEST) Received: from mgamail.intel.com (mgamail.intel.com [198.175.65.9]) by mails.dpdk.org (Postfix) with ESMTP id 8F34842E95 for ; Wed, 26 Jun 2024 13:44:49 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1719402289; x=1750938289; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=nNIZ1N7xszWUbsamlRI4+XwkX2urhEmn4tt+ra67620=; b=VAWDq1UBiN4MGMmbaLhv0+ok7AyIj3fngc7hju1HBWTP7K1CznLj4NAJ c9oNcnfMgPrbnMxaH2NOiwKwzf35dNUY0UTor6J0IFNEVvyPBHTHFuKgH 6DAIeU/uSZQuuaS/bFSlcrT+kl7O0Jqzvsl23Ih4aDz4GCUVBdtFQuFOB cjTY3YMn+RPe8jyWrP8oIJvguBqmxqeaI1vs1ELUhlH2DFa5sHU9FWOm/ 7ImE7iBlfsYTbTBKfwIRkJUzwn4zEBEMiRg6kUPF78zmouZiJFBZKZvl6 JXB/ORrl5kxucYg7KS2RpLXzDqq6FwYwD29K1qEyIksUjDGyb7lGtpBEP A==; X-CSE-ConnectionGUID: hg5qDsMTTJOngDBLQlKvTg== X-CSE-MsgGUID: diy09QnEQrS4tTPuTT3o5w== X-IronPort-AV: E=McAfee;i="6700,10204,11114"; a="38979467" X-IronPort-AV: E=Sophos;i="6.08,266,1712646000"; d="scan'208";a="38979467" 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:44:49 -0700 X-CSE-ConnectionGUID: xj4+xBczRGCd8SGsIgavzQ== X-CSE-MsgGUID: 8lce6k/hSDarT0wGb3chvQ== X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="6.08,266,1712646000"; d="scan'208";a="43874081" Received: from unknown (HELO silpixa00401119.ir.intel.com) ([10.55.129.167]) by orviesa010.jf.intel.com with ESMTP; 26 Jun 2024 04:44:48 -0700 From: Anatoly Burakov To: dev@dpdk.org Cc: Sergey Temerkhanov , ian.stokes@intel.com, bruce.richardson@intel.com Subject: [PATCH v4 065/103] net/ice/base: refactor ETH56G support for multiple PHYs per MAC Date: Wed, 26 Jun 2024 12:41:53 +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: Sergey Temerkhanov Support configurations with multiple ETH56G PHYs per a MAC complex. These PHYs have their own addresses and are supposed to have their ports numbered contiguously. This commit mainly provides port number translation for these configurations. Also, handle dual NAC correctly for max PHY ports as they differ from everything else. Signed-off-by: Sergey Temerkhanov Signed-off-by: Ian Stokes --- drivers/net/ice/base/ice_ptp_hw.c | 234 ++++++++++++++++++----------- drivers/net/ice/base/ice_sbq_cmd.h | 3 +- drivers/net/ice/base/ice_status.h | 2 + drivers/net/ice/base/ice_type.h | 24 ++- 4 files changed, 175 insertions(+), 88 deletions(-) diff --git a/drivers/net/ice/base/ice_ptp_hw.c b/drivers/net/ice/base/ice_ptp_hw.c index 17193feaa8..df3e3e77bd 100644 --- a/drivers/net/ice/base/ice_ptp_hw.c +++ b/drivers/net/ice/base/ice_ptp_hw.c @@ -911,8 +911,13 @@ static void ice_ptp_exec_tmr_cmd(struct ice_hw *hw) ice_flush(hw); } +enum eth56g_res_type { + ETH56G_PHY_REG, + ETH56G_PHY_MEM, +}; + /* 56G PHY access functions */ -static const u32 eth56g_port_base[ICE_NUM_PHY_PORTS] = { +static const u32 ice_eth56g_port_base[ICE_NUM_PHY_PORTS] = { ICE_PHY0_BASE, ICE_PHY1_BASE, ICE_PHY2_BASE, @@ -923,13 +928,14 @@ static const u32 eth56g_port_base[ICE_NUM_PHY_PORTS] = { /** * ice_write_phy_eth56g_raw_lp - Write a PHY port register with lock parameter * @hw: pointer to the HW struct + * @phy_index: PHY index * @reg_addr: PHY register address * @val: Value to write * @lock_sbq: true to lock the sideband queue */ static int -ice_write_phy_eth56g_raw_lp(struct ice_hw *hw, u32 reg_addr, u32 val, - bool lock_sbq) +ice_write_phy_eth56g_raw_lp(struct ice_hw *hw, u8 phy_index, u32 reg_addr, + u32 val, bool lock_sbq) { struct ice_sbq_msg_input phy_msg; int err; @@ -940,7 +946,7 @@ ice_write_phy_eth56g_raw_lp(struct ice_hw *hw, u32 reg_addr, u32 val, phy_msg.msg_addr_high = ICE_HI_WORD(reg_addr); phy_msg.data = val; - phy_msg.dest_dev = hw->phy_addr; + phy_msg.dest_dev = hw->phy_addr[phy_index]; err = ice_sbq_rw_reg_lp(hw, &phy_msg, lock_sbq); @@ -954,13 +960,14 @@ ice_write_phy_eth56g_raw_lp(struct ice_hw *hw, u32 reg_addr, u32 val, /** * ice_read_phy_eth56g_raw_lp - Read a PHY port register with lock parameter * @hw: pointer to the HW struct - * @reg_addr: PHY port register address - * @val: Pointer to the value to read (out param) + * @phy_index: PHY index + * @reg_addr: PHY register address + * @val: Value to write * @lock_sbq: true to lock the sideband queue */ static int -ice_read_phy_eth56g_raw_lp(struct ice_hw *hw, u32 reg_addr, u32 *val, - bool lock_sbq) +ice_read_phy_eth56g_raw_lp(struct ice_hw *hw, u8 phy_index, u32 reg_addr, + u32 *val, bool lock_sbq) { struct ice_sbq_msg_input phy_msg; int err; @@ -970,7 +977,8 @@ ice_read_phy_eth56g_raw_lp(struct ice_hw *hw, u32 reg_addr, u32 *val, phy_msg.msg_addr_low = ICE_LO_WORD(reg_addr); phy_msg.msg_addr_high = ICE_HI_WORD(reg_addr); - phy_msg.dest_dev = hw->phy_addr; + phy_msg.data = 0; + phy_msg.dest_dev = hw->phy_addr[phy_index]; err = ice_sbq_rw_reg_lp(hw, &phy_msg, lock_sbq); @@ -986,47 +994,95 @@ ice_read_phy_eth56g_raw_lp(struct ice_hw *hw, u32 reg_addr, u32 *val, /** * ice_phy_port_reg_address_eth56g - Calculate a PHY port register address * @port: Port number to be written + * @res_type: resource type (register/memory) * @offset: Offset from PHY port register base * @address: The result address */ static int -ice_phy_port_reg_address_eth56g(u8 port, u16 offset, u32 *address) +ice_phy_port_res_address_eth56g(u8 port, enum eth56g_res_type res_type, + u16 offset, u32 *address) { u8 phy, lane; - if (port >= ICE_NUM_EXTERNAL_PORTS) - return ICE_ERR_OUT_OF_RANGE; - phy = port / ICE_PORTS_PER_QUAD; lane = port % ICE_PORTS_PER_QUAD; - *address = offset + eth56g_port_base[phy] + - PHY_PTP_LANE_ADDR_STEP * lane; + switch (res_type) { + case ETH56G_PHY_REG: + *address = offset + ice_eth56g_port_base[phy] + + PHY_PTP_LANE_ADDR_STEP * lane; + break; + case ETH56G_PHY_MEM: + *address = offset + ice_eth56g_port_base[phy] + + PHY_PTP_MEM_START + PHY_PTP_MEM_LANE_STEP * lane; + break; + default: + return ICE_ERR_PARAM; + } return 0; } /** - * ice_phy_port_mem_address_eth56g - Calculate a PHY port memory address - * @port: Port number to be written - * @offset: Offset from PHY port register base - * @address: The result address + * ice_write_phy_port_eth56g_lp - Write a PHY port register with lock parameter + * @hw: pointer to the HW struct + * @reg_offs: PHY register offset + * @port: Port number + * @val: Value to write + * @res_type: resource type (register/memory) + * @lock_sbq: true to lock the sideband queue */ static int -ice_phy_port_mem_address_eth56g(u8 port, u16 offset, u32 *address) +ice_write_phy_port_eth56g_lp(struct ice_hw *hw, u8 port, u32 reg_offs, u32 val, + enum eth56g_res_type res_type, bool lock_sbq) { - u8 phy, lane; + u8 phy_index = port / hw->phy_ports; + u8 phy_port = port % hw->phy_ports; + int err; + u32 reg_addr; - if (port >= ICE_NUM_EXTERNAL_PORTS) + if (port >= hw->max_phy_port) return ICE_ERR_OUT_OF_RANGE; - phy = port / ICE_PORTS_PER_QUAD; - lane = port % ICE_PORTS_PER_QUAD; + err = ice_phy_port_res_address_eth56g(phy_port, res_type, reg_offs, + ®_addr); - *address = offset + eth56g_port_base[phy] + - PHY_PTP_MEM_START + PHY_PTP_MEM_LANE_STEP * lane; + if (err) + return err; - return 0; + return ice_write_phy_eth56g_raw_lp(hw, phy_index, reg_addr, val, + lock_sbq); +} + +/** + * ice_read_phy_port_eth56g_lp - Read a PHY port register with lock parameter + * @hw: pointer to the HW struct + * @reg_offs: PHY register offset + * @port: Port number + * @val: Value to write + * @res_type: resource type (register/memory) + * @lock_sbq: true to lock the sideband queue + */ +static int +ice_read_phy_port_eth56g_lp(struct ice_hw *hw, u8 port, u32 reg_offs, u32 *val, + enum eth56g_res_type res_type, bool lock_sbq) +{ + u8 phy_index = port / hw->phy_ports; + u8 phy_port = port % hw->phy_ports; + int err; + u32 reg_addr; + + if (port >= hw->max_phy_port) + return ICE_ERR_OUT_OF_RANGE; + + err = ice_phy_port_res_address_eth56g(phy_port, res_type, reg_offs, + ®_addr); + + if (err) + return err; + + return ice_read_phy_eth56g_raw_lp(hw, phy_index, reg_addr, val, + lock_sbq); } /** @@ -1041,14 +1097,8 @@ static int ice_write_phy_reg_eth56g_lp(struct ice_hw *hw, u8 port, u16 offset, u32 val, bool lock_sbq) { - int err; - u32 reg_addr; - - err = ice_phy_port_reg_address_eth56g(port, offset, ®_addr); - if (err) - return err; - - return ice_write_phy_eth56g_raw_lp(hw, reg_addr, val, lock_sbq); + return ice_write_phy_port_eth56g_lp(hw, port, offset, val, + ETH56G_PHY_REG, lock_sbq); } /** @@ -1077,14 +1127,8 @@ static int ice_read_phy_reg_eth56g_lp(struct ice_hw *hw, u8 port, u16 offset, u32 *val, bool lock_sbq) { - int err; - u32 reg_addr; - - err = ice_phy_port_reg_address_eth56g(port, offset, ®_addr); - if (err) - return err; - - return ice_read_phy_eth56g_raw_lp(hw, reg_addr, val, lock_sbq); + return ice_read_phy_port_eth56g_lp(hw, port, offset, val, + ETH56G_PHY_REG, lock_sbq); } /** @@ -1113,14 +1157,8 @@ static int ice_phy_port_mem_read_eth56g_lp(struct ice_hw *hw, u8 port, u16 offset, u32 *val, bool lock_sbq) { - int err; - u32 mem_addr; - - err = ice_phy_port_mem_address_eth56g(port, offset, &mem_addr); - if (err) - return err; - - return ice_read_phy_eth56g_raw_lp(hw, mem_addr, val, lock_sbq); + return ice_read_phy_port_eth56g_lp(hw, port, offset, val, + ETH56G_PHY_MEM, lock_sbq); } /** @@ -1150,14 +1188,8 @@ static int ice_phy_port_mem_write_eth56g_lp(struct ice_hw *hw, u8 port, u16 offset, u32 val, bool lock_sbq) { - int err; - u32 mem_addr; - - err = ice_phy_port_mem_address_eth56g(port, offset, &mem_addr); - if (err) - return err; - - return ice_write_phy_eth56g_raw_lp(hw, mem_addr, val, lock_sbq); + return ice_write_phy_port_eth56g_lp(hw, port, offset, val, + ETH56G_PHY_MEM, lock_sbq); } /** @@ -2192,22 +2224,35 @@ static int ice_ptp_init_phc_eth56g(struct ice_hw *hw) } /** - * ice_ptp_read_tx_hwtstamp_status_eth56g - Get the current TX timestamp - * err mask. Returns the mask of ports where TX timestamps are available + * ice_ptp_read_tx_hwtstamp_status_eth56g - Get TX timestamp status * @hw: pointer to the HW struct - * @ts_err: the timestamp mask pointer + * @ts_status: the timestamp mask pointer + * + * Read the PHY Tx timestamp status mask indicating which ports have Tx + * timestamps available. */ int -ice_ptp_read_tx_hwtstamp_status_eth56g(struct ice_hw *hw, u32 *ts_err) +ice_ptp_read_tx_hwtstamp_status_eth56g(struct ice_hw *hw, u32 *ts_status) { - int err; + u32 curr_status; + u8 phy, mask; - err = ice_read_phy_eth56g_raw_lp(hw, PHY_PTP_INT_STATUS, ts_err, - true); - if (err) - return err; + mask = (1 << hw->phy_ports) - 1; + *ts_status = 0; - ice_debug(hw, ICE_DBG_PTP, "PHY interrupt err: %x\n", *ts_err); + for (phy = 0; phy < hw->num_phys; phy++) { + int err; + + err = ice_read_phy_eth56g_raw_lp(hw, phy, PHY_PTP_INT_STATUS, + &curr_status, true); + + if (err) + return err; + + *ts_status |= (curr_status & mask) << (phy * hw->phy_ports); + } + + ice_debug(hw, ICE_DBG_PTP, "PHY interrupt err: %x\n", *ts_status); return 0; } @@ -2216,37 +2261,56 @@ ice_ptp_read_tx_hwtstamp_status_eth56g(struct ice_hw *hw, u32 *ts_err) /** * ice_ptp_init_phy_model - Initialize hw->phy_model based on device type - * @hw: pointer to the HW struct + * @hw: pointer to the HW structure * - * Determine the PHY configuration for the device, and initialize hw->phy_model + * Determine the PHY model for the device, and initialize hw->phy_model * for use by other functions. */ void ice_ptp_init_phy_model(struct ice_hw *hw) { - u32 phy_rev; + unsigned int phy; + + for (phy = 0; phy < MAX_PHYS_PER_ICE; phy++) + hw->phy_addr[phy] = 0; switch (hw->device_id & ICE_DEVID_MASK) { case ICE_DEV_ID_E825C_BACKPLANE & ICE_DEVID_MASK: - hw->phy_addr = eth56g_dev_0; + hw->phy_addr[0] = eth56g_dev_0; + hw->phy_addr[1] = eth56g_dev_1; + hw->num_phys = ICE_PHYS_PER_CPLX_C825X; + hw->phy_ports = ICE_PORTS_PER_PHY_C825X; + hw->max_phy_port = ice_is_nac_dual(hw) ? + ICE_PORTS_PER_PHY_C825X : + ICE_PHYS_PER_CPLX_C825X * ICE_PORTS_PER_PHY_C825X; break; default: - hw->phy_addr = 0; + goto e8xx; } - if (hw->phy_addr) { - int err; + ice_sb_access_ena_eth56g(hw, true); + for (phy = 0; phy < hw->num_phys; phy++) + if (hw->phy_addr[phy]) { + int err; + u32 phy_rev; - ice_sb_access_ena_eth56g(hw, true); - err = ice_read_phy_eth56g_raw_lp(hw, PHY_REG_REVISION, - &phy_rev, true); - if (err) - return; + err = ice_read_phy_eth56g_raw_lp(hw, phy, + PHY_REG_REVISION, + &phy_rev, true); + if (err) { + hw->phy_model = ICE_PHY_UNSUP; + return; + } - if (phy_rev == PHY_REVISION_ETH56G) { - hw->phy_model = ICE_PHY_ETH56G; - return; + if (phy_rev != PHY_REVISION_ETH56G) { + hw->phy_model = ICE_PHY_UNSUP; + return; + } } - } + + hw->phy_model = ICE_PHY_ETH56G; + + return; +e8xx: if (ice_is_e810(hw)) hw->phy_model = ICE_PHY_E810; diff --git a/drivers/net/ice/base/ice_sbq_cmd.h b/drivers/net/ice/base/ice_sbq_cmd.h index aad77af9a1..d0f5ed25c4 100644 --- a/drivers/net/ice/base/ice_sbq_cmd.h +++ b/drivers/net/ice/base/ice_sbq_cmd.h @@ -48,7 +48,8 @@ struct ice_sbq_evt_desc { }; enum ice_sbq_msg_dev { - eth56g_dev_0 = 0x02, + eth56g_dev_0 = 2, + eth56g_dev_1 = 13, rmn_0 = 0x02, rmn_1 = 0x03, rmn_2 = 0x04, diff --git a/drivers/net/ice/base/ice_status.h b/drivers/net/ice/base/ice_status.h index 1965347a8b..16cb22f3a6 100644 --- a/drivers/net/ice/base/ice_status.h +++ b/drivers/net/ice/base/ice_status.h @@ -36,6 +36,8 @@ enum ice_status { ICE_ERR_BUF_TOO_SHORT = -52, ICE_ERR_NVM_BLANK_MODE = -53, + ICE_ERR_UNKNOWN_PHY = -60, + /* ARQ/ASQ specific error codes. Range -100..-109 */ ICE_ERR_AQ_ERROR = -100, ICE_ERR_AQ_TIMEOUT = -101, diff --git a/drivers/net/ice/base/ice_type.h b/drivers/net/ice/base/ice_type.h index 9bccced824..153c235bd6 100644 --- a/drivers/net/ice/base/ice_type.h +++ b/drivers/net/ice/base/ice_type.h @@ -1237,12 +1237,18 @@ struct ice_switch_info { /* PHY model */ enum ice_phy_model { - ICE_PHY_E810 = 1, + ICE_PHY_UNSUP = -1, + ICE_PHY_E810 = 1, ICE_PHY_E822, ICE_PHY_ETH56G, ICE_PHY_E830, }; +enum ice_eth56g_mode { + ICE_ETH56G_MODE_0, + ICE_ETH56G_MODE_1, +}; + /* Port hardware description */ struct ice_hw { u8 *hw_addr; @@ -1269,9 +1275,17 @@ struct ice_hw { u8 pf_id; /* device profile info */ enum ice_phy_model phy_model; - u8 phy_addr; /* PHY address */ u8 phy_ports; u8 max_phy_port; +#define ICE_PHYS_PER_CPLX_E824S 1 +#define ICE_PORTS_PER_PHY_E824S 8 + +#define ICE_PHYS_PER_CPLX_C825X 2 +#define ICE_PORTS_PER_PHY_C825X 4 + +#define MAX_PHYS_PER_ICE 2 + u8 num_phys; + u8 phy_addr[MAX_PHYS_PER_ICE]; /* PHY address */ u8 logical_pf_id; u16 max_burst_size; /* driver sets this value */ @@ -1678,4 +1692,10 @@ struct ice_aq_get_set_rss_lut_params { /* AQ API version for FW auto drop reports */ #define ICE_FW_API_AUTO_DROP_MAJ 1 #define ICE_FW_API_AUTO_DROP_MIN 4 + +static inline bool +ice_is_nac_dual(struct ice_hw *hw) +{ + return !!(hw->dev_caps.nac_topo.mode & ICE_NAC_TOPO_DUAL_M); +} #endif /* _ICE_TYPE_H_ */ -- 2.43.0