patches for DPDK stable branches
 help / color / mirror / Atom feed
From: Jiawen Wu <jiawenwu@trustnetic.com>
To: dev@dpdk.org
Cc: Jiawen Wu <jiawenwu@trustnetic.com>, stable@dpdk.org
Subject: [PATCH 7/9] net/ngbe: redesign internal PHY init flow
Date: Mon, 30 May 2022 17:30:14 +0800	[thread overview]
Message-ID: <20220530093016.16326-8-jiawenwu@trustnetic.com> (raw)
In-Reply-To: <20220530093016.16326-1-jiawenwu@trustnetic.com>

Add to read efuse values from flash, and disable EEE to improve signal
quality. Remove PHY semaphore to access PHY registers faster. And remove
unnecessary page selection where quick access is required.

When rte_eth_link_get_nowait() is called frequently with LSC disabled by
self-developed applications, eventually the PHY status register will be
accessed frequently. It will cause internal PHY init failure, if they are
done simultaneously. So there is a protection added for internal PHY init.

Fixes: 3518df5774c7 ("net/ngbe: support device start/stop")
Fixes: 91bc12c5227c ("net/ngbe: optimize PHY initialization process")
Cc: stable@dpdk.org

Signed-off-by: Jiawen Wu <jiawenwu@trustnetic.com>
---
 drivers/net/ngbe/base/ngbe_hw.c      |  16 ++++
 drivers/net/ngbe/base/ngbe_hw.h      |   1 +
 drivers/net/ngbe/base/ngbe_phy.c     |  12 ---
 drivers/net/ngbe/base/ngbe_phy_rtl.c | 106 ++++++++++++++++++++-------
 drivers/net/ngbe/base/ngbe_type.h    |   2 +
 5 files changed, 100 insertions(+), 37 deletions(-)

diff --git a/drivers/net/ngbe/base/ngbe_hw.c b/drivers/net/ngbe/base/ngbe_hw.c
index facc1d9e82..c1114ba3b1 100644
--- a/drivers/net/ngbe/base/ngbe_hw.c
+++ b/drivers/net/ngbe/base/ngbe_hw.c
@@ -53,6 +53,7 @@ s32 ngbe_init_hw(struct ngbe_hw *hw)
 {
 	s32 status;
 
+	ngbe_read_efuse(hw);
 	ngbe_save_eeprom_version(hw);
 
 	/* Reset the hardware */
@@ -1855,6 +1856,21 @@ u32 ngbe_flash_read_dword(struct ngbe_hw *hw, u32 addr)
 	return rd32(hw, NGBE_SPIDAT);
 }
 
+void ngbe_read_efuse(struct ngbe_hw *hw)
+{
+	u32 efuse[2];
+	u8 lan_id = hw->bus.lan_id;
+
+	efuse[0] = ngbe_flash_read_dword(hw, 0xfe010 + lan_id * 8);
+	efuse[1] = ngbe_flash_read_dword(hw, 0xfe010 + lan_id * 8 + 4);
+
+	DEBUGOUT("port %d efuse[0] = %08x, efuse[1] = %08x\n",
+		lan_id, efuse[0], efuse[1]);
+
+	hw->gphy_efuse[0] = efuse[0];
+	hw->gphy_efuse[1] = efuse[1];
+}
+
 void ngbe_map_device_id(struct ngbe_hw *hw)
 {
 	u16 oem = hw->sub_system_id & NGBE_OEM_MASK;
diff --git a/drivers/net/ngbe/base/ngbe_hw.h b/drivers/net/ngbe/base/ngbe_hw.h
index 2813e72d60..b92a691fa0 100644
--- a/drivers/net/ngbe/base/ngbe_hw.h
+++ b/drivers/net/ngbe/base/ngbe_hw.h
@@ -83,6 +83,7 @@ s32 ngbe_init_phy(struct ngbe_hw *hw);
 s32 ngbe_enable_rx_dma(struct ngbe_hw *hw, u32 regval);
 void ngbe_map_device_id(struct ngbe_hw *hw);
 
+void ngbe_read_efuse(struct ngbe_hw *hw);
 u32 ngbe_fmgr_cmd_op(struct ngbe_hw *hw, u32 cmd, u32 cmd_addr);
 u32 ngbe_flash_read_dword(struct ngbe_hw *hw, u32 addr);
 
diff --git a/drivers/net/ngbe/base/ngbe_phy.c b/drivers/net/ngbe/base/ngbe_phy.c
index 84f2925e7e..06562b594f 100644
--- a/drivers/net/ngbe/base/ngbe_phy.c
+++ b/drivers/net/ngbe/base/ngbe_phy.c
@@ -290,16 +290,10 @@ s32 ngbe_read_phy_reg(struct ngbe_hw *hw, u32 reg_addr,
 			       u32 device_type, u16 *phy_data)
 {
 	s32 err;
-	u32 gssr = hw->phy.phy_semaphore_mask;
-
-	if (hw->mac.acquire_swfw_sync(hw, gssr))
-		return NGBE_ERR_SWFW_SYNC;
 
 	err = hw->phy.read_reg_unlocked(hw, reg_addr, device_type,
 					phy_data);
 
-	hw->mac.release_swfw_sync(hw, gssr);
-
 	return err;
 }
 
@@ -350,16 +344,10 @@ s32 ngbe_write_phy_reg(struct ngbe_hw *hw, u32 reg_addr,
 				u32 device_type, u16 phy_data)
 {
 	s32 err;
-	u32 gssr = hw->phy.phy_semaphore_mask;
-
-	if (hw->mac.acquire_swfw_sync(hw, gssr))
-		err = NGBE_ERR_SWFW_SYNC;
 
 	err = hw->phy.write_reg_unlocked(hw, reg_addr, device_type,
 					 phy_data);
 
-	hw->mac.release_swfw_sync(hw, gssr);
-
 	return err;
 }
 
diff --git a/drivers/net/ngbe/base/ngbe_phy_rtl.c b/drivers/net/ngbe/base/ngbe_phy_rtl.c
index 3a2d624ddb..33c5e79e87 100644
--- a/drivers/net/ngbe/base/ngbe_phy_rtl.c
+++ b/drivers/net/ngbe/base/ngbe_phy_rtl.c
@@ -14,7 +14,9 @@ s32 ngbe_read_phy_reg_rtl(struct ngbe_hw *hw,
 	reg.addr = reg_addr;
 	ngbe_mdi_map_register(&reg, &reg22);
 
-	wr32(hw, NGBE_PHY_CONFIG(RTL_PAGE_SELECT), reg22.page);
+	if (!(reg22.page == 0xa43 &&
+			(reg22.addr == 0x1a || reg22.addr == 0x1d)))
+		wr32(hw, NGBE_PHY_CONFIG(RTL_PAGE_SELECT), reg22.page);
 	*phy_data = 0xFFFF & rd32(hw, NGBE_PHY_CONFIG(reg22.addr));
 
 	return 0;
@@ -30,7 +32,9 @@ s32 ngbe_write_phy_reg_rtl(struct ngbe_hw *hw,
 	reg.addr = reg_addr;
 	ngbe_mdi_map_register(&reg, &reg22);
 
-	wr32(hw, NGBE_PHY_CONFIG(RTL_PAGE_SELECT), reg22.page);
+	if (!(reg22.page == 0xa43 &&
+			(reg22.addr == 0x1a || reg22.addr == 0x1d)))
+		wr32(hw, NGBE_PHY_CONFIG(RTL_PAGE_SELECT), reg22.page);
 	wr32(hw, NGBE_PHY_CONFIG(reg22.addr), phy_data);
 
 	return 0;
@@ -60,16 +64,61 @@ static void ngbe_phy_led_ctrl_rtl(struct ngbe_hw *hw)
 	hw->phy.write_reg(hw, RTL_LPCR, 0xd04, value);
 }
 
+static s32 ngbe_wait_mdio_access_on(struct ngbe_hw *hw)
+{
+	int i;
+	u16 val = 0;
+
+	for (i = 0; i < 100; i++) {
+		/* irq status */
+		hw->phy.read_reg(hw, RTL_INSR, 0xa43, &val);
+		if (val & RTL_INSR_ACCESS)
+			break;
+		msec_delay(1);
+	}
+
+	if (i == 100) {
+		DEBUGOUT("wait_mdio_access_on timeout");
+		return NGBE_ERR_PHY_TIMEOUT;
+	}
+
+	return 0;
+}
+
+static void ngbe_efuse_calibration(struct ngbe_hw *hw)
+{
+	u32 efuse[2];
+
+	ngbe_wait_mdio_access_on(hw);
+
+	efuse[0] = hw->gphy_efuse[0];
+	efuse[1] = hw->gphy_efuse[1];
+
+	if (!efuse[0] && !efuse[1]) {
+		efuse[0] = 0xFFFFFFFF;
+		efuse[1] = 0xFFFFFFFF;
+	}
+
+	/* calibration */
+	efuse[0] |= 0xF0000100;
+	efuse[1] |= 0xFF807FFF;
+	DEBUGOUT("port %d efuse[0] = %08x, efuse[1] = %08x",
+		hw->bus.lan_id, efuse[0], efuse[1]);
+
+	/* EODR, Efuse Output Data Register */
+	hw->phy.write_reg(hw, 16, 0xa46, (efuse[0] >>  0) & 0xFFFF);
+	hw->phy.write_reg(hw, 17, 0xa46, (efuse[0] >> 16) & 0xFFFF);
+	hw->phy.write_reg(hw, 18, 0xa46, (efuse[1] >>  0) & 0xFFFF);
+	hw->phy.write_reg(hw, 19, 0xa46, (efuse[1] >> 16) & 0xFFFF);
+}
+
 s32 ngbe_init_phy_rtl(struct ngbe_hw *hw)
 {
 	int i;
 	u16 value = 0;
 
-	/* enable interrupts, only link status change and an done is allowed */
-	value = RTL_INER_LSC | RTL_INER_ANC;
-	hw->phy.write_reg(hw, RTL_INER, 0xa42, value);
-
-	hw->phy.read_reg(hw, RTL_INSR, 0xa43, &value);
+	hw->init_phy = true;
+	msec_delay(1);
 
 	for (i = 0; i < 15; i++) {
 		if (!rd32m(hw, NGBE_STAT,
@@ -83,6 +132,8 @@ s32 ngbe_init_phy_rtl(struct ngbe_hw *hw)
 		return NGBE_ERR_PHY_TIMEOUT;
 	}
 
+	ngbe_efuse_calibration(hw);
+
 	hw->phy.write_reg(hw, RTL_SCR, 0xa46, RTL_SCR_EFUSE);
 	hw->phy.read_reg(hw, RTL_SCR, 0xa46, &value);
 	if (!(value & RTL_SCR_EFUSE)) {
@@ -90,15 +141,10 @@ s32 ngbe_init_phy_rtl(struct ngbe_hw *hw)
 		return NGBE_ERR_PHY_TIMEOUT;
 	}
 
-	for (i = 0; i < 1000; i++) {
-		hw->phy.read_reg(hw, RTL_INSR, 0xa43, &value);
-		if (value & RTL_INSR_ACCESS)
-			break;
-		msec_delay(1);
-	}
-	if (i == 1000)
-		DEBUGOUT("PHY wait mdio 1 access timeout.");
+	ngbe_wait_mdio_access_on(hw);
 
+	hw->phy.write_reg(hw, 27, 0xa42, 0x8011);
+	hw->phy.write_reg(hw, 28, 0xa42, 0x5737);
 
 	hw->phy.write_reg(hw, RTL_SCR, 0xa46, RTL_SCR_EXTINI);
 	hw->phy.read_reg(hw, RTL_SCR, 0xa46, &value);
@@ -107,24 +153,26 @@ s32 ngbe_init_phy_rtl(struct ngbe_hw *hw)
 		return NGBE_ERR_PHY_TIMEOUT;
 	}
 
-	for (i = 0; i < 1000; i++) {
-		hw->phy.read_reg(hw, RTL_INSR, 0xa43, &value);
-		if (value & RTL_INSR_ACCESS)
-			break;
-		msec_delay(1);
-	}
-	if (i == 1000)
-		DEBUGOUT("PHY wait mdio 2 access timeout.");
+	ngbe_wait_mdio_access_on(hw);
 
-	for (i = 0; i < 1000; i++) {
+	for (i = 0; i < 100; i++) {
 		hw->phy.read_reg(hw, RTL_GSR, 0xa42, &value);
 		if ((value & RTL_GSR_ST) == RTL_GSR_ST_LANON)
 			break;
 		msec_delay(1);
 	}
-	if (i == 1000)
+	if (i == 100)
 		return NGBE_ERR_PHY_TIMEOUT;
 
+	/* Disable EEE */
+	hw->phy.write_reg(hw, 0x11, 0xa4b, 0x1110);
+	hw->phy.write_reg(hw, 0xd, 0x0, 0x0007);
+	hw->phy.write_reg(hw, 0xe, 0x0, 0x003c);
+	hw->phy.write_reg(hw, 0xd, 0x0, 0x4007);
+	hw->phy.write_reg(hw, 0xe, 0x0, 0x0000);
+
+	hw->init_phy = false;
+
 	return 0;
 }
 
@@ -142,6 +190,9 @@ s32 ngbe_setup_phy_link_rtl(struct ngbe_hw *hw,
 
 	UNREFERENCED_PARAMETER(autoneg_wait_to_complete);
 
+	hw->init_phy = true;
+	msec_delay(1);
+
 	hw->phy.read_reg(hw, RTL_INSR, 0xa43, &autoneg_reg);
 
 	if (!hw->mac.autoneg) {
@@ -243,6 +294,8 @@ s32 ngbe_setup_phy_link_rtl(struct ngbe_hw *hw,
 skip_an:
 	ngbe_phy_led_ctrl_rtl(hw);
 
+	hw->init_phy = false;
+
 	return 0;
 }
 
@@ -309,6 +362,9 @@ s32 ngbe_check_phy_link_rtl(struct ngbe_hw *hw, u32 *speed, bool *link_up)
 	u16 phy_data = 0;
 	u16 insr = 0;
 
+	if (hw->init_phy)
+		return -1;
+
 	hw->phy.read_reg(hw, RTL_INSR, 0xa43, &insr);
 
 	/* Initialize speed and link to default case */
diff --git a/drivers/net/ngbe/base/ngbe_type.h b/drivers/net/ngbe/base/ngbe_type.h
index 666562bf22..0ad4766d2a 100644
--- a/drivers/net/ngbe/base/ngbe_type.h
+++ b/drivers/net/ngbe/base/ngbe_type.h
@@ -428,10 +428,12 @@ struct ngbe_hw {
 
 	u32 q_rx_regs[8 * 4];
 	u32 q_tx_regs[8 * 4];
+	u32 gphy_efuse[2];
 	bool offset_loaded;
 	bool is_pf;
 	bool gpio_ctl;
 	u32 led_conf;
+	bool init_phy;
 	struct {
 		u64 rx_qp_packets;
 		u64 tx_qp_packets;
-- 
2.27.0




  parent reply	other threads:[~2022-05-30  9:22 UTC|newest]

Thread overview: 8+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
     [not found] <20220530093016.16326-1-jiawenwu@trustnetic.com>
2022-05-30  9:30 ` [PATCH 1/9] net/ngbe: fix to set force speed Jiawen Wu
2022-05-30  9:30 ` [PATCH 3/9] net/ngbe: fix occasional failure of reading PHY ID Jiawen Wu
2022-05-30  9:30 ` [PATCH 4/9] net/ngbe: fix external PHY to power down Jiawen Wu
2022-05-30  9:30 ` [PATCH 5/9] net/ngbe: fix to read M88E1512 PHY mode Jiawen Wu
2022-05-30  9:30 ` [PATCH 6/9] net/ngbe: change PCIe related operations to use rte API Jiawen Wu
2022-05-30  9:30 ` Jiawen Wu [this message]
2022-05-30  9:30 ` [PATCH 8/9] net/txgbe: fix SGMII mode to link up Jiawen Wu
2022-05-30  9:30 ` [PATCH 9/9] net/txgbe: fix max number of queues for SRIOV Jiawen Wu

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=20220530093016.16326-8-jiawenwu@trustnetic.com \
    --to=jiawenwu@trustnetic.com \
    --cc=dev@dpdk.org \
    --cc=stable@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).