Don't assume that only the driver would be accessing LNKCTL. ASPM policy changes can trigger write to LNKCTL outside of driver's control. Use pcie_lnkctl_clear_and_set() which does proper locking to avoid losing concurrent updates to the register value. Suggested-by: Lukas Wunner <lukas@xxxxxxxxx> Signed-off-by: Ilpo Järvinen <ilpo.jarvinen@xxxxxxxxxxxxxxx> --- drivers/net/ethernet/broadcom/tg3.c | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/drivers/net/ethernet/broadcom/tg3.c b/drivers/net/ethernet/broadcom/tg3.c index 58747292521d..f3b30e7af25d 100644 --- a/drivers/net/ethernet/broadcom/tg3.c +++ b/drivers/net/ethernet/broadcom/tg3.c @@ -4027,8 +4027,7 @@ static int tg3_power_down_prepare(struct tg3 *tp) /* Restore the CLKREQ setting. */ if (tg3_flag(tp, CLKREQ_BUG)) - pcie_capability_set_word(tp->pdev, PCI_EXP_LNKCTL, - PCI_EXP_LNKCTL_CLKREQ_EN); + pcie_lnkctl_clear_and_set(tp->pdev, 0, PCI_EXP_LNKCTL_CLKREQ_EN); misc_host_ctrl = tr32(TG3PCI_MISC_HOST_CTRL); tw32(TG3PCI_MISC_HOST_CTRL, @@ -5069,13 +5068,14 @@ static int tg3_setup_copper_phy(struct tg3 *tp, bool force_reset) /* Prevent send BD corruption. */ if (tg3_flag(tp, CLKREQ_BUG)) { + u16 clkreq = 0; + if (tp->link_config.active_speed == SPEED_100 || tp->link_config.active_speed == SPEED_10) - pcie_capability_clear_word(tp->pdev, PCI_EXP_LNKCTL, - PCI_EXP_LNKCTL_CLKREQ_EN); - else - pcie_capability_set_word(tp->pdev, PCI_EXP_LNKCTL, - PCI_EXP_LNKCTL_CLKREQ_EN); + clkreq = PCI_EXP_LNKCTL_CLKREQ_EN; + + pcie_lnkctl_clear_and_set(tp->pdev, PCI_EXP_LNKCTL_CLKREQ_EN, + clkreq); } tg3_test_and_report_link_chg(tp, current_link_up); -- 2.30.2