patch 'net/ngbe: add spinlock protection on YT PHY' has been queued to stable release 22.11.2

Xueming Li xuemingl at nvidia.com
Mon Feb 27 08:00:02 CET 2023


Hi,

FYI, your patch has been queued to stable release 22.11.2

Note it hasn't been pushed to http://dpdk.org/browse/dpdk-stable yet.
It will be pushed if I get no objections before 03/01/23. So please
shout if anyone has objections.

Also note that after the patch there's a diff of the upstream commit vs the
patch applied to the branch. This will indicate if there was any rebasing
needed to apply to the stable branch. If there were code changes for rebasing
(ie: not only metadata diffs), please double check that the rebase was
correctly done.

Queued patches are on a temporary branch at:
https://git.dpdk.org/dpdk-stable/log/?h=22.11-staging

This queued commit can be viewed at:
https://git.dpdk.org/dpdk-stable/commit/?h=22.11-staging&id=c22430a6e5ad6bb5f6b1975f64085b28ff53995b

Thanks.

Xueming Li <xuemingl at nvidia.com>

---
>From c22430a6e5ad6bb5f6b1975f64085b28ff53995b Mon Sep 17 00:00:00 2001
From: Jiawen Wu <jiawenwu at trustnetic.com>
Date: Thu, 2 Feb 2023 17:21:28 +0800
Subject: [PATCH] net/ngbe: add spinlock protection on YT PHY
Cc: Xueming Li <xuemingl at nvidia.com>

[ upstream commit 31a28a99fd8af98ceb4771c14dc0f4169f5fa991 ]

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")

Signed-off-by: Jiawen Wu <jiawenwu at 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 @@ skip_an:
 		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 @@ skip_an:
 			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 @@ skip_an:
 			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 @@ skip_an:
 		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 @@ skip_an:
 			}
 			/* 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 @@ skip_an:

 		/* 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.25.1

---
  Diff of the applied patch vs upstream commit (please double-check if non-empty:
---
--- -	2023-02-27 14:08:43.923887900 +0800
+++ 0095-net-ngbe-add-spinlock-protection-on-YT-PHY.patch	2023-02-27 14:08:40.829237000 +0800
@@ -1 +1 @@
-From 31a28a99fd8af98ceb4771c14dc0f4169f5fa991 Mon Sep 17 00:00:00 2001
+From c22430a6e5ad6bb5f6b1975f64085b28ff53995b Mon Sep 17 00:00:00 2001
@@ -4,0 +5,3 @@
+Cc: Xueming Li <xuemingl at nvidia.com>
+
+[ upstream commit 31a28a99fd8af98ceb4771c14dc0f4169f5fa991 ]
@@ -12 +14,0 @@
-Cc: stable at dpdk.org


More information about the stable mailing list