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 C8C7CA034C for ; Mon, 30 May 2022 11:22:29 +0200 (CEST) Received: from [217.70.189.124] (localhost [127.0.0.1]) by mails.dpdk.org (Postfix) with ESMTP id DC35A42BAD; Mon, 30 May 2022 11:22:27 +0200 (CEST) Received: from smtpbgeu2.qq.com (smtpbgeu2.qq.com [18.194.254.142]) by mails.dpdk.org (Postfix) with ESMTP id 39CB642B95 for ; Mon, 30 May 2022 11:22:25 +0200 (CEST) X-QQ-mid: bizesmtp87t1653902541tmcmn960 Received: from wxdbg.localdomain.com ( [183.129.236.74]) by bizesmtp.qq.com (ESMTP) with id ; Mon, 30 May 2022 17:22:21 +0800 (CST) X-QQ-SSF: 01400000000000F0P000000A0000000 X-QQ-FEAT: 4LFlwc+MlXlsXTK4kPGrSrRXwX20+NC9QVp3PLKz1orMzxHN2e/1dZn2Irr0s t/fSiwFlJbZcLOvWXPJS1nkffXgtId9pbUMgH4JFJxyo2H/JkA2PmgoMKCqfrccY9vXeiC2 dJ+u40bsVEEIJxOZO7iKjfz4Ssnda8NYfHl2V6Bm6pwWh73/2NEQ1JBPf0abHqa+CfwuKym b8aGa4wuMvvsYIT/Nq9LNUD6VHJfwYSID1ZPBCFlUZ/xW2IpHeCGiCmR5Dbr9amoBxRsn8o eLyk1pFxgTXbhjzd2cqEbCWGimW8tmo9QTzxeoBlMeqMkDHoM+9wmfdHKbxUppzpVUTohtI tTzT6jufQCRAcetYxARN+5pAhIUwYlU214eEdNZlnE1J4nw9Ts= X-QQ-GoodBg: 2 From: Jiawen Wu To: dev@dpdk.org Cc: Jiawen Wu , stable@dpdk.org Subject: [PATCH 7/9] net/ngbe: redesign internal PHY init flow Date: Mon, 30 May 2022 17:30:14 +0800 Message-Id: <20220530093016.16326-8-jiawenwu@trustnetic.com> X-Mailer: git-send-email 2.27.0 In-Reply-To: <20220530093016.16326-1-jiawenwu@trustnetic.com> References: <20220530093016.16326-1-jiawenwu@trustnetic.com> MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-QQ-SENDSIZE: 520 Feedback-ID: bizesmtp:trustnetic.com:qybgforeign:qybgforeign10 X-QQ-Bgrelay: 1 X-BeenThere: stable@dpdk.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: patches for DPDK stable branches List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: stable-bounces@dpdk.org 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 --- 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(®, ®22); - 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(®, ®22); - 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