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) ...@@ -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, static int fec_enet_get_link_ksettings(struct net_device *ndev,
struct ethtool_cmd *cmd) struct ethtool_link_ksettings *cmd)
{ {
struct fec_enet_private *fep = netdev_priv(ndev); struct fec_enet_private *fep = netdev_priv(ndev);
struct phy_device *phydev = fep->phy_dev; struct phy_device *phydev = fep->phy_dev;
...@@ -2067,11 +2067,11 @@ static int fec_enet_get_settings(struct net_device *ndev, ...@@ -2067,11 +2067,11 @@ static int fec_enet_get_settings(struct net_device *ndev,
if (!phydev) if (!phydev)
return -ENODEV; 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, static int fec_enet_set_link_ksettings(struct net_device *ndev,
struct ethtool_cmd *cmd) const struct ethtool_link_ksettings *cmd)
{ {
struct fec_enet_private *fep = netdev_priv(ndev); struct fec_enet_private *fep = netdev_priv(ndev);
struct phy_device *phydev = fep->phy_dev; struct phy_device *phydev = fep->phy_dev;
...@@ -2079,7 +2079,7 @@ static int fec_enet_set_settings(struct net_device *ndev, ...@@ -2079,7 +2079,7 @@ static int fec_enet_set_settings(struct net_device *ndev,
if (!phydev) if (!phydev)
return -ENODEV; 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, 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) ...@@ -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 = { 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_drvinfo = fec_enet_get_drvinfo,
.get_regs_len = fec_enet_get_regs_len, .get_regs_len = fec_enet_get_regs_len,
.get_regs = fec_enet_get_regs, .get_regs = fec_enet_get_regs,
...@@ -2583,6 +2581,8 @@ static const struct ethtool_ops fec_enet_ethtool_ops = { ...@@ -2583,6 +2581,8 @@ static const struct ethtool_ops fec_enet_ethtool_ops = {
.set_tunable = fec_enet_set_tunable, .set_tunable = fec_enet_set_tunable,
.get_wol = fec_enet_get_wol, .get_wol = fec_enet_get_wol,
.set_wol = fec_enet_set_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) 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) ...@@ -362,6 +362,60 @@ int phy_ethtool_sset(struct phy_device *phydev, struct ethtool_cmd *cmd)
} }
EXPORT_SYMBOL(phy_ethtool_sset); 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) int phy_ethtool_gset(struct phy_device *phydev, struct ethtool_cmd *cmd)
{ {
cmd->supported = phydev->supported; cmd->supported = phydev->supported;
...@@ -385,6 +439,33 @@ int phy_ethtool_gset(struct phy_device *phydev, struct ethtool_cmd *cmd) ...@@ -385,6 +439,33 @@ int phy_ethtool_gset(struct phy_device *phydev, struct ethtool_cmd *cmd)
} }
EXPORT_SYMBOL(phy_ethtool_gset); 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 * phy_mii_ioctl - generic PHY MII ioctl interface
* @phydev: the phy_device struct * @phydev: the phy_device struct
......
...@@ -150,6 +150,13 @@ extern int ...@@ -150,6 +150,13 @@ extern int
__ethtool_get_link_ksettings(struct net_device *dev, __ethtool_get_link_ksettings(struct net_device *dev,
struct ethtool_link_ksettings *link_ksettings); 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 * struct ethtool_ops - optional netdev operations
* @get_settings: DEPRECATED, use %get_link_ksettings/%set_link_ksettings * @get_settings: DEPRECATED, use %get_link_ksettings/%set_link_ksettings
......
...@@ -805,6 +805,10 @@ void phy_start_machine(struct phy_device *phydev); ...@@ -805,6 +805,10 @@ void phy_start_machine(struct phy_device *phydev);
void phy_stop_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_sset(struct phy_device *phydev, struct ethtool_cmd *cmd);
int phy_ethtool_gset(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_mii_ioctl(struct phy_device *phydev, struct ifreq *ifr, int cmd);
int phy_start_interrupts(struct phy_device *phydev); int phy_start_interrupts(struct phy_device *phydev);
void phy_print_status(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) ...@@ -391,14 +391,16 @@ static int __ethtool_set_flags(struct net_device *dev, u32 data)
return 0; 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); bitmap_zero(dst, __ETHTOOL_LINK_MODE_MASK_NBITS);
dst[0] = legacy_u32; 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. */ /* 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) const unsigned long *src)
{ {
bool retval = true; bool retval = true;
...@@ -419,6 +421,7 @@ static bool convert_link_mode_to_legacy_u32(u32 *legacy_u32, ...@@ -419,6 +421,7 @@ static bool convert_link_mode_to_legacy_u32(u32 *legacy_u32,
*legacy_u32 = src[0]; *legacy_u32 = src[0];
return retval; return retval;
} }
EXPORT_SYMBOL(ethtool_convert_link_mode_to_legacy_u32);
/* return false if legacy contained non-0 deprecated fields /* return false if legacy contained non-0 deprecated fields
* transceiver/maxtxpkt/maxrxpkt. rest of ksettings always updated * transceiver/maxtxpkt/maxrxpkt. rest of ksettings always updated
...@@ -441,13 +444,13 @@ convert_legacy_settings_to_link_ksettings( ...@@ -441,13 +444,13 @@ convert_legacy_settings_to_link_ksettings(
legacy_settings->maxrxpkt) legacy_settings->maxrxpkt)
retval = false; retval = false;
convert_legacy_u32_to_link_mode( ethtool_convert_legacy_u32_to_link_mode(
link_ksettings->link_modes.supported, link_ksettings->link_modes.supported,
legacy_settings->supported); legacy_settings->supported);
convert_legacy_u32_to_link_mode( ethtool_convert_legacy_u32_to_link_mode(
link_ksettings->link_modes.advertising, link_ksettings->link_modes.advertising,
legacy_settings->advertising); legacy_settings->advertising);
convert_legacy_u32_to_link_mode( ethtool_convert_legacy_u32_to_link_mode(
link_ksettings->link_modes.lp_advertising, link_ksettings->link_modes.lp_advertising,
legacy_settings->lp_advertising); legacy_settings->lp_advertising);
link_ksettings->base.speed link_ksettings->base.speed
...@@ -486,13 +489,13 @@ convert_link_ksettings_to_legacy_settings( ...@@ -486,13 +489,13 @@ convert_link_ksettings_to_legacy_settings(
* __u32 maxrxpkt; * __u32 maxrxpkt;
*/ */
retval &= convert_link_mode_to_legacy_u32( retval &= ethtool_convert_link_mode_to_legacy_u32(
&legacy_settings->supported, &legacy_settings->supported,
link_ksettings->link_modes.supported); link_ksettings->link_modes.supported);
retval &= convert_link_mode_to_legacy_u32( retval &= ethtool_convert_link_mode_to_legacy_u32(
&legacy_settings->advertising, &legacy_settings->advertising,
link_ksettings->link_modes.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, &legacy_settings->lp_advertising,
link_ksettings->link_modes.lp_advertising); link_ksettings->link_modes.lp_advertising);
ethtool_cmd_speed_set(legacy_settings, link_ksettings->base.speed); 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