diff options
Diffstat (limited to 'drivers/net/phy/phy.c')
| -rw-r--r-- | drivers/net/phy/phy.c | 68 | 
1 files changed, 36 insertions, 32 deletions
| diff --git a/drivers/net/phy/phy.c b/drivers/net/phy/phy.c index 82ab8fb82587..d0626bf5c540 100644 --- a/drivers/net/phy/phy.c +++ b/drivers/net/phy/phy.c @@ -54,6 +54,8 @@ static const char *phy_speed_to_str(int speed)  		return "5Gbps";  	case SPEED_10000:  		return "10Gbps"; +	case SPEED_14000: +		return "14Gbps";  	case SPEED_20000:  		return "20Gbps";  	case SPEED_25000: @@ -149,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 @@ -163,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); @@ -241,7 +268,7 @@ static const struct phy_setting settings[] = {   * phy_lookup_setting - lookup a PHY setting   * @speed: speed to match   * @duplex: duplex to match - * @feature: allowed link modes + * @features: allowed link modes   * @exact: an exact match is required   *   * Search the settings array for a setting that matches the speed and @@ -377,6 +404,7 @@ static void phy_sanitize_settings(struct phy_device *phydev)   * @cmd: ethtool_cmd   *   * A few notes about parameter checking: + *   * - We don't set port or transceiver, so we don't care what they   *   were set to.   * - phy_start_aneg() will make sure forced settings are sane, and @@ -484,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); @@ -531,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); @@ -1415,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;  	} @@ -1448,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); @@ -1474,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); | 
