Commit 9f2f13f4 authored by Alexandru Ardelean's avatar Alexandru Ardelean Committed by David S. Miller

ethtool: implement Energy Detect Powerdown support via phy-tunable

The `phy_tunable_id` has been named `ETHTOOL_PHY_EDPD` since it looks like
this feature is common across other PHYs (like EEE), and defining
`ETHTOOL_PHY_ENERGY_DETECT_POWER_DOWN` seems too long.

The way EDPD works, is that the RX block is put to a lower power mode,
except for link-pulse detection circuits. The TX block is also put to low
power mode, but the PHY wakes-up periodically to send link pulses, to avoid
lock-ups in case the other side is also in EDPD mode.

Currently, there are 2 PHY drivers that look like they could use this new
PHY tunable feature: the `adin` && `micrel` PHYs.

The ADIN's datasheet mentions that TX pulses are at intervals of 1 second
default each, and they can be disabled. For the Micrel KSZ9031 PHY, the
datasheet does not mention whether they can be disabled, but mentions that
they can modified.

The way this change is structured, is similar to the PHY tunable downshift
control:
* a `ETHTOOL_PHY_EDPD_DFLT_TX_MSECS` value is exposed to cover a default
  TX interval; some PHYs could specify a certain value that makes sense
* `ETHTOOL_PHY_EDPD_NO_TX` would disable TX when EDPD is enabled
* `ETHTOOL_PHY_EDPD_DISABLE` will disable EDPD

As noted by the `ETHTOOL_PHY_EDPD_DFLT_TX_MSECS` the interval unit is 1
millisecond, which should cover a reasonable range of intervals:
 - from 1 millisecond, which does not sound like much of a power-saver
 - to ~65 seconds which is quite a lot to wait for a link to come up when
   plugging a cable
Reviewed-by: default avatarAndrew Lunn <andrew@lunn.ch>
Reviewed-by: default avatarFlorian Fainelli <f.fainelli@gmail.com>
Signed-off-by: default avatarAlexandru Ardelean <alexandru.ardelean@analog.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 56a4e37e
...@@ -259,10 +259,32 @@ struct ethtool_tunable { ...@@ -259,10 +259,32 @@ struct ethtool_tunable {
#define ETHTOOL_PHY_FAST_LINK_DOWN_ON 0 #define ETHTOOL_PHY_FAST_LINK_DOWN_ON 0
#define ETHTOOL_PHY_FAST_LINK_DOWN_OFF 0xff #define ETHTOOL_PHY_FAST_LINK_DOWN_OFF 0xff
/* Energy Detect Power Down (EDPD) is a feature supported by some PHYs, where
* the PHY's RX & TX blocks are put into a low-power mode when there is no
* link detected (typically cable is un-plugged). For RX, only a minimal
* link-detection is available, and for TX the PHY wakes up to send link pulses
* to avoid any lock-ups in case the peer PHY may also be running in EDPD mode.
*
* Some PHYs may support configuration of the wake-up interval for TX pulses,
* and some PHYs may support only disabling TX pulses entirely. For the latter
* a special value is required (ETHTOOL_PHY_EDPD_NO_TX) so that this can be
* configured from userspace (should the user want it).
*
* The interval units for TX wake-up are in milliseconds, since this should
* cover a reasonable range of intervals:
* - from 1 millisecond, which does not sound like much of a power-saver
* - to ~65 seconds which is quite a lot to wait for a link to come up when
* plugging a cable
*/
#define ETHTOOL_PHY_EDPD_DFLT_TX_MSECS 0xffff
#define ETHTOOL_PHY_EDPD_NO_TX 0xfffe
#define ETHTOOL_PHY_EDPD_DISABLE 0
enum phy_tunable_id { enum phy_tunable_id {
ETHTOOL_PHY_ID_UNSPEC, ETHTOOL_PHY_ID_UNSPEC,
ETHTOOL_PHY_DOWNSHIFT, ETHTOOL_PHY_DOWNSHIFT,
ETHTOOL_PHY_FAST_LINK_DOWN, ETHTOOL_PHY_FAST_LINK_DOWN,
ETHTOOL_PHY_EDPD,
/* /*
* Add your fresh new phy tunable attribute above and remember to update * Add your fresh new phy tunable attribute above and remember to update
* phy_tunable_strings[] in net/core/ethtool.c * phy_tunable_strings[] in net/core/ethtool.c
......
...@@ -133,6 +133,7 @@ phy_tunable_strings[__ETHTOOL_PHY_TUNABLE_COUNT][ETH_GSTRING_LEN] = { ...@@ -133,6 +133,7 @@ phy_tunable_strings[__ETHTOOL_PHY_TUNABLE_COUNT][ETH_GSTRING_LEN] = {
[ETHTOOL_ID_UNSPEC] = "Unspec", [ETHTOOL_ID_UNSPEC] = "Unspec",
[ETHTOOL_PHY_DOWNSHIFT] = "phy-downshift", [ETHTOOL_PHY_DOWNSHIFT] = "phy-downshift",
[ETHTOOL_PHY_FAST_LINK_DOWN] = "phy-fast-link-down", [ETHTOOL_PHY_FAST_LINK_DOWN] = "phy-fast-link-down",
[ETHTOOL_PHY_EDPD] = "phy-energy-detect-power-down",
}; };
static int ethtool_get_features(struct net_device *dev, void __user *useraddr) static int ethtool_get_features(struct net_device *dev, void __user *useraddr)
...@@ -2451,6 +2452,11 @@ static int ethtool_phy_tunable_valid(const struct ethtool_tunable *tuna) ...@@ -2451,6 +2452,11 @@ static int ethtool_phy_tunable_valid(const struct ethtool_tunable *tuna)
tuna->type_id != ETHTOOL_TUNABLE_U8) tuna->type_id != ETHTOOL_TUNABLE_U8)
return -EINVAL; return -EINVAL;
break; break;
case ETHTOOL_PHY_EDPD:
if (tuna->len != sizeof(u16) ||
tuna->type_id != ETHTOOL_TUNABLE_U16)
return -EINVAL;
break;
default: default:
return -EINVAL; return -EINVAL;
} }
......
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