struct work_struct work;
        } wk;
 
+       spinlock_t config25_lock;
        spinlock_t mac_ocp_lock;
 
        unsigned supports_gmii:1;
        RTL_R8(tp, ChipCmd);
 }
 
+static void rtl_mod_config2(struct rtl8169_private *tp, u8 clear, u8 set)
+{
+       unsigned long flags;
+       u8 val;
+
+       spin_lock_irqsave(&tp->config25_lock, flags);
+       val = RTL_R8(tp, Config2);
+       RTL_W8(tp, Config2, (val & ~clear) | set);
+       spin_unlock_irqrestore(&tp->config25_lock, flags);
+}
+
+static void rtl_mod_config5(struct rtl8169_private *tp, u8 clear, u8 set)
+{
+       unsigned long flags;
+       u8 val;
+
+       spin_lock_irqsave(&tp->config25_lock, flags);
+       val = RTL_R8(tp, Config5);
+       RTL_W8(tp, Config5, (val & ~clear) | set);
+       spin_unlock_irqrestore(&tp->config25_lock, flags);
+}
+
 static bool rtl_is_8125(struct rtl8169_private *tp)
 {
        return tp->mac_version >= RTL_GIGA_MAC_VER_61;
                { WAKE_MAGIC, Config3, MagicPacket }
        };
        unsigned int i, tmp = ARRAY_SIZE(cfg);
+       unsigned long flags;
        u8 options;
 
        rtl_unlock_config_regs(tp);
                        r8168_mac_ocp_modify(tp, 0xc0b6, BIT(0), 0);
        }
 
+       spin_lock_irqsave(&tp->config25_lock, flags);
        for (i = 0; i < tmp; i++) {
                options = RTL_R8(tp, cfg[i].reg) & ~cfg[i].mask;
                if (wolopts & cfg[i].opt)
                        options |= cfg[i].mask;
                RTL_W8(tp, cfg[i].reg, options);
        }
+       spin_unlock_irqrestore(&tp->config25_lock, flags);
 
        switch (tp->mac_version) {
        case RTL_GIGA_MAC_VER_02 ... RTL_GIGA_MAC_VER_06:
        case RTL_GIGA_MAC_VER_34:
        case RTL_GIGA_MAC_VER_37:
        case RTL_GIGA_MAC_VER_39 ... RTL_GIGA_MAC_VER_63:
-               options = RTL_R8(tp, Config2) & ~PME_SIGNAL;
                if (wolopts)
-                       options |= PME_SIGNAL;
-               RTL_W8(tp, Config2, options);
+                       rtl_mod_config2(tp, 0, PME_SIGNAL);
+               else
+                       rtl_mod_config2(tp, PME_SIGNAL, 0);
                break;
        default:
                break;
 {
        /* Don't enable ASPM in the chip if OS can't control ASPM */
        if (enable && tp->aspm_manageable) {
-               RTL_W8(tp, Config5, RTL_R8(tp, Config5) | ASPM_en);
-               RTL_W8(tp, Config2, RTL_R8(tp, Config2) | ClkReqEn);
+               rtl_mod_config5(tp, 0, ASPM_en);
+               rtl_mod_config2(tp, 0, ClkReqEn);
 
                switch (tp->mac_version) {
                case RTL_GIGA_MAC_VER_46 ... RTL_GIGA_MAC_VER_48:
                        break;
                }
 
-               RTL_W8(tp, Config2, RTL_R8(tp, Config2) & ~ClkReqEn);
-               RTL_W8(tp, Config5, RTL_R8(tp, Config5) & ~ASPM_en);
+               rtl_mod_config2(tp, ClkReqEn, 0);
+               rtl_mod_config5(tp, ASPM_en, 0);
        }
 
        udelay(10);
        RTL_W32(tp, MISC, RTL_R32(tp, MISC) | TXPLA_RST);
        RTL_W32(tp, MISC, RTL_R32(tp, MISC) & ~TXPLA_RST);
 
-       RTL_W8(tp, Config5, RTL_R8(tp, Config5) & ~Spi_en);
+       rtl_mod_config5(tp, Spi_en, 0);
 }
 
 static void rtl_hw_start_8168e_2(struct rtl8169_private *tp)
 
        RTL_W8(tp, DLLPR, RTL_R8(tp, DLLPR) | PFM_EN);
        RTL_W32(tp, MISC, RTL_R32(tp, MISC) | PWM_EN);
-       RTL_W8(tp, Config5, RTL_R8(tp, Config5) & ~Spi_en);
+       rtl_mod_config5(tp, Spi_en, 0);
 
        rtl_hw_aspm_clkreq_enable(tp, true);
 }
        RTL_W8(tp, MCU, RTL_R8(tp, MCU) & ~NOW_IS_OOB);
        RTL_W8(tp, DLLPR, RTL_R8(tp, DLLPR) | PFM_EN);
        RTL_W32(tp, MISC, RTL_R32(tp, MISC) | PWM_EN);
-       RTL_W8(tp, Config5, RTL_R8(tp, Config5) & ~Spi_en);
+       rtl_mod_config5(tp, Spi_en, 0);
 
        rtl8168_config_eee_mac(tp);
 }
        tp->eee_adv = -1;
        tp->ocp_base = OCP_STD_PHY_BASE;
 
+       spin_lock_init(&tp->config25_lock);
        spin_lock_init(&tp->mac_ocp_lock);
 
        dev->tstats = devm_netdev_alloc_pcpu_stats(&pdev->dev,