Commit 52e36c4d authored by David S. Miller's avatar David S. Miller

Merge branch 'fec-ksettings'

Philippe Reynes says:

====================
fec: ethtool: move to new api {get|set}_link_ksettings

Ethtool has a new api {get|set}_link_ksettings that deprecate
the old api {get|set}_settings. We update the fec driver to use
this new ethtool api.

For this first version, I've converted old u32 value in phy structure
to link_modes structure. Another way would be to replace u32 in
phy structure to use DECLARE_LINK_MODE_MASK for advertising, ....
====================
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parents 2a2bbf17 54846f58
......@@ -2058,8 +2058,8 @@ static void fec_enet_mii_remove(struct fec_enet_private *fep)
}
}
static int fec_enet_get_settings(struct net_device *ndev,
struct ethtool_cmd *cmd)
static int fec_enet_get_link_ksettings(struct net_device *ndev,
struct ethtool_link_ksettings *cmd)
{
struct fec_enet_private *fep = netdev_priv(ndev);
struct phy_device *phydev = fep->phy_dev;
......@@ -2067,11 +2067,11 @@ static int fec_enet_get_settings(struct net_device *ndev,
if (!phydev)
return -ENODEV;
return phy_ethtool_gset(phydev, cmd);
return phy_ethtool_ksettings_get(phydev, cmd);
}
static int fec_enet_set_settings(struct net_device *ndev,
struct ethtool_cmd *cmd)
static int fec_enet_set_link_ksettings(struct net_device *ndev,
const struct ethtool_link_ksettings *cmd)
{
struct fec_enet_private *fep = netdev_priv(ndev);
struct phy_device *phydev = fep->phy_dev;
......@@ -2079,7 +2079,7 @@ static int fec_enet_set_settings(struct net_device *ndev,
if (!phydev)
return -ENODEV;
return phy_ethtool_sset(phydev, cmd);
return phy_ethtool_ksettings_set(phydev, cmd);
}
static void fec_enet_get_drvinfo(struct net_device *ndev,
......@@ -2562,8 +2562,6 @@ fec_enet_set_wol(struct net_device *ndev, struct ethtool_wolinfo *wol)
}
static const struct ethtool_ops fec_enet_ethtool_ops = {
.get_settings = fec_enet_get_settings,
.set_settings = fec_enet_set_settings,
.get_drvinfo = fec_enet_get_drvinfo,
.get_regs_len = fec_enet_get_regs_len,
.get_regs = fec_enet_get_regs,
......@@ -2583,6 +2581,8 @@ static const struct ethtool_ops fec_enet_ethtool_ops = {
.set_tunable = fec_enet_set_tunable,
.get_wol = fec_enet_get_wol,
.set_wol = fec_enet_set_wol,
.get_link_ksettings = fec_enet_get_link_ksettings,
.set_link_ksettings = fec_enet_set_link_ksettings,
};
static int fec_enet_ioctl(struct net_device *ndev, struct ifreq *rq, int cmd)
......
......@@ -362,6 +362,60 @@ int phy_ethtool_sset(struct phy_device *phydev, struct ethtool_cmd *cmd)
}
EXPORT_SYMBOL(phy_ethtool_sset);
int phy_ethtool_ksettings_set(struct phy_device *phydev,
const struct ethtool_link_ksettings *cmd)
{
u8 autoneg = cmd->base.autoneg;
u8 duplex = cmd->base.duplex;
u32 speed = cmd->base.speed;
u32 advertising;
if (cmd->base.phy_address != phydev->mdio.addr)
return -EINVAL;
ethtool_convert_link_mode_to_legacy_u32(&advertising,
cmd->link_modes.advertising);
/* We make sure that we don't pass unsupported values in to the PHY */
advertising &= phydev->supported;
/* Verify the settings we care about. */
if (autoneg != AUTONEG_ENABLE && autoneg != AUTONEG_DISABLE)
return -EINVAL;
if (autoneg == AUTONEG_ENABLE && advertising == 0)
return -EINVAL;
if (autoneg == AUTONEG_DISABLE &&
((speed != SPEED_1000 &&
speed != SPEED_100 &&
speed != SPEED_10) ||
(duplex != DUPLEX_HALF &&
duplex != DUPLEX_FULL)))
return -EINVAL;
phydev->autoneg = autoneg;
phydev->speed = speed;
phydev->advertising = advertising;
if (autoneg == AUTONEG_ENABLE)
phydev->advertising |= ADVERTISED_Autoneg;
else
phydev->advertising &= ~ADVERTISED_Autoneg;
phydev->duplex = duplex;
phydev->mdix = cmd->base.eth_tp_mdix_ctrl;
/* Restart the PHY */
phy_start_aneg(phydev);
return 0;
}
EXPORT_SYMBOL(phy_ethtool_ksettings_set);
int phy_ethtool_gset(struct phy_device *phydev, struct ethtool_cmd *cmd)
{
cmd->supported = phydev->supported;
......@@ -385,6 +439,33 @@ int phy_ethtool_gset(struct phy_device *phydev, struct ethtool_cmd *cmd)
}
EXPORT_SYMBOL(phy_ethtool_gset);
int 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);
ethtool_convert_legacy_u32_to_link_mode(cmd->link_modes.advertising,
phydev->advertising);
ethtool_convert_legacy_u32_to_link_mode(cmd->link_modes.lp_advertising,
phydev->lp_advertising);
cmd->base.speed = phydev->speed;
cmd->base.duplex = phydev->duplex;
if (phydev->interface == PHY_INTERFACE_MODE_MOCA)
cmd->base.port = PORT_BNC;
else
cmd->base.port = PORT_MII;
cmd->base.phy_address = phydev->mdio.addr;
cmd->base.autoneg = phydev->autoneg;
cmd->base.eth_tp_mdix_ctrl = phydev->mdix;
return 0;
}
EXPORT_SYMBOL(phy_ethtool_ksettings_get);
/**
* phy_mii_ioctl - generic PHY MII ioctl interface
* @phydev: the phy_device struct
......
......@@ -150,6 +150,13 @@ extern int
__ethtool_get_link_ksettings(struct net_device *dev,
struct ethtool_link_ksettings *link_ksettings);
void ethtool_convert_legacy_u32_to_link_mode(unsigned long *dst,
u32 legacy_u32);
/* return false if src had higher bits set. lower bits always updated. */
bool ethtool_convert_link_mode_to_legacy_u32(u32 *legacy_u32,
const unsigned long *src);
/**
* struct ethtool_ops - optional netdev operations
* @get_settings: DEPRECATED, use %get_link_ksettings/%set_link_ksettings
......
......@@ -805,6 +805,10 @@ void phy_start_machine(struct phy_device *phydev);
void phy_stop_machine(struct phy_device *phydev);
int phy_ethtool_sset(struct phy_device *phydev, struct ethtool_cmd *cmd);
int phy_ethtool_gset(struct phy_device *phydev, struct ethtool_cmd *cmd);
int phy_ethtool_ksettings_get(struct phy_device *phydev,
struct ethtool_link_ksettings *cmd);
int phy_ethtool_ksettings_set(struct phy_device *phydev,
const struct ethtool_link_ksettings *cmd);
int phy_mii_ioctl(struct phy_device *phydev, struct ifreq *ifr, int cmd);
int phy_start_interrupts(struct phy_device *phydev);
void phy_print_status(struct phy_device *phydev);
......
......@@ -391,14 +391,16 @@ static int __ethtool_set_flags(struct net_device *dev, u32 data)
return 0;
}
static void convert_legacy_u32_to_link_mode(unsigned long *dst, u32 legacy_u32)
void ethtool_convert_legacy_u32_to_link_mode(unsigned long *dst,
u32 legacy_u32)
{
bitmap_zero(dst, __ETHTOOL_LINK_MODE_MASK_NBITS);
dst[0] = legacy_u32;
}
EXPORT_SYMBOL(ethtool_convert_legacy_u32_to_link_mode);
/* return false if src had higher bits set. lower bits always updated. */
static bool convert_link_mode_to_legacy_u32(u32 *legacy_u32,
bool ethtool_convert_link_mode_to_legacy_u32(u32 *legacy_u32,
const unsigned long *src)
{
bool retval = true;
......@@ -419,6 +421,7 @@ static bool convert_link_mode_to_legacy_u32(u32 *legacy_u32,
*legacy_u32 = src[0];
return retval;
}
EXPORT_SYMBOL(ethtool_convert_link_mode_to_legacy_u32);
/* return false if legacy contained non-0 deprecated fields
* transceiver/maxtxpkt/maxrxpkt. rest of ksettings always updated
......@@ -441,13 +444,13 @@ convert_legacy_settings_to_link_ksettings(
legacy_settings->maxrxpkt)
retval = false;
convert_legacy_u32_to_link_mode(
ethtool_convert_legacy_u32_to_link_mode(
link_ksettings->link_modes.supported,
legacy_settings->supported);
convert_legacy_u32_to_link_mode(
ethtool_convert_legacy_u32_to_link_mode(
link_ksettings->link_modes.advertising,
legacy_settings->advertising);
convert_legacy_u32_to_link_mode(
ethtool_convert_legacy_u32_to_link_mode(
link_ksettings->link_modes.lp_advertising,
legacy_settings->lp_advertising);
link_ksettings->base.speed
......@@ -486,13 +489,13 @@ convert_link_ksettings_to_legacy_settings(
* __u32 maxrxpkt;
*/
retval &= convert_link_mode_to_legacy_u32(
retval &= ethtool_convert_link_mode_to_legacy_u32(
&legacy_settings->supported,
link_ksettings->link_modes.supported);
retval &= convert_link_mode_to_legacy_u32(
retval &= ethtool_convert_link_mode_to_legacy_u32(
&legacy_settings->advertising,
link_ksettings->link_modes.advertising);
retval &= convert_link_mode_to_legacy_u32(
retval &= ethtool_convert_link_mode_to_legacy_u32(
&legacy_settings->lp_advertising,
link_ksettings->link_modes.lp_advertising);
ethtool_cmd_speed_set(legacy_settings, link_ksettings->base.speed);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment