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 205A94404F; Wed, 12 Jun 2024 17:20:07 +0200 (CEST) Received: from mails.dpdk.org (localhost [127.0.0.1]) by mails.dpdk.org (Postfix) with ESMTP id 5461D42F7A; Wed, 12 Jun 2024 17:06:12 +0200 (CEST) Received: from mgamail.intel.com (mgamail.intel.com [198.175.65.10]) by mails.dpdk.org (Postfix) with ESMTP id 68D0D42F6D for ; Wed, 12 Jun 2024 17:06:09 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1718204770; x=1749740770; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=yyXRNOqVlTG7px6FH/kCWSoD2GRAzZSH0seD5ChldHM=; b=KXg06p0RHKR+Ke/nl0U+sQG2NOEa/IfRF7JRVl/L4GoT/LYk+u+cxNWj XT+Cf8/nR4kC+OR4RCupIm+f0bv1bGxw7CHPsvKyQedL7g/ompi9GA0Yu clV2s4Pv4D9vkfv+mQ9mrzTj63c2B2TBQYPu5RvSYFqgFYYpJvwMm4v1h PjrHdfSQg2kXoc6PYYGsWHIrCLHvRWLaYH/Vpg8D4JI+me/paRxFHy4T3 G5/np6w6YLF7hIIBNI6nAIq9wZ/9GwaNOkriy+XEpdMD1My0Qqe9dVuIa DRGOoxhKHl0mUUoi73drPy1EYZM1BdEfFKoRoSdEbdYY6sOCozybRmzPK g==; X-CSE-ConnectionGUID: /Y7MsD/0TwaKdxoMSmOx6g== X-CSE-MsgGUID: cnNgQw3vQU2+UGAiNgVkKQ== X-IronPort-AV: E=McAfee;i="6700,10204,11101"; a="32459871" X-IronPort-AV: E=Sophos;i="6.08,233,1712646000"; d="scan'208";a="32459871" Received: from orviesa009.jf.intel.com ([10.64.159.149]) by orvoesa102.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 12 Jun 2024 08:06:09 -0700 X-CSE-ConnectionGUID: Vez+6hwfT8qnYWUcDbeJBQ== X-CSE-MsgGUID: aEXYACVQSD2ZdUbtQe56vQ== X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="6.08,233,1712646000"; d="scan'208";a="39925824" Received: from silpixa00401119.ir.intel.com ([10.55.129.167]) by orviesa009.jf.intel.com with ESMTP; 12 Jun 2024 08:06:07 -0700 From: Anatoly Burakov To: dev@dpdk.org Cc: Ian Stokes , bruce.richardson@intel.com, Sergey Temerkhanov Subject: [PATCH v2 104/148] net/ice/base: refactor ETH56G support for miltiple PHYs per MAC Date: Wed, 12 Jun 2024 16:01:38 +0100 Message-ID: X-Mailer: git-send-email 2.43.0 In-Reply-To: References: <20240430154014.1026-1-ian.stokes@intel.com> 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: Ian Stokes 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 | 18 ++- 4 files changed, 169 insertions(+), 88 deletions(-) diff --git a/drivers/net/ice/base/ice_ptp_hw.c b/drivers/net/ice/base/ice_ptp_hw.c index 5be4abb73d..07018279b6 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->phy_ports) 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->phy_ports) + 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); } /** @@ -2271,22 +2303,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; } @@ -2295,37 +2340,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 67ea9f9038..a00edc0ea6 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 */ -- 2.43.0