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 v2 06/10] net/ngbe: add spinlock protection on YT PHY
Date: Thu,  2 Feb 2023 17:21:28 +0800	[thread overview]
Message-ID: <20230202092132.3271910-7-jiawenwu@trustnetic.com> (raw)
In-Reply-To: <20230202092132.3271910-1-jiawenwu@trustnetic.com>

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 <jiawenwu@trustnetic.com>
---
 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


  parent reply	other threads:[~2023-02-02  9:25 UTC|newest]

Thread overview: 27+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
     [not found] <20230118060039.3074016-1-jiawenwu@trustnetic.com>
2023-01-18  6:00 ` [PATCH 1/8] net/txgbe: fix Rx buffer size in configure register Jiawen Wu
2023-01-27 15:36   ` Ferruh Yigit
2023-02-01  2:34     ` Jiawen Wu
2023-02-01 10:40       ` Ferruh Yigit
2023-01-18  6:00 ` [PATCH 2/8] net/txgbe: fix default signal quality value for KX/KX4 Jiawen Wu
2023-01-18  6:00 ` [PATCH 3/8] net/txgbe: fix packet type to parse from offload flags Jiawen Wu
2023-01-27 15:36   ` Ferruh Yigit
2023-02-01  3:14     ` Jiawen Wu
2023-02-01 10:41       ` Ferruh Yigit
2023-01-18  6:00 ` [PATCH 4/8] net/ngbe: " Jiawen Wu
2023-01-27 15:37   ` Ferruh Yigit
2023-01-18  6:00 ` [PATCH 5/8] net/ngbe: add spinlock protection on YT PHY Jiawen Wu
     [not found] ` <20230202092132.3271910-1-jiawenwu@trustnetic.com>
2023-02-02  9:21   ` [PATCH v2 01/10] net/ngbe: fix Rx buffer size in configure register Jiawen Wu
2023-02-08 10:28     ` Ferruh Yigit
2023-02-09  9:00       ` Jiawen Wu
2023-02-14  8:15         ` Jiawen Wu
2023-02-14  9:55           ` Ferruh Yigit
2023-02-15  9:35             ` Ferruh Yigit
2023-02-15 10:09               ` Jiawen Wu
2023-02-02  9:21   ` [PATCH v2 02/10] net/txgbe: " Jiawen Wu
2023-02-02  9:21   ` [PATCH v2 03/10] net/txgbe: fix default signal quality value for KX/KX4 Jiawen Wu
2023-02-02  9:21   ` [PATCH v2 04/10] net/txgbe: fix packet type to parse from offload flags Jiawen Wu
2023-02-02  9:21   ` [PATCH v2 05/10] net/ngbe: " Jiawen Wu
2023-02-02  9:21   ` Jiawen Wu [this message]
2023-02-02  9:21   ` [PATCH v2 09/10] net/txgbe: fix interrupt loss Jiawen Wu
2023-02-15  2:00 ` [PATCH v3] net/txgbe: fix Rx buffer size in configure register Jiawen Wu
2023-02-15 10:24   ` Ferruh Yigit

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=20230202092132.3271910-7-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).