})
 #endif
 
+static const phy_interface_t phylink_sfp_interface_preference[] = {
+       PHY_INTERFACE_MODE_25GBASER,
+       PHY_INTERFACE_MODE_USXGMII,
+       PHY_INTERFACE_MODE_10GBASER,
+       PHY_INTERFACE_MODE_5GBASER,
+       PHY_INTERFACE_MODE_2500BASEX,
+       PHY_INTERFACE_MODE_SGMII,
+       PHY_INTERFACE_MODE_1000BASEX,
+       PHY_INTERFACE_MODE_100BASEX,
+};
+
+static DECLARE_PHY_INTERFACE_MASK(phylink_sfp_interfaces);
+
 /**
  * phylink_set_port_modes() - set the port type modes in the ethtool mask
  * @mask: ethtool link mode mask
                                unsigned long *supported,
                                struct phylink_link_state *state)
 {
+       DECLARE_PHY_INTERFACE_MASK(interfaces);
+
+       /* If the PHY provides a bitmap of the interfaces it will be using
+        * depending on the negotiated media speeds, use this to validate
+        * which ethtool link modes can be used.
+        */
+       if (!phy_interface_empty(phy->possible_interfaces)) {
+               /* We only care about the union of the PHY's interfaces and
+                * those which the host supports.
+                */
+               phy_interface_and(interfaces, phy->possible_interfaces,
+                                 pl->config->supported_interfaces);
+
+               if (phy_interface_empty(interfaces)) {
+                       phylink_err(pl, "PHY has no common interfaces\n");
+                       return -EINVAL;
+               }
+
+               if (phy_on_sfp(phy)) {
+                       /* If the PHY is on a SFP, limit the interfaces to
+                        * those that can be used with a SFP module.
+                        */
+                       phy_interface_and(interfaces, interfaces,
+                                         phylink_sfp_interfaces);
+
+                       if (phy_interface_empty(interfaces)) {
+                               phylink_err(pl, "SFP PHY's possible interfaces becomes empty\n");
+                               return -EINVAL;
+                       }
+               }
+
+               phylink_dbg(pl, "PHY %s uses interfaces %*pbl, validating %*pbl\n",
+                           phydev_name(phy),
+                           (int)PHY_INTERFACE_MODE_MAX,
+                           phy->possible_interfaces,
+                           (int)PHY_INTERFACE_MODE_MAX, interfaces);
+
+               return phylink_validate_mask(pl, phy, supported, state,
+                                            interfaces);
+       }
+
        /* Check whether we would use rate matching for the proposed interface
         * mode.
         */
        pl->netdev->sfp_bus = NULL;
 }
 
-static const phy_interface_t phylink_sfp_interface_preference[] = {
-       PHY_INTERFACE_MODE_25GBASER,
-       PHY_INTERFACE_MODE_USXGMII,
-       PHY_INTERFACE_MODE_10GBASER,
-       PHY_INTERFACE_MODE_5GBASER,
-       PHY_INTERFACE_MODE_2500BASEX,
-       PHY_INTERFACE_MODE_SGMII,
-       PHY_INTERFACE_MODE_1000BASEX,
-       PHY_INTERFACE_MODE_100BASEX,
-};
-
-static DECLARE_PHY_INTERFACE_MASK(phylink_sfp_interfaces);
-
 static phy_interface_t phylink_choose_sfp_interface(struct phylink *pl,
                                                    const unsigned long *intf)
 {