From: Jiawen Wu <jiawenwu@trustnetic.com>
To: dev@dpdk.org
Cc: Jiawen Wu <jiawenwu@trustnetic.com>, stable@dpdk.org
Subject: [PATCH 5/8] net/ngbe: add spinlock protection on YT PHY
Date: Wed, 18 Jan 2023 14:00:36 +0800 [thread overview]
Message-ID: <20230118060039.3074016-6-jiawenwu@trustnetic.com> (raw)
In-Reply-To: <20230118060039.3074016-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
next prev parent reply other threads:[~2023-01-18 6:04 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 ` Jiawen Wu [this message]
[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 ` [PATCH v2 06/10] net/ngbe: add spinlock protection on YT PHY Jiawen Wu
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=20230118060039.3074016-6-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).