#define dpaa_get_max_mtu()     \
        (dpaa_max_frm - (VLAN_ETH_HLEN + ETH_FCS_LEN))
 
+static void dpaa_eth_cgr_set_speed(struct mac_device *mac_dev, int speed);
+
 static int dpaa_netdev_init(struct net_device *net_dev,
                            const struct net_device_ops *dpaa_ops,
                            u16 tx_timeout)
        net_dev->needed_headroom = priv->tx_headroom;
        net_dev->watchdog_timeo = msecs_to_jiffies(tx_timeout);
 
+       mac_dev->net_dev = net_dev;
+       mac_dev->update_speed = dpaa_eth_cgr_set_speed;
+
        /* start without the RUNNING flag, phylib controls it later */
        netif_carrier_off(net_dev);
 
        initcgr.we_mask = cpu_to_be16(QM_CGR_WE_CSCN_EN | QM_CGR_WE_CS_THRES);
        initcgr.cgr.cscn_en = QM_CGR_EN;
 
-       /* Set different thresholds based on the MAC speed.
-        * This may turn suboptimal if the MAC is reconfigured at a speed
-        * lower than its max, e.g. if a dTSEC later negotiates a 100Mbps link.
-        * In such cases, we ought to reconfigure the threshold, too.
+       /* Set different thresholds based on the configured MAC speed.
+        * This may turn suboptimal if the MAC is reconfigured at another
+        * speed, so MACs must call dpaa_eth_cgr_set_speed in their adjust_link
+        * callback.
         */
        if (priv->mac_dev->if_support & SUPPORTED_10000baseT_Full)
                cs_th = DPAA_CS_THRESHOLD_10G;
        return err;
 }
 
+static void dpaa_eth_cgr_set_speed(struct mac_device *mac_dev, int speed)
+{
+       struct net_device *net_dev = mac_dev->net_dev;
+       struct dpaa_priv *priv = netdev_priv(net_dev);
+       struct qm_mcc_initcgr opts = { };
+       u32 cs_th;
+       int err;
+
+       opts.we_mask = cpu_to_be16(QM_CGR_WE_CS_THRES);
+       switch (speed) {
+       case SPEED_10000:
+               cs_th = DPAA_CS_THRESHOLD_10G;
+               break;
+       case SPEED_1000:
+       default:
+               cs_th = DPAA_CS_THRESHOLD_1G;
+               break;
+       }
+       qm_cgr_cs_thres_set64(&opts.cgr.cs_thres, cs_th, 1);
+
+       err = qman_update_cgr_safe(&priv->cgr_data.cgr, &opts);
+       if (err)
+               netdev_err(net_dev, "could not update speed: %d\n", err);
+}
+
 static inline void dpaa_setup_ingress(const struct dpaa_priv *priv,
                                      struct dpaa_fq *fq,
                                      const struct qman_fq *template)
 
        return 0;
 }
 
-static void adjust_link_void(struct mac_device *mac_dev)
+static void tgec_adjust_link(struct mac_device *mac_dev)
 {
+       struct phy_device *phy_dev = mac_dev->phy_dev;
+
+       mac_dev->update_speed(mac_dev, phy_dev->speed);
 }
 
 static int tgec_set_exception(struct fman_mac *tgec,
        mac_dev->set_allmulti           = tgec_set_allmulti;
        mac_dev->set_tstamp             = tgec_set_tstamp;
        mac_dev->set_multi              = fman_set_multi;
-       mac_dev->adjust_link            = adjust_link_void;
+       mac_dev->adjust_link            = tgec_adjust_link;
        mac_dev->enable                 = tgec_enable;
        mac_dev->disable                = tgec_disable;