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 2FA7242409 for ; Wed, 18 Jan 2023 07:04:26 +0100 (CET) Received: from mails.dpdk.org (localhost [127.0.0.1]) by mails.dpdk.org (Postfix) with ESMTP id C98C6410EE; Wed, 18 Jan 2023 07:04:24 +0100 (CET) Received: from smtpbg156.qq.com (smtpbg156.qq.com [15.184.82.18]) by mails.dpdk.org (Postfix) with ESMTP id EA76742D59; Wed, 18 Jan 2023 07:04:20 +0100 (CET) X-QQ-mid: bizesmtp69t1674021857tdpi4o0m Received: from wxdbg.localdomain.com ( [183.129.236.74]) by bizesmtp.qq.com (ESMTP) with id ; Wed, 18 Jan 2023 14:04:16 +0800 (CST) X-QQ-SSF: 01400000000000H0X000B00A0000000 X-QQ-FEAT: FVl8EHhfVR7uhbB1A9ra2Qpk4/PxebGUOEhy4y3z18OFkrpES4q+J1UumQihH 0/ev6kf+9O0A2LAkMXcUf6SJGoN4KhcNOUTNEEGnbWRr6d/XY8OJODHTWAqsDX4x6n8bjuI W5c30UDg5jfbLLxa0f0MQPsFAPSRN7LdSjpSI44D+saW9QVKGTH3WEW1o9x1ff94FCwwpLH mLnWvTWLWG23yJn03hlEO5y8cKSpc5m/JIXHDq4pqiciL/RX2yV9VUBcmASy19TRmv1aVjy BwYNKo8t/C2dBSwAcspC9B6W5DFxIXXHzBWc4Wj51OvAIyRW7zjToHFlYM3KdMv9Ff1rg4i I+ib8q4PITWPGQaP5myhHcz2TXq77UBH/wjP050F/3Un4wvgCj9XmtImG2kGy8BwE+WwXGG X-QQ-GoodBg: 2 From: Jiawen Wu To: dev@dpdk.org Cc: Jiawen Wu , stable@dpdk.org Subject: [PATCH 5/8] net/ngbe: add spinlock protection on YT PHY Date: Wed, 18 Jan 2023 14:00:36 +0800 Message-Id: <20230118060039.3074016-6-jiawenwu@trustnetic.com> X-Mailer: git-send-email 2.27.0 In-Reply-To: <20230118060039.3074016-1-jiawenwu@trustnetic.com> References: <20230118060039.3074016-1-jiawenwu@trustnetic.com> MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-QQ-SENDSIZE: 520 Feedback-ID: bizesmtp:trustnetic.com:qybglogicsvr:qybglogicsvr5 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 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; -- 2.27.0