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 9197B454EF; Tue, 25 Jun 2024 13:25:33 +0200 (CEST) Received: from mails.dpdk.org (localhost [127.0.0.1]) by mails.dpdk.org (Postfix) with ESMTP id B8AF043265; Tue, 25 Jun 2024 13:18:38 +0200 (CEST) Received: from mgamail.intel.com (mgamail.intel.com [192.198.163.19]) by mails.dpdk.org (Postfix) with ESMTP id EA23642EDE for ; Tue, 25 Jun 2024 13:17:15 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1719314236; x=1750850236; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=tUeRDEdu2A0bT5isL1M9BTng4eU58QjC5N8hdp3ivA4=; b=MVGflULFv6rdH5t/zYnacI6Kle3jC7ak1JDUl4jFVtUUl4S/L3Vj1KaT uWq3xG7uzwjJc2qqFOYTEih/vY/ob6rURBYp/5u+dsjKFQvaWLASS1/d8 e1KWoOSB+9qZo76/eEwDjnvKtH9HDTo9cLqINFL83cbplEdaCJRisOGqf IpX727qPJT0/ucasm6GZmeHFm1+fIulA0DYhxQpC4IKMEuNgcTwrXn3Th VKjHPBTKE3v+X/hxJFAd278R5lFU12FRrq6pwfAYc+8GlItVlchyUJGTr gLojy9muv6OVzLgsYfNkMzKkkfD2gPLw6wq/WQXOcIhJPE4GHvdSeH2hq Q==; X-CSE-ConnectionGUID: rpc+Gk8ATICesfOV8gBzug== X-CSE-MsgGUID: B7navs1JRz+HPG2Gqq63VQ== X-IronPort-AV: E=McAfee;i="6700,10204,11113"; a="16080419" X-IronPort-AV: E=Sophos;i="6.08,263,1712646000"; d="scan'208";a="16080419" Received: from orviesa009.jf.intel.com ([10.64.159.149]) by fmvoesa113.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 25 Jun 2024 04:17:15 -0700 X-CSE-ConnectionGUID: 6Icf4B9eSGeSyocMu0pJXw== X-CSE-MsgGUID: QNvkIINxTja7WPrrWDhZZw== X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="6.08,263,1712646000"; d="scan'208";a="43719527" Received: from unknown (HELO silpixa00401119.ir.intel.com) ([10.55.129.167]) by orviesa009.jf.intel.com with ESMTP; 25 Jun 2024 04:17:15 -0700 From: Anatoly Burakov To: dev@dpdk.org Cc: Sergey Temerkhanov , bruce.richardson@intel.com, ian.stokes@intel.com Subject: [PATCH v3 085/129] net/ice/base: refactor ETH56G support for multiple PHYs per MAC Date: Tue, 25 Jun 2024 12:13:30 +0100 Message-ID: <6f07dc0ca548b8dd26aba01240f2488a6f9dcdcb.1719313663.git.anatoly.burakov@intel.com> 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 9e59eecd9b..52ce4720b8 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); } /** @@ -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 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