diff options
author | Guenter Roeck <linux@roeck-us.net> | 2015-03-06 22:23:51 -0800 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2015-03-07 22:34:10 -0500 |
commit | 11b3b45d69f1709aae6bb48b214064e22f0b5ef7 (patch) | |
tree | ebf2a6f9f6b76520bbcbe58d614e11e33d592adf /drivers/net/dsa | |
parent | 6f5a272c99108d9f8450c454a4baede9e7cc643f (diff) | |
download | linux-stable-11b3b45d69f1709aae6bb48b214064e22f0b5ef7.tar.gz linux-stable-11b3b45d69f1709aae6bb48b214064e22f0b5ef7.tar.bz2 linux-stable-11b3b45d69f1709aae6bb48b214064e22f0b5ef7.zip |
net: dsa: mv88e6xxx: Add EEE support
EEE configuration is similar for the various MV88E6xxx chips.
Add generic support for it.
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
Reviewed-by: Florian Fainelli <f.fainelli@gmail.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/net/dsa')
-rw-r--r-- | drivers/net/dsa/mv88e6xxx.c | 51 | ||||
-rw-r--r-- | drivers/net/dsa/mv88e6xxx.h | 3 |
2 files changed, 54 insertions, 0 deletions
diff --git a/drivers/net/dsa/mv88e6xxx.c b/drivers/net/dsa/mv88e6xxx.c index a83ace0803e7..c18ffc98aacc 100644 --- a/drivers/net/dsa/mv88e6xxx.c +++ b/drivers/net/dsa/mv88e6xxx.c @@ -649,6 +649,57 @@ int mv88e6xxx_phy_write_indirect(struct dsa_switch *ds, int addr, int regnum, return mv88e6xxx_phy_wait(ds); } +int mv88e6xxx_get_eee(struct dsa_switch *ds, int port, struct ethtool_eee *e) +{ + int reg; + + reg = mv88e6xxx_phy_read_indirect(ds, port, 16); + if (reg < 0) + return -EOPNOTSUPP; + + e->eee_enabled = !!(reg & 0x0200); + e->tx_lpi_enabled = !!(reg & 0x0100); + + reg = REG_READ(REG_PORT(port), 0); + e->eee_active = !!(reg & 0x0040); + + return 0; +} + +static int mv88e6xxx_eee_enable_set(struct dsa_switch *ds, int port, + bool eee_enabled, bool tx_lpi_enabled) +{ + int reg, nreg; + + reg = mv88e6xxx_phy_read_indirect(ds, port, 16); + if (reg < 0) + return reg; + + nreg = reg & ~0x0300; + if (eee_enabled) + nreg |= 0x0200; + if (tx_lpi_enabled) + nreg |= 0x0100; + + if (nreg != reg) + return mv88e6xxx_phy_write_indirect(ds, port, 16, nreg); + + return 0; +} + +int mv88e6xxx_set_eee(struct dsa_switch *ds, int port, + struct phy_device *phydev, struct ethtool_eee *e) +{ + int ret; + + ret = mv88e6xxx_eee_enable_set(ds, port, e->eee_enabled, + e->tx_lpi_enabled); + if (ret) + return -EOPNOTSUPP; + + return 0; +} + static int __init mv88e6xxx_init(void) { #if IS_ENABLED(CONFIG_NET_DSA_MV88E6131) diff --git a/drivers/net/dsa/mv88e6xxx.h b/drivers/net/dsa/mv88e6xxx.h index 72942271bb67..5fd42ced9011 100644 --- a/drivers/net/dsa/mv88e6xxx.h +++ b/drivers/net/dsa/mv88e6xxx.h @@ -88,6 +88,9 @@ int mv88e6xxx_eeprom_busy_wait(struct dsa_switch *ds); int mv88e6xxx_phy_read_indirect(struct dsa_switch *ds, int addr, int regnum); int mv88e6xxx_phy_write_indirect(struct dsa_switch *ds, int addr, int regnum, u16 val); +int mv88e6xxx_get_eee(struct dsa_switch *ds, int port, struct ethtool_eee *e); +int mv88e6xxx_set_eee(struct dsa_switch *ds, int port, + struct phy_device *phydev, struct ethtool_eee *e); extern struct dsa_switch_driver mv88e6131_switch_driver; extern struct dsa_switch_driver mv88e6123_61_65_switch_driver; |