}
 EXPORT_SYMBOL_GPL(enetc_port_mac_wr);
 
-void enetc_set_ptcfpr(struct enetc_hw *hw, unsigned long preemptible_tcs)
+static void enetc_change_preemptible_tcs(struct enetc_ndev_priv *priv,
+                                        u8 preemptible_tcs)
 {
-       u32 val;
-       int tc;
-
-       for (tc = 0; tc < 8; tc++) {
-               val = enetc_port_rd(hw, ENETC_PTCFPR(tc));
-
-               if (preemptible_tcs & BIT(tc))
-                       val |= ENETC_PTCFPR_FPE;
-               else
-                       val &= ~ENETC_PTCFPR_FPE;
-
-               enetc_port_wr(hw, ENETC_PTCFPR(tc), val);
-       }
+       priv->preemptible_tcs = preemptible_tcs;
+       enetc_mm_commit_preemptible_tcs(priv);
 }
-EXPORT_SYMBOL_GPL(enetc_set_ptcfpr);
 
 static int enetc_num_stack_tx_queues(struct enetc_ndev_priv *priv)
 {
 
        enetc_debug_tx_ring_prios(priv);
 
-       enetc_set_ptcfpr(hw, 0);
+       enetc_change_preemptible_tcs(priv, 0);
 }
 
 int enetc_setup_tc_mqprio(struct net_device *ndev, void *type_data)
 
        enetc_debug_tx_ring_prios(priv);
 
-       enetc_set_ptcfpr(hw, mqprio->preemptible_tcs);
+       enetc_change_preemptible_tcs(priv, mqprio->preemptible_tcs);
 
        return 0;
 
 
        u16 rx_bd_count, tx_bd_count;
 
        u16 msg_enable;
+
+       u8 preemptible_tcs;
+
        enum enetc_active_offloads active_offloads;
 
        u32 speed; /* store speed for compare update pspeed */
 /* ethtool */
 void enetc_set_ethtool_ops(struct net_device *ndev);
 void enetc_mm_link_state_update(struct enetc_ndev_priv *priv, bool link);
+void enetc_mm_commit_preemptible_tcs(struct enetc_ndev_priv *priv);
 
 /* control buffer descriptor ring (CBDR) */
 int enetc_setup_cbdr(struct device *dev, struct enetc_hw *hw, int bd_count,
 
 void enetc_reset_ptcmsdur(struct enetc_hw *hw);
 void enetc_set_ptcmsdur(struct enetc_hw *hw, u32 *queue_max_sdu);
-void enetc_set_ptcfpr(struct enetc_hw *hw, unsigned long preemptible_tcs);
 
 #ifdef CONFIG_FSL_ENETC_QOS
 int enetc_qos_query_caps(struct net_device *ndev, void *type_data);
 
        return 0;
 }
 
+static int enetc_mm_wait_tx_active(struct enetc_hw *hw, int verify_time)
+{
+       int timeout = verify_time * USEC_PER_MSEC * ENETC_MM_VERIFY_RETRIES;
+       u32 val;
+
+       /* This will time out after the standard value of 3 verification
+        * attempts. To not sleep forever, it relies on a non-zero verify_time,
+        * guarantee which is provided by the ethtool nlattr policy.
+        */
+       return read_poll_timeout(enetc_port_rd, val,
+                                ENETC_MMCSR_GET_VSTS(val) == 3,
+                                ENETC_MM_VERIFY_SLEEP_US, timeout,
+                                true, hw, ENETC_MMCSR);
+}
+
+static void enetc_set_ptcfpr(struct enetc_hw *hw, u8 preemptible_tcs)
+{
+       u32 val;
+       int tc;
+
+       for (tc = 0; tc < 8; tc++) {
+               val = enetc_port_rd(hw, ENETC_PTCFPR(tc));
+
+               if (preemptible_tcs & BIT(tc))
+                       val |= ENETC_PTCFPR_FPE;
+               else
+                       val &= ~ENETC_PTCFPR_FPE;
+
+               enetc_port_wr(hw, ENETC_PTCFPR(tc), val);
+       }
+}
+
+/* ENETC does not have an IRQ to notify changes to the MAC Merge TX status
+ * (active/inactive), but the preemptible traffic classes should only be
+ * committed to hardware once TX is active. Resort to polling.
+ */
+void enetc_mm_commit_preemptible_tcs(struct enetc_ndev_priv *priv)
+{
+       struct enetc_hw *hw = &priv->si->hw;
+       u8 preemptible_tcs = 0;
+       u32 val;
+       int err;
+
+       val = enetc_port_rd(hw, ENETC_MMCSR);
+       if (!(val & ENETC_MMCSR_ME))
+               goto out;
+
+       if (!(val & ENETC_MMCSR_VDIS)) {
+               err = enetc_mm_wait_tx_active(hw, ENETC_MMCSR_GET_VT(val));
+               if (err)
+                       goto out;
+       }
+
+       preemptible_tcs = priv->preemptible_tcs;
+out:
+       enetc_set_ptcfpr(hw, preemptible_tcs);
+}
+
 /* FIXME: Workaround for the link partner's verification failing if ENETC
  * priorly received too much express traffic. The documentation doesn't
  * suggest this is needed.
 
        enetc_restart_emac_rx(priv->si);
 
+       enetc_mm_commit_preemptible_tcs(priv);
+
        mutex_unlock(&priv->mm_lock);
 
        return 0;
 
        enetc_port_wr(hw, ENETC_MMCSR, val);
 
+       enetc_mm_commit_preemptible_tcs(priv);
+
        mutex_unlock(&priv->mm_lock);
 }
 EXPORT_SYMBOL_GPL(enetc_mm_link_state_update);