Merge branch 'ethtool-add-support-for-Fast-Link-Down-as-new-PHY-tunable'
Heiner Kallweit says: ==================== ethtool: add support for Fast Link Down as new PHY tunable This adds support for Fast Link Down as new PHY tunable. Fast Link Down reduces the time until a link down event is reported for 1000BaseT. According to the standard it's 750ms what is too long for several use cases. This is the kernel-related series, the ethtool userspace extension I'd submit once the kernel part has been applied. v2: - add describing comment in patch 1 ==================== Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
Коммит
d7aa033831
|
@ -29,6 +29,7 @@
|
|||
#include <linux/ethtool.h>
|
||||
#include <linux/phy.h>
|
||||
#include <linux/marvell_phy.h>
|
||||
#include <linux/bitfield.h>
|
||||
#include <linux/of.h>
|
||||
|
||||
#include <linux/io.h>
|
||||
|
@ -91,6 +92,14 @@
|
|||
#define MII_88E1510_TEMP_SENSOR 0x1b
|
||||
#define MII_88E1510_TEMP_SENSOR_MASK 0xff
|
||||
|
||||
#define MII_88E1540_COPPER_CTRL3 0x1a
|
||||
#define MII_88E1540_COPPER_CTRL3_LINK_DOWN_DELAY_MASK GENMASK(11, 10)
|
||||
#define MII_88E1540_COPPER_CTRL3_LINK_DOWN_DELAY_00MS 0
|
||||
#define MII_88E1540_COPPER_CTRL3_LINK_DOWN_DELAY_10MS 1
|
||||
#define MII_88E1540_COPPER_CTRL3_LINK_DOWN_DELAY_20MS 2
|
||||
#define MII_88E1540_COPPER_CTRL3_LINK_DOWN_DELAY_40MS 3
|
||||
#define MII_88E1540_COPPER_CTRL3_FAST_LINK_DOWN BIT(9)
|
||||
|
||||
#define MII_88E6390_MISC_TEST 0x1b
|
||||
#define MII_88E6390_MISC_TEST_SAMPLE_1S 0
|
||||
#define MII_88E6390_MISC_TEST_SAMPLE_10MS BIT(14)
|
||||
|
@ -1025,6 +1034,101 @@ static int m88e1145_config_init(struct phy_device *phydev)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int m88e1540_get_fld(struct phy_device *phydev, u8 *msecs)
|
||||
{
|
||||
int val;
|
||||
|
||||
val = phy_read(phydev, MII_88E1540_COPPER_CTRL3);
|
||||
if (val < 0)
|
||||
return val;
|
||||
|
||||
if (!(val & MII_88E1540_COPPER_CTRL3_FAST_LINK_DOWN)) {
|
||||
*msecs = ETHTOOL_PHY_FAST_LINK_DOWN_OFF;
|
||||
return 0;
|
||||
}
|
||||
|
||||
val = FIELD_GET(MII_88E1540_COPPER_CTRL3_LINK_DOWN_DELAY_MASK, val);
|
||||
|
||||
switch (val) {
|
||||
case MII_88E1540_COPPER_CTRL3_LINK_DOWN_DELAY_00MS:
|
||||
*msecs = 0;
|
||||
break;
|
||||
case MII_88E1540_COPPER_CTRL3_LINK_DOWN_DELAY_10MS:
|
||||
*msecs = 10;
|
||||
break;
|
||||
case MII_88E1540_COPPER_CTRL3_LINK_DOWN_DELAY_20MS:
|
||||
*msecs = 20;
|
||||
break;
|
||||
case MII_88E1540_COPPER_CTRL3_LINK_DOWN_DELAY_40MS:
|
||||
*msecs = 40;
|
||||
break;
|
||||
default:
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int m88e1540_set_fld(struct phy_device *phydev, const u8 *msecs)
|
||||
{
|
||||
struct ethtool_eee eee;
|
||||
int val, ret;
|
||||
|
||||
if (*msecs == ETHTOOL_PHY_FAST_LINK_DOWN_OFF)
|
||||
return phy_clear_bits(phydev, MII_88E1540_COPPER_CTRL3,
|
||||
MII_88E1540_COPPER_CTRL3_FAST_LINK_DOWN);
|
||||
|
||||
/* According to the Marvell data sheet EEE must be disabled for
|
||||
* Fast Link Down detection to work properly
|
||||
*/
|
||||
ret = phy_ethtool_get_eee(phydev, &eee);
|
||||
if (!ret && eee.eee_enabled) {
|
||||
phydev_warn(phydev, "Fast Link Down detection requires EEE to be disabled!\n");
|
||||
return -EBUSY;
|
||||
}
|
||||
|
||||
if (*msecs <= 5)
|
||||
val = MII_88E1540_COPPER_CTRL3_LINK_DOWN_DELAY_00MS;
|
||||
else if (*msecs <= 15)
|
||||
val = MII_88E1540_COPPER_CTRL3_LINK_DOWN_DELAY_10MS;
|
||||
else if (*msecs <= 30)
|
||||
val = MII_88E1540_COPPER_CTRL3_LINK_DOWN_DELAY_20MS;
|
||||
else
|
||||
val = MII_88E1540_COPPER_CTRL3_LINK_DOWN_DELAY_40MS;
|
||||
|
||||
val = FIELD_PREP(MII_88E1540_COPPER_CTRL3_LINK_DOWN_DELAY_MASK, val);
|
||||
|
||||
ret = phy_modify(phydev, MII_88E1540_COPPER_CTRL3,
|
||||
MII_88E1540_COPPER_CTRL3_LINK_DOWN_DELAY_MASK, val);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
return phy_set_bits(phydev, MII_88E1540_COPPER_CTRL3,
|
||||
MII_88E1540_COPPER_CTRL3_FAST_LINK_DOWN);
|
||||
}
|
||||
|
||||
static int m88e1540_get_tunable(struct phy_device *phydev,
|
||||
struct ethtool_tunable *tuna, void *data)
|
||||
{
|
||||
switch (tuna->id) {
|
||||
case ETHTOOL_PHY_FAST_LINK_DOWN:
|
||||
return m88e1540_get_fld(phydev, data);
|
||||
default:
|
||||
return -EOPNOTSUPP;
|
||||
}
|
||||
}
|
||||
|
||||
static int m88e1540_set_tunable(struct phy_device *phydev,
|
||||
struct ethtool_tunable *tuna, const void *data)
|
||||
{
|
||||
switch (tuna->id) {
|
||||
case ETHTOOL_PHY_FAST_LINK_DOWN:
|
||||
return m88e1540_set_fld(phydev, data);
|
||||
default:
|
||||
return -EOPNOTSUPP;
|
||||
}
|
||||
}
|
||||
|
||||
/* The VOD can be out of specification on link up. Poke an
|
||||
* undocumented register, in an undocumented page, with a magic value
|
||||
* to fix this.
|
||||
|
@ -2247,6 +2351,8 @@ static struct phy_driver marvell_drivers[] = {
|
|||
.get_sset_count = marvell_get_sset_count,
|
||||
.get_strings = marvell_get_strings,
|
||||
.get_stats = marvell_get_stats,
|
||||
.get_tunable = m88e1540_get_tunable,
|
||||
.set_tunable = m88e1540_set_tunable,
|
||||
},
|
||||
{
|
||||
.phy_id = MARVELL_PHY_ID_88E1545,
|
||||
|
@ -2307,6 +2413,8 @@ static struct phy_driver marvell_drivers[] = {
|
|||
.get_sset_count = marvell_get_sset_count,
|
||||
.get_strings = marvell_get_strings,
|
||||
.get_stats = marvell_get_stats,
|
||||
.get_tunable = m88e1540_get_tunable,
|
||||
.set_tunable = m88e1540_set_tunable,
|
||||
},
|
||||
};
|
||||
|
||||
|
|
|
@ -252,9 +252,17 @@ struct ethtool_tunable {
|
|||
#define DOWNSHIFT_DEV_DEFAULT_COUNT 0xff
|
||||
#define DOWNSHIFT_DEV_DISABLE 0
|
||||
|
||||
/* Time in msecs after which link is reported as down
|
||||
* 0 = lowest time supported by the PHY
|
||||
* 0xff = off, link down detection according to standard
|
||||
*/
|
||||
#define ETHTOOL_PHY_FAST_LINK_DOWN_ON 0
|
||||
#define ETHTOOL_PHY_FAST_LINK_DOWN_OFF 0xff
|
||||
|
||||
enum phy_tunable_id {
|
||||
ETHTOOL_PHY_ID_UNSPEC,
|
||||
ETHTOOL_PHY_DOWNSHIFT,
|
||||
ETHTOOL_PHY_FAST_LINK_DOWN,
|
||||
/*
|
||||
* Add your fresh new phy tunable attribute above and remember to update
|
||||
* phy_tunable_strings[] in net/core/ethtool.c
|
||||
|
|
|
@ -136,6 +136,7 @@ static const char
|
|||
phy_tunable_strings[__ETHTOOL_PHY_TUNABLE_COUNT][ETH_GSTRING_LEN] = {
|
||||
[ETHTOOL_ID_UNSPEC] = "Unspec",
|
||||
[ETHTOOL_PHY_DOWNSHIFT] = "phy-downshift",
|
||||
[ETHTOOL_PHY_FAST_LINK_DOWN] = "phy-fast-link-down",
|
||||
};
|
||||
|
||||
static int ethtool_get_features(struct net_device *dev, void __user *useraddr)
|
||||
|
@ -2432,6 +2433,7 @@ static int ethtool_phy_tunable_valid(const struct ethtool_tunable *tuna)
|
|||
{
|
||||
switch (tuna->id) {
|
||||
case ETHTOOL_PHY_DOWNSHIFT:
|
||||
case ETHTOOL_PHY_FAST_LINK_DOWN:
|
||||
if (tuna->len != sizeof(u8) ||
|
||||
tuna->type_id != ETHTOOL_TUNABLE_U8)
|
||||
return -EINVAL;
|
||||
|
|
Загрузка…
Ссылка в новой задаче