2016-04-14 22:35:15

by Philippe Reynes

[permalink] [raw]
Subject: [PATCH 0/3] 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, ....


Philippe Reynes (3):
net: ethtool: export conversion function between u32 and link mode
phy: add generic function to support ksetting support
fec: move to new ethtool api {get|set}_link_ksettings

drivers/net/ethernet/freescale/fec_main.c | 16 +++---
drivers/net/phy/phy.c | 81 +++++++++++++++++++++++++++++
include/linux/ethtool.h | 7 +++
include/linux/phy.h | 4 ++
net/core/ethtool.c | 21 ++++---
5 files changed, 112 insertions(+), 17 deletions(-)

--
1.7.4.4


2016-04-14 22:35:26

by Philippe Reynes

[permalink] [raw]
Subject: [PATCH 3/3] fec: move to new ethtool api {get|set}_link_ksettings

The ethtool api {get|set}_settings is deprecated.
We move the fec driver to new api {get|set}_link_ksettings.

Signed-off-by: Philippe Reynes <[email protected]>
---
drivers/net/ethernet/freescale/fec_main.c | 16 ++++++++--------
1 files changed, 8 insertions(+), 8 deletions(-)

diff --git a/drivers/net/ethernet/freescale/fec_main.c b/drivers/net/ethernet/freescale/fec_main.c
index 08243c2..bfa10c3 100644
--- a/drivers/net/ethernet/freescale/fec_main.c
+++ b/drivers/net/ethernet/freescale/fec_main.c
@@ -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)
--
1.7.4.4

2016-04-14 22:35:51

by Philippe Reynes

[permalink] [raw]
Subject: [PATCH 2/3] phy: add generic function to support ksetting support

The old ethtool api (get_setting and set_setting) has
generic phy functions phy_ethtool_sset and phy_ethtool_gset.
To supprt the new ethtool api (get_link_ksettings and
set_link_ksettings), we add generic phy function
phy_ethtool_ksettings_get and phy_ethtool_ksettings_set.

Signed-off-by: Philippe Reynes <[email protected]>
---
drivers/net/phy/phy.c | 81 +++++++++++++++++++++++++++++++++++++++++++++++++
include/linux/phy.h | 4 ++
2 files changed, 85 insertions(+), 0 deletions(-)

diff --git a/drivers/net/phy/phy.c b/drivers/net/phy/phy.c
index 5590b9c..6f221c8 100644
--- a/drivers/net/phy/phy.c
+++ b/drivers/net/phy/phy.c
@@ -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
diff --git a/include/linux/phy.h b/include/linux/phy.h
index 2abd791..be3f83b 100644
--- a/include/linux/phy.h
+++ b/include/linux/phy.h
@@ -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);
--
1.7.4.4

2016-04-14 22:36:12

by Philippe Reynes

[permalink] [raw]
Subject: [PATCH 1/3] net: ethtool: export conversion function between u32 and link mode

The function convert_legacy_u32_to_link_mode and
convert_link_mode_to_legacy_u32 may be used outside
of ethtool.c. We rename them to ethtool_convert_...
and export them, so we could use them in others
drivers and modules.

Signed-off-by: Philippe Reynes <[email protected]>
---
include/linux/ethtool.h | 7 +++++++
net/core/ethtool.c | 21 ++++++++++++---------
2 files changed, 19 insertions(+), 9 deletions(-)

diff --git a/include/linux/ethtool.h b/include/linux/ethtool.h
index e2b7bf2..9ded8c6 100644
--- a/include/linux/ethtool.h
+++ b/include/linux/ethtool.h
@@ -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
diff --git a/net/core/ethtool.c b/net/core/ethtool.c
index f426c5a..81e3082 100644
--- a/net/core/ethtool.c
+++ b/net/core/ethtool.c
@@ -387,15 +387,17 @@ 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,
- const unsigned long *src)
+bool ethtool_convert_link_mode_to_legacy_u32(u32 *legacy_u32,
+ const unsigned long *src)
{
bool retval = true;

@@ -415,6 +417,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
@@ -437,13 +440,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
@@ -482,13 +485,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);
--
1.7.4.4

2016-04-15 02:51:07

by Andy Duan

[permalink] [raw]
Subject: RE: [PATCH 2/3] phy: add generic function to support ksetting support

From: Philippe Reynes <[email protected]> Sent: Friday, April 15, 2016 6:35 AM
> To: [email protected]; [email protected]; [email protected]; Fugang
> Duan <[email protected]>
> Cc: [email protected]; [email protected]; Philippe Reynes
> <[email protected]>
> Subject: [PATCH 2/3] phy: add generic function to support ksetting support
>
> The old ethtool api (get_setting and set_setting) has generic phy functions
> phy_ethtool_sset and phy_ethtool_gset.
> To supprt the new ethtool api (get_link_ksettings and set_link_ksettings), we
> add generic phy function phy_ethtool_ksettings_get and
> phy_ethtool_ksettings_set.
>
> Signed-off-by: Philippe Reynes <[email protected]>
> ---
> drivers/net/phy/phy.c | 81
> +++++++++++++++++++++++++++++++++++++++++++++++++
> include/linux/phy.h | 4 ++
> 2 files changed, 85 insertions(+), 0 deletions(-)
>
> diff --git a/drivers/net/phy/phy.c b/drivers/net/phy/phy.c index
> 5590b9c..6f221c8 100644
> --- a/drivers/net/phy/phy.c
> +++ b/drivers/net/phy/phy.c
> @@ -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
> diff --git a/include/linux/phy.h b/include/linux/phy.h index 2abd791..be3f83b
> 100644
> --- a/include/linux/phy.h
> +++ b/include/linux/phy.h
> @@ -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);
> --
> 1.7.4.4

It seems fine. There have many drivers need to update .set_settings/. get_settings, not only fsl fec driver.
And whether there still need to keep the old interface in phy.c driver ?

Regards,
Andy

2016-04-15 02:53:53

by Andy Duan

[permalink] [raw]
Subject: RE: [PATCH 3/3] fec: move to new ethtool api {get|set}_link_ksettings

From: Philippe Reynes <[email protected]> Sent: Friday, April 15, 2016 6:35 AM
> To: [email protected]; [email protected]; [email protected]; Fugang
> Duan <[email protected]>
> Cc: [email protected]; [email protected]; Philippe Reynes
> <[email protected]>
> Subject: [PATCH 3/3] fec: move to new ethtool api {get|set}_link_ksettings
>
> The ethtool api {get|set}_settings is deprecated.
> We move the fec driver to new api {get|set}_link_ksettings.
>
> Signed-off-by: Philippe Reynes <[email protected]>
> ---
> drivers/net/ethernet/freescale/fec_main.c | 16 ++++++++--------
> 1 files changed, 8 insertions(+), 8 deletions(-)
>
> diff --git a/drivers/net/ethernet/freescale/fec_main.c
> b/drivers/net/ethernet/freescale/fec_main.c
> index 08243c2..bfa10c3 100644
> --- a/drivers/net/ethernet/freescale/fec_main.c
> +++ b/drivers/net/ethernet/freescale/fec_main.c
> @@ -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)
> --
> 1.7.4.4

Acked-by: Fugang Duan <[email protected]>

2016-04-15 22:53:39

by Philippe Reynes

[permalink] [raw]
Subject: Re: [PATCH 2/3] phy: add generic function to support ksetting support

On 15/04/16 04:50, Fugang Duan wrote:
> From: Philippe Reynes<[email protected]> Sent: Friday, April 15, 2016 6:35 AM
>> To: [email protected]; [email protected]; [email protected]; Fugang
>> Duan<[email protected]>
>> Cc: [email protected]; [email protected]; Philippe Reynes
>> <[email protected]>
>> Subject: [PATCH 2/3] phy: add generic function to support ksetting support
>>
>> The old ethtool api (get_setting and set_setting) has generic phy functions
>> phy_ethtool_sset and phy_ethtool_gset.
>> To supprt the new ethtool api (get_link_ksettings and set_link_ksettings), we
>> add generic phy function phy_ethtool_ksettings_get and
>> phy_ethtool_ksettings_set.
>>
>> Signed-off-by: Philippe Reynes<[email protected]>
>> ---
>> drivers/net/phy/phy.c | 81
>> +++++++++++++++++++++++++++++++++++++++++++++++++
>> include/linux/phy.h | 4 ++
>> 2 files changed, 85 insertions(+), 0 deletions(-)
>>
>> diff --git a/drivers/net/phy/phy.c b/drivers/net/phy/phy.c index
>> 5590b9c..6f221c8 100644
>> --- a/drivers/net/phy/phy.c
>> +++ b/drivers/net/phy/phy.c
>> @@ -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
>> diff --git a/include/linux/phy.h b/include/linux/phy.h index 2abd791..be3f83b
>> 100644
>> --- a/include/linux/phy.h
>> +++ b/include/linux/phy.h
>> @@ -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);
>> --
>> 1.7.4.4
>
> It seems fine. There have many drivers need to update .set_settings/. get_settings, not only fsl fec driver.

Yes, a lot a drivers needs to be updated. Right now, I've only updated the fec.
If everybody agree, I can replace them.

> And whether there still need to keep the old interface in phy.c driver ?


I think we could remove the old interface when all the drivers would have moved to the new interface.

> Regards,
> Andy

Regards,
Philippe

2016-04-18 18:45:29

by David Miller

[permalink] [raw]
Subject: Re: [PATCH 0/3] fec: ethtool: move to new api {get|set}_link_ksettings

From: Philippe Reynes <[email protected]>
Date: Fri, 15 Apr 2016 00:34:58 +0200

> 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, ....

Series applied, thanks.