From patchwork Thu Feb 2 09:21:28 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jiawen Wu X-Patchwork-Id: 122899 X-Patchwork-Delegate: ferruh.yigit@amd.com Return-Path: X-Original-To: patchwork@inbox.dpdk.org Delivered-To: patchwork@inbox.dpdk.org Received: from mails.dpdk.org (mails.dpdk.org [217.70.189.124]) by inbox.dpdk.org (Postfix) with ESMTP id F3CC441BAB; Thu, 2 Feb 2023 10:26:16 +0100 (CET) Received: from mails.dpdk.org (localhost [127.0.0.1]) by mails.dpdk.org (Postfix) with ESMTP id 72CDD42DA0; Thu, 2 Feb 2023 10:25:57 +0100 (CET) Received: from smtpbgsg1.qq.com (smtpbgsg1.qq.com [54.254.200.92]) by mails.dpdk.org (Postfix) with ESMTP id 915AE42D65; Thu, 2 Feb 2023 10:25:55 +0100 (CET) X-QQ-mid: bizesmtp85t1675329952tjbdswig Received: from wxdbg.localdomain.com ( [183.129.236.74]) by bizesmtp.qq.com (ESMTP) with id ; Thu, 02 Feb 2023 17:25:51 +0800 (CST) X-QQ-SSF: 01400000002000H0Y000B00A0000000 X-QQ-FEAT: hoArX50alxEdFUrc3iWK3lc+56p6n8j9eWEDZM1jWobtBc4d4GYYyfmL4C5dc +HBLanWqtNHjYgsA29CfLGzrVn8gNR4uD4Kxl/6d7vN1YERC4uEHJ+9y4lkrO0dr/P7ha0w Ud7/62LmMBva6EhgmZqEuixNhWGBWVrexGGs3Z1cAU+uRdsCNvm7g65or1Ab9C7/MiJNwgG P64qGg+z7LNRsZos4x1BnE8FzRp7ZegeBbINu6AZQ7veRvS2VRYhQxDMMQ5xF78tXf/P57n WUo7bhR1RsP+SxaSqRXPqRgx4pHEiOUaGmIS4He+RvP4FId/IVO7Tjrxh42bs6gPn8dY2xG BsbA7Ecxh6yRlOhx1AuwiMf8A+58wFDy5QFQeIw7RpymQQR0MSIg+HaKm3Ox0PhfhAntvW5 BKkKfbyGJqGH7oXW2/i6tA== X-QQ-GoodBg: 2 From: Jiawen Wu To: dev@dpdk.org Cc: Jiawen Wu , stable@dpdk.org Subject: [PATCH v2 06/10] net/ngbe: add spinlock protection on YT PHY Date: Thu, 2 Feb 2023 17:21:28 +0800 Message-Id: <20230202092132.3271910-7-jiawenwu@trustnetic.com> X-Mailer: git-send-email 2.27.0 In-Reply-To: <20230202092132.3271910-1-jiawenwu@trustnetic.com> References: <20230118060039.3074016-1-jiawenwu@trustnetic.com> <20230202092132.3271910-1-jiawenwu@trustnetic.com> MIME-Version: 1.0 X-QQ-SENDSIZE: 520 Feedback-ID: bizesmtp:trustnetic.com:qybglogicsvr:qybglogicsvr5 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 For yt8521s/yt8531s PHY, if other registers are accessing between reads/writes of ext field registers, the value of ext filed registers will get weird for unknown reasons. So it's protected when all of ext field registers accessing. Fixes: 44e97550ca68 ("net/ngbe: identify and reset PHY") Cc: stable@dpdk.org Signed-off-by: Jiawen Wu --- drivers/net/ngbe/base/ngbe_phy_yt.c | 36 +++++++++++++++++++++++++++++ drivers/net/ngbe/base/ngbe_type.h | 1 + 2 files changed, 37 insertions(+) diff --git a/drivers/net/ngbe/base/ngbe_phy_yt.c b/drivers/net/ngbe/base/ngbe_phy_yt.c index c88946f7c3..726d6c8ef5 100644 --- a/drivers/net/ngbe/base/ngbe_phy_yt.c +++ b/drivers/net/ngbe/base/ngbe_phy_yt.c @@ -100,11 +100,15 @@ s32 ngbe_write_phy_reg_sds_ext_yt(struct ngbe_hw *hw, s32 ngbe_init_phy_yt(struct ngbe_hw *hw) { + rte_spinlock_init(&hw->phy_lock); + + rte_spinlock_lock(&hw->phy_lock); /* close sds area register */ ngbe_write_phy_reg_ext_yt(hw, YT_SMI_PHY, 0, 0); /* enable interrupts */ ngbe_write_phy_reg_mdi(hw, YT_INTR, 0, YT_INTR_ENA_MASK | YT_SDS_INTR_ENA_MASK); + rte_spinlock_unlock(&hw->phy_lock); hw->phy.set_phy_power(hw, false); @@ -123,7 +127,9 @@ s32 ngbe_setup_phy_link_yt(struct ngbe_hw *hw, u32 speed, hw->phy.autoneg_advertised = 0; /* check chip_mode first */ + rte_spinlock_lock(&hw->phy_lock); ngbe_read_phy_reg_ext_yt(hw, YT_CHIP, 0, &value); + rte_spinlock_unlock(&hw->phy_lock); if ((value & YT_CHIP_MODE_MASK) == YT_CHIP_MODE_SEL(0)) { /* UTP to rgmii */ if (!hw->mac.autoneg) { @@ -146,11 +152,14 @@ s32 ngbe_setup_phy_link_yt(struct ngbe_hw *hw, u32 speed, } /* duplex full */ value |= YT_BCR_DUPLEX | YT_BCR_RESET; + rte_spinlock_lock(&hw->phy_lock); ngbe_write_phy_reg_mdi(hw, YT_BCR, 0, value); + rte_spinlock_unlock(&hw->phy_lock); goto skip_an; } + rte_spinlock_lock(&hw->phy_lock); /*disable 100/10base-T Self-negotiation ability*/ ngbe_read_phy_reg_mdi(hw, YT_ANA, 0, &value); value &= ~(YT_ANA_100BASET_FULL | YT_ANA_100BASET_HALF | @@ -189,6 +198,7 @@ s32 ngbe_setup_phy_link_yt(struct ngbe_hw *hw, u32 speed, ngbe_read_phy_reg_mdi(hw, YT_BCR, 0, &value); value |= YT_BCR_RESET | YT_BCR_ANE | YT_BCR_RESTART_AN; ngbe_write_phy_reg_mdi(hw, YT_BCR, 0, value); + rte_spinlock_unlock(&hw->phy_lock); skip_an: hw->phy.set_phy_power(hw, true); } else if ((value & YT_CHIP_MODE_MASK) == YT_CHIP_MODE_SEL(1)) { @@ -199,6 +209,7 @@ s32 ngbe_setup_phy_link_yt(struct ngbe_hw *hw, u32 speed, value = YT_RGMII_CONF1_RXDELAY | YT_RGMII_CONF1_TXDELAY_FE | YT_RGMII_CONF1_TXDELAY; + rte_spinlock_lock(&hw->phy_lock); ngbe_write_phy_reg_ext_yt(hw, YT_RGMII_CONF1, 0, value); value = YT_CHIP_MODE_SEL(1) | YT_CHIP_SW_LDO_EN | @@ -225,17 +236,21 @@ s32 ngbe_setup_phy_link_yt(struct ngbe_hw *hw, u32 speed, value = YT_BCR_RESET | YT_BCR_DUPLEX | YT_BCR_SPEED_SELECT1; hw->phy.write_reg(hw, YT_BCR, 0, value); + rte_spinlock_unlock(&hw->phy_lock); hw->phy.set_phy_power(hw, true); } else if ((value & YT_CHIP_MODE_MASK) == YT_CHIP_MODE_SEL(2)) { hw->phy.set_phy_power(hw, true); + rte_spinlock_lock(&hw->phy_lock); hw->phy.read_reg(hw, YT_SPST, 0, &value); + rte_spinlock_unlock(&hw->phy_lock); if (value & YT_SPST_LINK) { /* fiber up */ hw->phy.autoneg_advertised |= NGBE_LINK_SPEED_1GB_FULL; } else { /* utp up */ + rte_spinlock_lock(&hw->phy_lock); /*disable 100/10base-T Self-negotiation ability*/ ngbe_read_phy_reg_mdi(hw, YT_ANA, 0, &value); value &= ~(YT_ANA_100BASET_FULL | YT_ANA_100BASET_HALF | @@ -279,10 +294,12 @@ s32 ngbe_setup_phy_link_yt(struct ngbe_hw *hw, u32 speed, ngbe_read_phy_reg_mdi(hw, YT_BCR, 0, &value); value |= YT_BCR_RESET; ngbe_write_phy_reg_mdi(hw, YT_BCR, 0, value); + rte_spinlock_unlock(&hw->phy_lock); } } else if ((value & YT_CHIP_MODE_MASK) == YT_CHIP_MODE_SEL(4)) { hw->phy.autoneg_advertised |= NGBE_LINK_SPEED_1GB_FULL; + rte_spinlock_lock(&hw->phy_lock); ngbe_read_phy_reg_ext_yt(hw, YT_RGMII_CONF1, 0, &value); value |= YT_RGMII_CONF1_MODE; ngbe_write_phy_reg_ext_yt(hw, YT_RGMII_CONF1, 0, value); @@ -297,6 +314,7 @@ s32 ngbe_setup_phy_link_yt(struct ngbe_hw *hw, u32 speed, ngbe_read_phy_reg_ext_yt(hw, YT_CHIP, 0, &value); value &= ~YT_SMI_PHY_SW_RST; ngbe_write_phy_reg_ext_yt(hw, YT_CHIP, 0, value); + rte_spinlock_unlock(&hw->phy_lock); hw->phy.set_phy_power(hw, true); } else if ((value & YT_CHIP_MODE_MASK) == YT_CHIP_MODE_SEL(5)) { @@ -320,7 +338,9 @@ s32 ngbe_setup_phy_link_yt(struct ngbe_hw *hw, u32 speed, } /* duplex full */ value |= YT_BCR_DUPLEX | YT_BCR_RESET; + rte_spinlock_lock(&hw->phy_lock); hw->phy.write_reg(hw, YT_BCR, 0, value); + rte_spinlock_unlock(&hw->phy_lock); goto skip_an_sr; } @@ -339,19 +359,23 @@ s32 ngbe_setup_phy_link_yt(struct ngbe_hw *hw, u32 speed, /* duplex full */ value |= YT_BCR_DUPLEX | YT_BCR_RESET; + rte_spinlock_lock(&hw->phy_lock); hw->phy.write_reg(hw, YT_BCR, 0, value); /* software reset to make the above configuration take effect */ hw->phy.read_reg(hw, YT_BCR, 0, &value); value |= YT_BCR_RESET | YT_BCR_ANE | YT_BCR_RESTART_AN; hw->phy.write_reg(hw, 0x0, 0, value); + rte_spinlock_unlock(&hw->phy_lock); skip_an_sr: hw->phy.set_phy_power(hw, true); } + rte_spinlock_lock(&hw->phy_lock); ngbe_write_phy_reg_ext_yt(hw, YT_SMI_PHY, 0, 0); ngbe_read_phy_reg_mdi(hw, YT_INTR_STATUS, 0, &value); + rte_spinlock_unlock(&hw->phy_lock); return 0; } @@ -366,6 +390,7 @@ s32 ngbe_reset_phy_yt(struct ngbe_hw *hw) hw->phy.type != ngbe_phy_yt8521s_sfi) return NGBE_ERR_PHY_TYPE; + rte_spinlock_lock(&hw->phy_lock); /* check chip_mode first */ ngbe_read_phy_reg_ext_yt(hw, YT_CHIP, 0, &ctrl); if (ctrl & YT_CHIP_MODE_MASK) { @@ -395,6 +420,7 @@ s32 ngbe_reset_phy_yt(struct ngbe_hw *hw) msleep(1); } } + rte_spinlock_unlock(&hw->phy_lock); if (i == YT_PHY_RST_WAIT_PERIOD) { DEBUGOUT("PHY reset polling failed to complete."); @@ -409,7 +435,9 @@ s32 ngbe_get_phy_advertised_pause_yt(struct ngbe_hw *hw, u8 *pause_bit) u16 value; s32 status = 0; + rte_spinlock_lock(&hw->phy_lock); status = hw->phy.read_reg(hw, YT_ANA, 0, &value); + rte_spinlock_unlock(&hw->phy_lock); value &= YT_FANA_PAUSE_MASK; *pause_bit = (u8)(value >> 7); @@ -421,7 +449,9 @@ s32 ngbe_get_phy_lp_advertised_pause_yt(struct ngbe_hw *hw, u8 *pause_bit) u16 value; s32 status = 0; + rte_spinlock_lock(&hw->phy_lock); status = hw->phy.read_reg(hw, YT_LPAR, 0, &value); + rte_spinlock_unlock(&hw->phy_lock); value &= YT_FLPAR_PAUSE_MASK; *pause_bit = (u8)(value >> 7); @@ -433,10 +463,12 @@ s32 ngbe_set_phy_pause_adv_yt(struct ngbe_hw *hw, u16 pause_bit) u16 value; s32 status = 0; + rte_spinlock_lock(&hw->phy_lock); status = hw->phy.read_reg(hw, YT_ANA, 0, &value); value &= ~YT_FANA_PAUSE_MASK; value |= pause_bit; status = hw->phy.write_reg(hw, YT_ANA, 0, value); + rte_spinlock_unlock(&hw->phy_lock); return status; } @@ -453,6 +485,7 @@ s32 ngbe_check_phy_link_yt(struct ngbe_hw *hw, /* Initialize speed and link to default case */ *link_up = false; *speed = NGBE_LINK_SPEED_UNKNOWN; + rte_spinlock_lock(&hw->phy_lock); ngbe_write_phy_reg_ext_yt(hw, YT_SMI_PHY, 0, 0); ngbe_read_phy_reg_mdi(hw, YT_INTR_STATUS, 0, &insr); @@ -472,6 +505,7 @@ s32 ngbe_check_phy_link_yt(struct ngbe_hw *hw, *link_up = true; } + rte_spinlock_unlock(&hw->phy_lock); if (*link_up) { if (phy_speed == YT_SPST_SPEED_1000M) *speed = NGBE_LINK_SPEED_1GB_FULL; @@ -488,6 +522,7 @@ s32 ngbe_set_phy_power_yt(struct ngbe_hw *hw, bool on) { u16 value = 0; + rte_spinlock_lock(&hw->phy_lock); /* power down/up in fiber mode */ hw->phy.read_reg(hw, YT_BCR, 0, &value); if (on) @@ -504,6 +539,7 @@ s32 ngbe_set_phy_power_yt(struct ngbe_hw *hw, bool on) else value |= YT_BCR_PWDN; ngbe_write_phy_reg_mdi(hw, YT_BCR, 0, value); + rte_spinlock_unlock(&hw->phy_lock); return 0; } diff --git a/drivers/net/ngbe/base/ngbe_type.h b/drivers/net/ngbe/base/ngbe_type.h index aa5c41146c..05804eeab7 100644 --- a/drivers/net/ngbe/base/ngbe_type.h +++ b/drivers/net/ngbe/base/ngbe_type.h @@ -433,6 +433,7 @@ struct ngbe_hw { bool gpio_ctl; u32 led_conf; bool init_phy; + rte_spinlock_t phy_lock; struct { u64 rx_qp_packets; u64 tx_qp_packets;