diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac1000_core.c b/drivers/net/ethernet/stmicro/stmmac/dwmac1000_core.c
index 2af4c8ac6fb7..7dc8b254c15a 100644
--- a/drivers/net/ethernet/stmicro/stmmac/dwmac1000_core.c
+++ b/drivers/net/ethernet/stmicro/stmmac/dwmac1000_core.c
@@ -95,14 +95,6 @@ static void dwmac1000_core_init(struct mac_device_info *hw,
 
 	writel(value, ioaddr + GMAC_CONTROL);
 
-	/* Mask GMAC interrupts */
-	value = GMAC_INT_DEFAULT_MASK;
-
-	if (hw->pcs)
-		value &= ~GMAC_INT_DISABLE_PCS;
-
-	writel(value, ioaddr + GMAC_INT_MASK);
-
 #ifdef STMMAC_VLAN_TAG_USED
 	/* Tag detection without filtering */
 	writel(0x0, ioaddr + GMAC_VLAN_TAG);
@@ -302,6 +294,24 @@ static void dwmac1000_pmt(struct mac_device_info *hw, unsigned long mode)
 	writel(pmt, ioaddr + GMAC_PMT);
 }
 
+static void dwmac1000_enable_mac_irq(struct mac_device_info *hw)
+{
+	void __iomem *ioaddr = hw->pcsr;
+	u32 value = GMAC_INT_DEFAULT_MASK;
+
+	if (hw->pcs)
+		value &= ~GMAC_INT_DISABLE_PCS;
+
+	writel(value, ioaddr + GMAC_INT_MASK);
+}
+
+static void dwmac1000_disable_mac_irq(struct mac_device_info *hw)
+{
+	void __iomem *ioaddr = hw->pcsr;
+
+	writel(0x7FF, ioaddr + GMAC_INT_MASK);
+}
+
 /* RGMII or SMII interface */
 static void dwmac1000_rgsmii(void __iomem *ioaddr, struct stmmac_extra_stats *x)
 {
@@ -548,6 +558,8 @@ const struct stmmac_ops dwmac1000_ops = {
 	.set_mac = stmmac_set_mac,
 	.rx_ipc = dwmac1000_rx_ipc_enable,
 	.dump_regs = dwmac1000_dump_regs,
+	.enable_mac_irq = dwmac1000_enable_mac_irq,
+	.disable_mac_irq = dwmac1000_disable_mac_irq,
 	.host_irq_status = dwmac1000_irq_status,
 	.set_filter = dwmac1000_set_filter,
 	.flow_ctrl = dwmac1000_flow_ctrl,
diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac4_core.c b/drivers/net/ethernet/stmicro/stmmac/dwmac4_core.c
index 29f765a246a0..8fc8d3cd238d 100644
--- a/drivers/net/ethernet/stmicro/stmmac/dwmac4_core.c
+++ b/drivers/net/ethernet/stmicro/stmmac/dwmac4_core.c
@@ -46,14 +46,6 @@ static void dwmac4_core_init(struct mac_device_info *hw,
 	}
 
 	writel(value, ioaddr + GMAC_CONFIG);
-
-	/* Enable GMAC interrupts */
-	value = GMAC_INT_DEFAULT_ENABLE;
-
-	if (hw->pcs)
-		value |= GMAC_PCS_IRQ_DEFAULT;
-
-	writel(value, ioaddr + GMAC_INT_EN);
 }
 
 static void dwmac4_rx_queue_enable(struct mac_device_info *hw,
@@ -777,6 +769,24 @@ static void dwmac4_get_adv_lp(void __iomem *ioaddr, struct rgmii_adv *adv)
 	dwmac_get_adv_lp(ioaddr, GMAC_PCS_BASE, adv);
 }
 
+static void dwmac4_enable_mac_irq(struct mac_device_info *hw)
+{
+	void __iomem *ioaddr = hw->pcsr;
+	u32 value = GMAC_INT_DEFAULT_ENABLE;
+
+	if (hw->pcs)
+		value |= GMAC_PCS_IRQ_DEFAULT;
+
+	writel(value, ioaddr + GMAC_INT_EN);
+}
+
+static void dwmac4_disable_mac_irq(struct mac_device_info *hw)
+{
+	void __iomem *ioaddr = hw->pcsr;
+
+	writel(0, ioaddr + GMAC_INT_EN);
+}
+
 /* RGMII or SMII interface */
 static void dwmac4_phystatus(void __iomem *ioaddr, struct stmmac_extra_stats *x)
 {
@@ -1177,6 +1187,8 @@ const struct stmmac_ops dwmac4_ops = {
 	.map_mtl_to_dma = dwmac4_map_mtl_dma,
 	.config_cbs = dwmac4_config_cbs,
 	.dump_regs = dwmac4_dump_regs,
+	.enable_mac_irq = dwmac4_enable_mac_irq,
+	.disable_mac_irq = dwmac4_disable_mac_irq,
 	.host_irq_status = dwmac4_irq_status,
 	.host_mtl_irq_status = dwmac4_irq_mtl_status,
 	.flow_ctrl = dwmac4_flow_ctrl,
@@ -1219,6 +1231,8 @@ const struct stmmac_ops dwmac410_ops = {
 	.map_mtl_to_dma = dwmac4_map_mtl_dma,
 	.config_cbs = dwmac4_config_cbs,
 	.dump_regs = dwmac4_dump_regs,
+	.enable_mac_irq = dwmac4_enable_mac_irq,
+	.disable_mac_irq = dwmac4_disable_mac_irq,
 	.host_irq_status = dwmac4_irq_status,
 	.host_mtl_irq_status = dwmac4_irq_mtl_status,
 	.flow_ctrl = dwmac4_flow_ctrl,
@@ -1264,6 +1278,8 @@ const struct stmmac_ops dwmac510_ops = {
 	.map_mtl_to_dma = dwmac4_map_mtl_dma,
 	.config_cbs = dwmac4_config_cbs,
 	.dump_regs = dwmac4_dump_regs,
+	.enable_mac_irq = dwmac4_enable_mac_irq,
+	.disable_mac_irq = dwmac4_disable_mac_irq,
 	.host_irq_status = dwmac4_irq_status,
 	.host_mtl_irq_status = dwmac4_irq_mtl_status,
 	.flow_ctrl = dwmac4_flow_ctrl,
diff --git a/drivers/net/ethernet/stmicro/stmmac/dwxgmac2_core.c b/drivers/net/ethernet/stmicro/stmmac/dwxgmac2_core.c
index ad4df9bddcf3..12af0f831510 100644
--- a/drivers/net/ethernet/stmicro/stmmac/dwxgmac2_core.c
+++ b/drivers/net/ethernet/stmicro/stmmac/dwxgmac2_core.c
@@ -44,7 +44,6 @@ static void dwxgmac2_core_init(struct mac_device_info *hw,
 
 	writel(tx, ioaddr + XGMAC_TX_CONFIG);
 	writel(rx, ioaddr + XGMAC_RX_CONFIG);
-	writel(XGMAC_INT_DEFAULT_EN, ioaddr + XGMAC_INT_EN);
 }
 
 static void dwxgmac2_set_mac(void __iomem *ioaddr, bool enable)
@@ -239,6 +238,16 @@ static void dwxgmac2_dump_regs(struct mac_device_info *hw, u32 *reg_space)
 		reg_space[i] = readl(ioaddr + i * 4);
 }
 
+static void dwxgmac2_enable_mac_irq(struct mac_device_info *hw)
+{
+	writel(XGMAC_INT_DEFAULT_EN, hw->pcsr + XGMAC_INT_EN);
+}
+
+static void dwxgmac2_disable_mac_irq(struct mac_device_info *hw)
+{
+	writel(0, hw->pcsr + XGMAC_INT_EN);
+}
+
 static int dwxgmac2_host_irq_status(struct mac_device_info *hw,
 				    struct stmmac_extra_stats *x)
 {
@@ -1464,6 +1473,8 @@ const struct stmmac_ops dwxgmac210_ops = {
 	.map_mtl_to_dma = dwxgmac2_map_mtl_to_dma,
 	.config_cbs = dwxgmac2_config_cbs,
 	.dump_regs = dwxgmac2_dump_regs,
+	.enable_mac_irq = dwxgmac2_enable_mac_irq,
+	.disable_mac_irq = dwxgmac2_disable_mac_irq,
 	.host_irq_status = dwxgmac2_host_irq_status,
 	.host_mtl_irq_status = dwxgmac2_host_mtl_irq_status,
 	.flow_ctrl = dwxgmac2_flow_ctrl,
@@ -1525,6 +1536,8 @@ const struct stmmac_ops dwxlgmac2_ops = {
 	.map_mtl_to_dma = dwxgmac2_map_mtl_to_dma,
 	.config_cbs = dwxgmac2_config_cbs,
 	.dump_regs = dwxgmac2_dump_regs,
+	.enable_mac_irq = dwxgmac2_enable_mac_irq,
+	.disable_mac_irq = dwxgmac2_disable_mac_irq,
 	.host_irq_status = dwxgmac2_host_irq_status,
 	.host_mtl_irq_status = dwxgmac2_host_mtl_irq_status,
 	.flow_ctrl = dwxgmac2_flow_ctrl,
diff --git a/drivers/net/ethernet/stmicro/stmmac/hwif.h b/drivers/net/ethernet/stmicro/stmmac/hwif.h
index dea5a4d17677..68496b7a640b 100644
--- a/drivers/net/ethernet/stmicro/stmmac/hwif.h
+++ b/drivers/net/ethernet/stmicro/stmmac/hwif.h
@@ -322,6 +322,9 @@ struct stmmac_ops {
 			   u32 queue);
 	/* Dump MAC registers */
 	void (*dump_regs)(struct mac_device_info *hw, u32 *reg_space);
+	/* Enable/Disable MAC core interrupts */
+	void (*enable_mac_irq)(struct mac_device_info *hw);
+	void (*disable_mac_irq)(struct mac_device_info *hw);
 	/* Handle extra events on specific interrupts hw dependent */
 	int (*host_irq_status)(struct mac_device_info *hw,
 			       struct stmmac_extra_stats *x);
@@ -429,6 +432,10 @@ struct stmmac_ops {
 	stmmac_do_void_callback(__priv, mac, config_cbs, __args)
 #define stmmac_dump_mac_regs(__priv, __args...) \
 	stmmac_do_void_callback(__priv, mac, dump_regs, __args)
+#define stmmac_enable_mac_irq(__priv, __args...) \
+	stmmac_do_void_callback(__priv, mac, enable_mac_irq, __args)
+#define stmmac_disable_mac_irq(__priv, __args...) \
+	stmmac_do_void_callback(__priv, mac, disable_mac_irq, __args)
 #define stmmac_host_irq_status(__priv, __args...) \
 	stmmac_do_callback(__priv, mac, host_irq_status, __args)
 #define stmmac_host_mtl_irq_status(__priv, __args...) \
diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
index f70cab9f46d9..d124cbaceafd 100644
--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
+++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
@@ -101,6 +101,8 @@ static unsigned int chain_mode;
 module_param(chain_mode, int, 0444);
 MODULE_PARM_DESC(chain_mode, "To use chain instead of ring mode");
 
+static void stmmac_enable_irq(struct stmmac_priv *priv);
+static void stmmac_disable_irq(struct stmmac_priv *priv);
 static irqreturn_t stmmac_interrupt(int irq, void *dev_id);
 
 #ifdef CONFIG_DEBUG_FS
@@ -2782,6 +2784,9 @@ static int stmmac_hw_setup(struct net_device *dev, bool init_ptp)
 	netif_set_real_num_rx_queues(dev, priv->plat->rx_queues_to_use);
 	netif_set_real_num_tx_queues(dev, priv->plat->tx_queues_to_use);
 
+	/* Enable MAC/MTL/DMA/etc IRQs */
+	stmmac_enable_irq(priv);
+
 	/* Start the ball rolling... */
 	stmmac_start_all_dma(priv);
 
@@ -2794,6 +2799,8 @@ static void stmmac_hw_teardown(struct net_device *dev)
 
 	stmmac_stop_all_dma(priv);
 
+	stmmac_disable_irq(priv);
+
 	stmmac_release_ptp(priv);
 
 	stmmac_mac_set(priv, priv->ioaddr, false);
@@ -4113,6 +4120,39 @@ static int stmmac_set_features(struct net_device *netdev,
 	return 0;
 }
 
+/**
+ * stmmac_enable_irq - device IRQs enable procedure
+ * @priv: driver private structure
+ * Description : enable all DW *MAC networking IRQs handled then in the
+ * main ISR.
+ */
+static void stmmac_enable_irq(struct stmmac_priv *priv)
+{
+	/* The main IRQ signal needs to be masked while the IRQs enable/disable
+	 * procedure is in progress, because the individual IRQs handlers can
+	 * also read/write the IRQs control registers.
+	 */
+	disable_irq(priv->dev->irq);
+
+	stmmac_enable_mac_irq(priv, priv->hw);
+
+	enable_irq(priv->dev->irq);
+}
+
+/**
+ * stmmac_disable_irq - device IRQs disable procedure
+ * @priv: driver private structure
+ * Description : disable all DW *MAC networking IRQs.
+ */
+static void stmmac_disable_irq(struct stmmac_priv *priv)
+{
+	disable_irq(priv->dev->irq);
+
+	stmmac_disable_mac_irq(priv, priv->hw);
+
+	enable_irq(priv->dev->irq);
+}
+
 /**
  *  stmmac_interrupt - main ISR
  *  @irq: interrupt number.
