DPDK patches and discussions
 help / color / mirror / Atom feed
From: Anatoly Burakov <anatoly.burakov@intel.com>
To: dev@dpdk.org
Subject: [PATCH v1 06/42] net/e1000/base: add LTR support in i225
Date: Fri, 31 Jan 2025 12:58:19 +0000	[thread overview]
Message-ID: <0ba8b622e01876dc7f63c93cdda637182eaeae9a.1738328107.git.anatoly.burakov@intel.com> (raw)
In-Reply-To: <cover.1738328106.git.anatoly.burakov@intel.com>

Enable Latency Tolerance Reporting (LTR) code and add its associated
definitions for i225. This is mostly identical to IGC driver, with some
minor differences due to the way IGC driver was originally generated.

Signed-off-by: Anatoly Burakov <anatoly.burakov@intel.com>
---
 drivers/net/intel/e1000/base/e1000_defines.h |  31 +++
 drivers/net/intel/e1000/base/e1000_i225.c    | 188 ++++++++++++++++++-
 drivers/net/intel/e1000/base/e1000_i225.h    |   2 +
 drivers/net/intel/e1000/base/e1000_regs.h    |   3 +-
 4 files changed, 222 insertions(+), 2 deletions(-)

diff --git a/drivers/net/intel/e1000/base/e1000_defines.h b/drivers/net/intel/e1000/base/e1000_defines.h
index 49e4f6c7cc..10009d7a19 100644
--- a/drivers/net/intel/e1000/base/e1000_defines.h
+++ b/drivers/net/intel/e1000/base/e1000_defines.h
@@ -1491,6 +1491,37 @@
 #define I210_RXPBSIZE_DEFAULT		0x000000A2 /* RXPBSIZE default */
 #define I210_TXPBSIZE_DEFAULT		0x04000014 /* TXPBSIZE default */
 
+#define E1000_LTRC_EEEMS_EN		0x00000020 /* Enable EEE LTR max send */
+/* Minimum time for 1000BASE-T where no data will be transmit following move out
+ * of EEE LPI Tx state
+ */
+#define E1000_TW_SYSTEM_1000_MASK	0x000000FF
+/* Minimum time for 100BASE-T where no data will be transmit following move out
+ * of EEE LPI Tx state
+ */
+#define E1000_TW_SYSTEM_100_MASK	0x0000FF00
+#define E1000_TW_SYSTEM_100_SHIFT	8
+#define E1000_LTRMINV_LTRV_MASK		0x000003FF /* LTR minimum value */
+#define E1000_LTRMAXV_LTRV_MASK		0x000003FF /* LTR maximum value */
+#define E1000_LTRMINV_SCALE_MASK	0x00001C00 /* LTR minimum scale */
+#define E1000_LTRMINV_SCALE_SHIFT	10
+/* Reg val to set scale to 1024 nsec */
+#define E1000_LTRMINV_SCALE_1024	2
+/* Reg val to set scale to 32768 nsec */
+#define E1000_LTRMINV_SCALE_32768	3
+#define E1000_LTRMINV_LSNP_REQ		0x00008000 /* LTR Snoop Requirement */
+#define E1000_LTRMAXV_SCALE_MASK	0x00001C00 /* LTR maximum scale */
+#define E1000_LTRMAXV_SCALE_SHIFT	10
+/* Reg val to set scale to 1024 nsec */
+#define E1000_LTRMAXV_SCALE_1024	2
+/* Reg val to set scale to 32768 nsec */
+#define E1000_LTRMAXV_SCALE_32768	3
+#define E1000_LTRMAXV_LSNP_REQ		0x00008000 /* LTR Snoop Requirement */
+
+#define I225_RXPBSIZE_DEFAULT		0x000000A2 /* RXPBSIZE default */
+#define I225_TXPBSIZE_DEFAULT		0x04000014 /* TXPBSIZE default */
+#define E1000_RXPBS_SIZE_I225_MASK	0x0000003F /* Rx packet buffer size */
+#define E1000_TXPB0S_SIZE_I225_MASK	0x0000003F /* Tx packet buffer 0 size */
 #define E1000_STM_OPCODE		0xDB00
 #define E1000_EEPROM_FLASH_SIZE_WORD	0x11
 #define INVM_DWORD_TO_RECORD_TYPE(invm_dword) \
diff --git a/drivers/net/intel/e1000/base/e1000_i225.c b/drivers/net/intel/e1000/base/e1000_i225.c
index 7c8cf8552d..9a512f3baf 100644
--- a/drivers/net/intel/e1000/base/e1000_i225.c
+++ b/drivers/net/intel/e1000/base/e1000_i225.c
@@ -102,7 +102,8 @@ STATIC s32 e1000_init_mac_params_i225(struct e1000_hw *hw)
 	mac->ops.init_hw = e1000_init_hw_i225;
 	/* link setup */
 	mac->ops.setup_link = e1000_setup_link_generic;
-	mac->ops.check_for_link = e1000_check_for_copper_link_generic;
+	/* check for link */
+	mac->ops.check_for_link = e1000_check_for_link_i225;
 	/* link info */
 	mac->ops.get_link_up_info = e1000_get_speed_and_duplex_copper_generic;
 	/* acquire SW_FW sync */
@@ -907,6 +908,191 @@ s32 e1000_pool_flash_update_done_i225(struct e1000_hw *hw)
 	return ret_val;
 }
 
+/* e1000_set_ltr_i225 - Set Latency Tolerance Reporting thresholds.
+ * @hw: pointer to the HW structure
+ * @link: bool indicating link status
+ *
+ * Set the LTR thresholds based on the link speed (Mbps), EEE, and DMAC
+ * settings, otherwise specify that there is no LTR requirement.
+ */
+s32 e1000_set_ltr_i225(struct e1000_hw *hw, bool link)
+{
+	u16 speed, duplex;
+	u32 tw_system, ltrc, ltrv, ltr_min, ltr_max, scale_min, scale_max;
+	s32 size;
+
+	DEBUGFUNC("e1000_set_ltr_i225");
+
+	/* If we do not have link, LTR thresholds are zero. */
+	if (link) {
+		hw->mac.ops.get_link_up_info(hw, &speed, &duplex);
+
+		/* Check if using copper interface with EEE enabled or if the
+		 * link speed is 10 Mbps.
+		 */
+		if ((hw->phy.media_type == e1000_media_type_copper) &&
+		    !(hw->dev_spec._i225.eee_disable) &&
+		     (speed != SPEED_10)) {
+			/* EEE enabled, so send LTRMAX threshold. */
+			ltrc = E1000_READ_REG(hw, E1000_LTRC) |
+				E1000_LTRC_EEEMS_EN;
+			E1000_WRITE_REG(hw, E1000_LTRC, ltrc);
+
+			/* Calculate tw_system (nsec). */
+			if (speed == SPEED_100) {
+				tw_system = ((E1000_READ_REG(hw, E1000_EEE_SU) &
+					     E1000_TW_SYSTEM_100_MASK) >>
+					     E1000_TW_SYSTEM_100_SHIFT) * 500;
+			} else {
+				tw_system = (E1000_READ_REG(hw, E1000_EEE_SU) &
+					     E1000_TW_SYSTEM_1000_MASK) * 500;
+				}
+		} else {
+			tw_system = 0;
+			}
+
+		/* Get the Rx packet buffer size. */
+		size = E1000_READ_REG(hw, E1000_RXPBS) &
+			E1000_RXPBS_SIZE_I225_MASK;
+
+		/* Calculations vary based on DMAC settings. */
+		if (E1000_READ_REG(hw, E1000_DMACR) & E1000_DMACR_DMAC_EN) {
+			size -= (E1000_READ_REG(hw, E1000_DMACR) &
+				 E1000_DMACR_DMACTHR_MASK) >>
+				 E1000_DMACR_DMACTHR_SHIFT;
+			/* Convert size to bits. */
+			size *= 1024 * 8;
+		} else {
+			/* Convert size to bytes, subtract the MTU, and then
+			 * convert the size to bits.
+			 */
+			size *= 1024;
+			size -= hw->dev_spec._i225.mtu;
+			size *= 8;
+		}
+
+		if (size < 0) {
+			DEBUGOUT1("Invalid effective Rx buffer size %d\n",
+				  size);
+			return -E1000_ERR_CONFIG;
+		}
+
+		/* Calculate the thresholds. Since speed is in Mbps, simplify
+		 * the calculation by multiplying size/speed by 1000 for result
+		 * to be in nsec before dividing by the scale in nsec. Set the
+		 * scale such that the LTR threshold fits in the register.
+		 */
+		ltr_min = (1000 * size) / speed;
+		ltr_max = ltr_min + tw_system;
+		scale_min = (ltr_min / 1024) < 1024 ? E1000_LTRMINV_SCALE_1024 :
+			    E1000_LTRMINV_SCALE_32768;
+		scale_max = (ltr_max / 1024) < 1024 ? E1000_LTRMAXV_SCALE_1024 :
+			    E1000_LTRMAXV_SCALE_32768;
+		ltr_min /= scale_min == E1000_LTRMINV_SCALE_1024 ? 1024 : 32768;
+		ltr_min -= 1;
+		ltr_max /= scale_max == E1000_LTRMAXV_SCALE_1024 ? 1024 : 32768;
+		ltr_max -= 1;
+
+		/* Only write the LTR thresholds if they differ from before. */
+		ltrv = E1000_READ_REG(hw, E1000_LTRMINV);
+		if (ltr_min != (ltrv & E1000_LTRMINV_LTRV_MASK)) {
+			ltrv = E1000_LTRMINV_LSNP_REQ | ltr_min |
+			      (scale_min << E1000_LTRMINV_SCALE_SHIFT);
+			E1000_WRITE_REG(hw, E1000_LTRMINV, ltrv);
+		}
+
+		ltrv = E1000_READ_REG(hw, E1000_LTRMAXV);
+		if (ltr_max != (ltrv & E1000_LTRMAXV_LTRV_MASK)) {
+			ltrv = E1000_LTRMAXV_LSNP_REQ | ltr_max |
+			      (scale_max << E1000_LTRMAXV_SCALE_SHIFT);
+			E1000_WRITE_REG(hw, E1000_LTRMAXV, ltrv);
+		}
+	}
+
+	return E1000_SUCCESS;
+}
+
+/* e1000_check_for_link_i225 - Check for link
+ * @hw: pointer to the HW structure
+ *
+ * Checks to see of the link status of the hardware has changed.  If a
+ * change in link status has been detected, then we read the PHY registers
+ * to get the current speed/duplex if link exists.
+ */
+s32 e1000_check_for_link_i225(struct e1000_hw *hw)
+{
+	struct e1000_mac_info *mac = &hw->mac;
+	s32 ret_val;
+	bool link = false;
+
+	DEBUGFUNC("e1000_check_for_link_i225");
+
+	/* We only want to go out to the PHY registers to see if
+	 * Auto-Neg has completed and/or if our link status has
+	 * changed.  The get_link_status flag is set upon receiving
+	 * a Link Status Change or Rx Sequence Error interrupt.
+	 */
+	if (!mac->get_link_status)
+		goto out;
+
+	/* First we want to see if the MII Status Register reports
+	 * link.  If so, then we want to get the current speed/duplex
+	 * of the PHY.
+	 */
+	ret_val = e1000_phy_has_link_generic(hw, 1, 0, &link);
+	if (ret_val)
+		goto out;
+
+	if (!link)
+		goto out; /* No link detected */
+
+	/* First we want to see if the MII Status Register reports
+	 * link.  If so, then we want to get the current speed/duplex
+	 * of the PHY.
+	 */
+	ret_val = e1000_phy_has_link_generic(hw, 1, 0, &link);
+	if (ret_val)
+		goto out;
+
+	if (!link)
+		goto out; /* No link detected */
+
+	mac->get_link_status = false;
+
+	/* Check if there was DownShift, must be checked
+	 * immediately after link-up
+	 */
+	e1000_check_downshift_generic(hw);
+
+	/* If we are forcing speed/duplex, then we simply return since
+	 * we have already determined whether we have link or not.
+	 */
+	if (!mac->autoneg)
+		goto out;
+
+	/* Auto-Neg is enabled.  Auto Speed Detection takes care
+	 * of MAC speed/duplex configuration.  So we only need to
+	 * configure Collision Distance in the MAC.
+	 */
+	mac->ops.config_collision_dist(hw);
+
+	/* Configure Flow Control now that Auto-Neg has completed.
+	 * First, we need to restore the desired flow control
+	 * settings because we may have had to re-autoneg with a
+	 * different link partner.
+	 */
+	ret_val = e1000_config_fc_after_link_up_generic(hw);
+	if (ret_val)
+		DEBUGOUT("Error configuring flow control\n");
+out:
+	/* Now that we are aware of our link settings, we can set the LTR
+	 * thresholds.
+	 */
+	ret_val = e1000_set_ltr_i225(hw, link);
+
+	return ret_val;
+}
+
 /* e1000_init_function_pointers_i225 - Init func ptrs.
  * @hw: pointer to the HW structure
  *
diff --git a/drivers/net/intel/e1000/base/e1000_i225.h b/drivers/net/intel/e1000/base/e1000_i225.h
index be3b1b76eb..cd6e7d0f6f 100644
--- a/drivers/net/intel/e1000/base/e1000_i225.h
+++ b/drivers/net/intel/e1000/base/e1000_i225.h
@@ -19,6 +19,8 @@ s32 e1000_write_erase_flash_command_i225(struct e1000_hw *hw, u32 opcode,
 					 u32 address);
 s32 e1000_id_led_init_i225(struct e1000_hw *hw);
 s32 e1000_blink_led_i225(struct e1000_hw *hw);
+s32 e1000_check_for_link_i225(struct e1000_hw *hw);
+s32 e1000_set_ltr_i225(struct e1000_hw *hw, bool link);
 s32 e1000_acquire_swfw_sync_i225(struct e1000_hw *hw, u16 mask);
 void e1000_release_swfw_sync_i225(struct e1000_hw *hw, u16 mask);
 s32 e1000_init_hw_i225(struct e1000_hw *hw);
diff --git a/drivers/net/intel/e1000/base/e1000_regs.h b/drivers/net/intel/e1000/base/e1000_regs.h
index b9d2a4484b..04bb94f819 100644
--- a/drivers/net/intel/e1000/base/e1000_regs.h
+++ b/drivers/net/intel/e1000/base/e1000_regs.h
@@ -697,6 +697,7 @@
 #define E1000_O2BGPTC	0x08FE4 /* OS2BMC packets received by BMC */
 #define E1000_O2BSPC	0x0415C /* OS2BMC packets transmitted by host */
 
-
+#define E1000_LTRMINV	0x5BB0 /* LTR Minimum Value */
+#define E1000_LTRMAXV	0x5BB4 /* LTR Maximum Value */
 
 #endif
-- 
2.43.5


  parent reply	other threads:[~2025-01-31 13:00 UTC|newest]

Thread overview: 45+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2025-01-31 12:58 [PATCH v1 00/42] Merge Intel IGC and E1000 drivers, and update E1000 base code Anatoly Burakov
2025-01-31 12:58 ` [PATCH v1 01/42] net/e1000/base: fix semaphore timeout value Anatoly Burakov
2025-01-31 12:58 ` [PATCH v1 02/42] net/e1000/base: add initial support for i225 Anatoly Burakov
2025-01-31 12:58 ` [PATCH v1 03/42] net/e1000/base: add link bringup " Anatoly Burakov
2025-01-31 12:58 ` [PATCH v1 04/42] net/e1000/base: add LED blink " Anatoly Burakov
2025-01-31 12:58 ` [PATCH v1 05/42] net/e1000/base: add NVM/EEPROM " Anatoly Burakov
2025-01-31 12:58 ` Anatoly Burakov [this message]
2025-01-31 12:58 ` [PATCH v1 07/42] net/e1000/base: add eee " Anatoly Burakov
2025-01-31 12:58 ` [PATCH v1 08/42] net/e1000/base: add misc definitions " Anatoly Burakov
2025-01-31 12:58 ` [PATCH v1 09/42] net/e1000: merge igc with e1000 Anatoly Burakov
2025-01-31 12:58 ` [PATCH v1 10/42] net/e1000: add missing i225 devices Anatoly Burakov
2025-01-31 12:58 ` [PATCH v1 11/42] net/e1000: add missing hardware support Anatoly Burakov
2025-01-31 12:58 ` [PATCH v1 12/42] net/e1000: add support for more I219 devices Anatoly Burakov
2025-01-31 12:58 ` [PATCH v1 13/42] net/e1000/base: correct minor formatting issues Anatoly Burakov
2025-01-31 12:58 ` [PATCH v1 14/42] net/e1000/base: correct mPHY access logic Anatoly Burakov
2025-01-31 12:58 ` [PATCH v1 15/42] net/e1000/base: skip MANC check for 82575 Anatoly Burakov
2025-01-31 12:58 ` [PATCH v1 16/42] net/e1000/base: correct disable k1 logic Anatoly Burakov
2025-01-31 12:58 ` [PATCH v1 17/42] net/e1000/base: workaround for packet loss Anatoly Burakov
2025-01-31 12:58 ` [PATCH v1 18/42] net/e1000/base: add EEE common API function Anatoly Burakov
2025-01-31 12:58 ` [PATCH v1 19/42] net/e1000/base: add queue select definitions Anatoly Burakov
2025-01-31 12:58 ` [PATCH v1 20/42] net/e1000/base: add profile information field Anatoly Burakov
2025-01-31 12:58 ` [PATCH v1 21/42] net/e1000/base: add LPI counters Anatoly Burakov
2025-01-31 12:58 ` [PATCH v1 22/42] net/e1000/base: improve code flow in ICH8LAN Anatoly Burakov
2025-01-31 12:58 ` [PATCH v1 23/42] net/e1000/base: add definition for EXFWSM register Anatoly Burakov
2025-01-31 12:58 ` [PATCH v1 24/42] net/e1000/base: use longer ULP exit timeout on more HW Anatoly Burakov
2025-01-31 12:58 ` [PATCH v1 25/42] net/e1000/base: make e1000_access_phy_wakeup_reg_bm non-static Anatoly Burakov
2025-01-31 12:58 ` [PATCH v1 26/42] net/e1000/base: make debug prints more informative Anatoly Burakov
2025-01-31 12:58 ` [PATCH v1 27/42] net/e1000/base: add WoL definitions Anatoly Burakov
2025-01-31 12:58 ` [PATCH v1 28/42] net/e1000/base: hardcode bus parameters for ICH8 Anatoly Burakov
2025-01-31 12:58 ` [PATCH v1 29/42] net/e1000/base: improve NVM checksum handling Anatoly Burakov
2025-01-31 12:58 ` [PATCH v1 30/42] net/e1000/base: remove redundant access to RO register Anatoly Burakov
2025-01-31 12:58 ` [PATCH v1 31/42] net/e1000/base: remove non-inclusive language Anatoly Burakov
2025-01-31 12:58 ` [PATCH v1 32/42] net/e1000/base: introduce PHY ID retry mechanism Anatoly Burakov
2025-01-31 12:58 ` [PATCH v1 33/42] net/e1000/base: add PHY read/write " Anatoly Burakov
2025-01-31 12:58 ` [PATCH v1 34/42] net/e1000/base: fix iterator type Anatoly Burakov
2025-01-31 12:58 ` [PATCH v1 35/42] net/e1000/base: fix static analysis warnings Anatoly Burakov
2025-01-31 12:58 ` [PATCH v1 36/42] net/e1000/base: fix reset for 82580 Anatoly Burakov
2025-01-31 12:58 ` [PATCH v1 37/42] net/e1000/base: fix mac addr hash bit_shift Anatoly Burakov
2025-01-31 12:58 ` [PATCH v1 38/42] net/e1000/base: fix uninitialized variable usage Anatoly Burakov
2025-01-31 12:58 ` [PATCH v1 39/42] net/e1000/base: fix unchecked return Anatoly Burakov
2025-01-31 12:58 ` [PATCH v1 40/42] net/e1000/base: fix data type in MAC hash Anatoly Burakov
2025-01-31 12:58 ` [PATCH v1 41/42] net/e1000/base: rename NVM version variable Anatoly Burakov
2025-01-31 12:58 ` [PATCH v1 42/42] net/e1000/base: update readme Anatoly Burakov
2025-01-31 13:11 ` [PATCH v1 00/42] Merge Intel IGC and E1000 drivers, and update E1000 base code Bruce Richardson
2025-01-31 13:13   ` David Marchand

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=0ba8b622e01876dc7f63c93cdda637182eaeae9a.1738328107.git.anatoly.burakov@intel.com \
    --to=anatoly.burakov@intel.com \
    --cc=dev@dpdk.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).