struct work_struct work;
        } wk;
 
+       spinlock_t mac_ocp_lock;
+
        unsigned supports_gmii:1;
        unsigned aspm_manageable:1;
        dma_addr_t counters_phys_addr;
                (RTL_R32(tp, GPHY_OCP) & 0xffff) : -ETIMEDOUT;
 }
 
-static void r8168_mac_ocp_write(struct rtl8169_private *tp, u32 reg, u32 data)
+static void __r8168_mac_ocp_write(struct rtl8169_private *tp, u32 reg, u32 data)
 {
        if (rtl_ocp_reg_failure(reg))
                return;
        RTL_W32(tp, OCPDR, OCPAR_FLAG | (reg << 15) | data);
 }
 
-static u16 r8168_mac_ocp_read(struct rtl8169_private *tp, u32 reg)
+static void r8168_mac_ocp_write(struct rtl8169_private *tp, u32 reg, u32 data)
+{
+       unsigned long flags;
+
+       spin_lock_irqsave(&tp->mac_ocp_lock, flags);
+       __r8168_mac_ocp_write(tp, reg, data);
+       spin_unlock_irqrestore(&tp->mac_ocp_lock, flags);
+}
+
+static u16 __r8168_mac_ocp_read(struct rtl8169_private *tp, u32 reg)
 {
        if (rtl_ocp_reg_failure(reg))
                return 0;
        return RTL_R32(tp, OCPDR);
 }
 
+static u16 r8168_mac_ocp_read(struct rtl8169_private *tp, u32 reg)
+{
+       unsigned long flags;
+       u16 val;
+
+       spin_lock_irqsave(&tp->mac_ocp_lock, flags);
+       val = __r8168_mac_ocp_read(tp, reg);
+       spin_unlock_irqrestore(&tp->mac_ocp_lock, flags);
+
+       return val;
+}
+
 static void r8168_mac_ocp_modify(struct rtl8169_private *tp, u32 reg, u16 mask,
                                 u16 set)
 {
-       u16 data = r8168_mac_ocp_read(tp, reg);
+       unsigned long flags;
+       u16 data;
 
-       r8168_mac_ocp_write(tp, reg, (data & ~mask) | set);
+       spin_lock_irqsave(&tp->mac_ocp_lock, flags);
+       data = __r8168_mac_ocp_read(tp, reg);
+       __r8168_mac_ocp_write(tp, reg, (data & ~mask) | set);
+       spin_unlock_irqrestore(&tp->mac_ocp_lock, flags);
 }
 
 /* Work around a hw issue with RTL8168g PHY, the quirk disables
        tp->eee_adv = -1;
        tp->ocp_base = OCP_STD_PHY_BASE;
 
+       spin_lock_init(&tp->mac_ocp_lock);
+
        dev->tstats = devm_netdev_alloc_pcpu_stats(&pdev->dev,
                                                   struct pcpu_sw_netstats);
        if (!dev->tstats)