Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/net-next
[linux-2.6-microblaze.git] / drivers / net / phy / phy.c
index 3e231a5..d0626bf 100644 (file)
@@ -151,6 +151,25 @@ static int phy_config_interrupt(struct phy_device *phydev, u32 interrupts)
        return 0;
 }
 
+/**
+ * phy_restart_aneg - restart auto-negotiation
+ * @phydev: target phy_device struct
+ *
+ * Restart the autonegotiation on @phydev.  Returns >= 0 on success or
+ * negative errno on error.
+ */
+int phy_restart_aneg(struct phy_device *phydev)
+{
+       int ret;
+
+       if (phydev->is_c45 && !(phydev->c45_ids.devices_in_package & BIT(0)))
+               ret = genphy_c45_restart_aneg(phydev);
+       else
+               ret = genphy_restart_aneg(phydev);
+
+       return ret;
+}
+EXPORT_SYMBOL_GPL(phy_restart_aneg);
 
 /**
  * phy_aneg_done - return auto-negotiation status
@@ -165,6 +184,12 @@ int phy_aneg_done(struct phy_device *phydev)
        if (phydev->drv && phydev->drv->aneg_done)
                return phydev->drv->aneg_done(phydev);
 
+       /* Avoid genphy_aneg_done() if the Clause 45 PHY does not
+        * implement Clause 22 registers
+        */
+       if (phydev->is_c45 && !(phydev->c45_ids.devices_in_package & BIT(0)))
+               return -EINVAL;
+
        return genphy_aneg_done(phydev);
 }
 EXPORT_SYMBOL(phy_aneg_done);
@@ -487,32 +512,8 @@ int phy_ethtool_ksettings_set(struct phy_device *phydev,
 }
 EXPORT_SYMBOL(phy_ethtool_ksettings_set);
 
-int phy_ethtool_gset(struct phy_device *phydev, struct ethtool_cmd *cmd)
-{
-       cmd->supported = phydev->supported;
-
-       cmd->advertising = phydev->advertising;
-       cmd->lp_advertising = phydev->lp_advertising;
-
-       ethtool_cmd_speed_set(cmd, phydev->speed);
-       cmd->duplex = phydev->duplex;
-       if (phydev->interface == PHY_INTERFACE_MODE_MOCA)
-               cmd->port = PORT_BNC;
-       else
-               cmd->port = PORT_MII;
-       cmd->phy_address = phydev->mdio.addr;
-       cmd->transceiver = phy_is_internal(phydev) ?
-               XCVR_INTERNAL : XCVR_EXTERNAL;
-       cmd->autoneg = phydev->autoneg;
-       cmd->eth_tp_mdix_ctrl = phydev->mdix_ctrl;
-       cmd->eth_tp_mdix = phydev->mdix;
-
-       return 0;
-}
-EXPORT_SYMBOL(phy_ethtool_gset);
-
-int phy_ethtool_ksettings_get(struct phy_device *phydev,
-                             struct ethtool_link_ksettings *cmd)
+void phy_ethtool_ksettings_get(struct phy_device *phydev,
+                              struct ethtool_link_ksettings *cmd)
 {
        ethtool_convert_legacy_u32_to_link_mode(cmd->link_modes.supported,
                                                phydev->supported);
@@ -534,8 +535,6 @@ int phy_ethtool_ksettings_get(struct phy_device *phydev,
        cmd->base.autoneg = phydev->autoneg;
        cmd->base.eth_tp_mdix_ctrl = phydev->mdix_ctrl;
        cmd->base.eth_tp_mdix = phydev->mdix;
-
-       return 0;
 }
 EXPORT_SYMBOL(phy_ethtool_ksettings_get);
 
@@ -1418,7 +1417,7 @@ int phy_ethtool_set_eee(struct phy_device *phydev, struct ethtool_eee *data)
                /* Restart autonegotiation so the new modes get sent to the
                 * link partner.
                 */
-               ret = genphy_restart_aneg(phydev);
+               ret = phy_restart_aneg(phydev);
                if (ret < 0)
                        return ret;
        }
@@ -1451,7 +1450,9 @@ int phy_ethtool_get_link_ksettings(struct net_device *ndev,
        if (!phydev)
                return -ENODEV;
 
-       return phy_ethtool_ksettings_get(phydev, cmd);
+       phy_ethtool_ksettings_get(phydev, cmd);
+
+       return 0;
 }
 EXPORT_SYMBOL(phy_ethtool_get_link_ksettings);
 
@@ -1477,6 +1478,6 @@ int phy_ethtool_nway_reset(struct net_device *ndev)
        if (!phydev->drv)
                return -EIO;
 
-       return genphy_restart_aneg(phydev);
+       return phy_restart_aneg(phydev);
 }
 EXPORT_SYMBOL(phy_ethtool_nway_reset);