Commit cb5b136c authored by David S. Miller's avatar David S. Miller

Merge branch 'dsa-rework-EEE-support'

Vivien Didelot says:

====================
net: dsa: rework EEE support

EEE implies configuring the port's PHY and MAC of both ends of the wire.

The current EEE support in DSA mixes PHY and MAC configuration, which is
bad because PHYs must be configured through a proper PHY driver. The DSA
switch operations for EEE are only meant for configuring the port's MAC,
which are integrated in the Ethernet switch device.

This patchset fixes the EEE support in qca8k driver, makes the DSA layer
call phy_init_eee for all drivers, and remove the EEE support from the
mv88e6xxx driver since the Marvell PHY driver should be enough for it.

Changes in v2:
 - make PHY device and DSA EEE ops mandatory for slave EEE operations.
 - simply return 0 in drivers which don't need to do anything to
   configure the port' MAC. Subsequent PHY calls will be enough.
====================
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parents 13e6be2d 08f50061
......@@ -327,12 +327,8 @@ static void bcm_sf2_port_disable(struct dsa_switch *ds, int port,
static int bcm_sf2_eee_init(struct dsa_switch *ds, int port,
struct phy_device *phy)
{
struct bcm_sf2_priv *priv = bcm_sf2_to_priv(ds);
struct ethtool_eee *p = &priv->port_sts[port].eee;
int ret;
p->supported = (SUPPORTED_1000baseT_Full | SUPPORTED_100baseT_Full);
ret = phy_init_eee(phy, 0);
if (ret)
return 0;
......@@ -342,8 +338,8 @@ static int bcm_sf2_eee_init(struct dsa_switch *ds, int port,
return 1;
}
static int bcm_sf2_sw_get_eee(struct dsa_switch *ds, int port,
struct ethtool_eee *e)
static int bcm_sf2_sw_get_mac_eee(struct dsa_switch *ds, int port,
struct ethtool_eee *e)
{
struct bcm_sf2_priv *priv = bcm_sf2_to_priv(ds);
struct ethtool_eee *p = &priv->port_sts[port].eee;
......@@ -356,22 +352,14 @@ static int bcm_sf2_sw_get_eee(struct dsa_switch *ds, int port,
return 0;
}
static int bcm_sf2_sw_set_eee(struct dsa_switch *ds, int port,
struct phy_device *phydev,
struct ethtool_eee *e)
static int bcm_sf2_sw_set_mac_eee(struct dsa_switch *ds, int port,
struct ethtool_eee *e)
{
struct bcm_sf2_priv *priv = bcm_sf2_to_priv(ds);
struct ethtool_eee *p = &priv->port_sts[port].eee;
p->eee_enabled = e->eee_enabled;
if (!p->eee_enabled) {
bcm_sf2_eee_enable_set(ds, port, false);
} else {
p->eee_enabled = bcm_sf2_eee_init(ds, port, phydev);
if (!p->eee_enabled)
return -EOPNOTSUPP;
}
bcm_sf2_eee_enable_set(ds, port, e->eee_enabled);
return 0;
}
......@@ -1023,8 +1011,8 @@ static const struct dsa_switch_ops bcm_sf2_ops = {
.set_wol = bcm_sf2_sw_set_wol,
.port_enable = bcm_sf2_port_setup,
.port_disable = bcm_sf2_port_disable,
.get_eee = bcm_sf2_sw_get_eee,
.set_eee = bcm_sf2_sw_set_eee,
.get_mac_eee = bcm_sf2_sw_get_mac_eee,
.set_mac_eee = bcm_sf2_sw_set_mac_eee,
.port_bridge_join = b53_br_join,
.port_bridge_leave = b53_br_leave,
.port_stp_state_set = b53_br_set_stp_state,
......
......@@ -810,56 +810,18 @@ static void mv88e6xxx_get_regs(struct dsa_switch *ds, int port,
mutex_unlock(&chip->reg_lock);
}
static int mv88e6xxx_energy_detect_read(struct mv88e6xxx_chip *chip, int port,
struct ethtool_eee *eee)
static int mv88e6xxx_get_mac_eee(struct dsa_switch *ds, int port,
struct ethtool_eee *e)
{
int err;
if (!chip->info->ops->phy_energy_detect_read)
return -EOPNOTSUPP;
/* assign eee->eee_enabled and eee->tx_lpi_enabled */
err = chip->info->ops->phy_energy_detect_read(chip, port, eee);
if (err)
return err;
/* assign eee->eee_active */
return mv88e6xxx_port_status_eee(chip, port, eee);
}
static int mv88e6xxx_energy_detect_write(struct mv88e6xxx_chip *chip, int port,
struct ethtool_eee *eee)
{
if (!chip->info->ops->phy_energy_detect_write)
return -EOPNOTSUPP;
return chip->info->ops->phy_energy_detect_write(chip, port, eee);
}
static int mv88e6xxx_get_eee(struct dsa_switch *ds, int port,
struct ethtool_eee *e)
{
struct mv88e6xxx_chip *chip = ds->priv;
int err;
mutex_lock(&chip->reg_lock);
err = mv88e6xxx_energy_detect_read(chip, port, e);
mutex_unlock(&chip->reg_lock);
return err;
/* Nothing to do on the port's MAC */
return 0;
}
static int mv88e6xxx_set_eee(struct dsa_switch *ds, int port,
struct phy_device *phydev, struct ethtool_eee *e)
static int mv88e6xxx_set_mac_eee(struct dsa_switch *ds, int port,
struct ethtool_eee *e)
{
struct mv88e6xxx_chip *chip = ds->priv;
int err;
mutex_lock(&chip->reg_lock);
err = mv88e6xxx_energy_detect_write(chip, port, e);
mutex_unlock(&chip->reg_lock);
return err;
/* Nothing to do on the port's MAC */
return 0;
}
static u16 mv88e6xxx_port_vlan(struct mv88e6xxx_chip *chip, int dev, int port)
......@@ -2521,8 +2483,6 @@ static const struct mv88e6xxx_ops mv88e6141_ops = {
.set_switch_mac = mv88e6xxx_g2_set_switch_mac,
.phy_read = mv88e6xxx_g2_smi_phy_read,
.phy_write = mv88e6xxx_g2_smi_phy_write,
.phy_energy_detect_read = mv88e6352_phy_energy_detect_read,
.phy_energy_detect_write = mv88e6352_phy_energy_detect_write,
.port_set_link = mv88e6xxx_port_set_link,
.port_set_duplex = mv88e6xxx_port_set_duplex,
.port_set_rgmii_delay = mv88e6390_port_set_rgmii_delay,
......@@ -2648,8 +2608,6 @@ static const struct mv88e6xxx_ops mv88e6172_ops = {
.set_switch_mac = mv88e6xxx_g2_set_switch_mac,
.phy_read = mv88e6xxx_g2_smi_phy_read,
.phy_write = mv88e6xxx_g2_smi_phy_write,
.phy_energy_detect_read = mv88e6352_phy_energy_detect_read,
.phy_energy_detect_write = mv88e6352_phy_energy_detect_write,
.port_set_link = mv88e6xxx_port_set_link,
.port_set_duplex = mv88e6xxx_port_set_duplex,
.port_set_rgmii_delay = mv88e6352_port_set_rgmii_delay,
......@@ -2719,8 +2677,6 @@ static const struct mv88e6xxx_ops mv88e6176_ops = {
.set_switch_mac = mv88e6xxx_g2_set_switch_mac,
.phy_read = mv88e6xxx_g2_smi_phy_read,
.phy_write = mv88e6xxx_g2_smi_phy_write,
.phy_energy_detect_read = mv88e6352_phy_energy_detect_read,
.phy_energy_detect_write = mv88e6352_phy_energy_detect_write,
.port_set_link = mv88e6xxx_port_set_link,
.port_set_duplex = mv88e6xxx_port_set_duplex,
.port_set_rgmii_delay = mv88e6352_port_set_rgmii_delay,
......@@ -2784,8 +2740,6 @@ static const struct mv88e6xxx_ops mv88e6190_ops = {
.set_switch_mac = mv88e6xxx_g2_set_switch_mac,
.phy_read = mv88e6xxx_g2_smi_phy_read,
.phy_write = mv88e6xxx_g2_smi_phy_write,
.phy_energy_detect_read = mv88e6390_phy_energy_detect_read,
.phy_energy_detect_write = mv88e6390_phy_energy_detect_write,
.port_set_link = mv88e6xxx_port_set_link,
.port_set_duplex = mv88e6xxx_port_set_duplex,
.port_set_rgmii_delay = mv88e6390_port_set_rgmii_delay,
......@@ -2821,8 +2775,6 @@ static const struct mv88e6xxx_ops mv88e6190x_ops = {
.set_switch_mac = mv88e6xxx_g2_set_switch_mac,
.phy_read = mv88e6xxx_g2_smi_phy_read,
.phy_write = mv88e6xxx_g2_smi_phy_write,
.phy_energy_detect_read = mv88e6390_phy_energy_detect_read,
.phy_energy_detect_write = mv88e6390_phy_energy_detect_write,
.port_set_link = mv88e6xxx_port_set_link,
.port_set_duplex = mv88e6xxx_port_set_duplex,
.port_set_rgmii_delay = mv88e6390_port_set_rgmii_delay,
......@@ -2858,8 +2810,6 @@ static const struct mv88e6xxx_ops mv88e6191_ops = {
.set_switch_mac = mv88e6xxx_g2_set_switch_mac,
.phy_read = mv88e6xxx_g2_smi_phy_read,
.phy_write = mv88e6xxx_g2_smi_phy_write,
.phy_energy_detect_read = mv88e6390_phy_energy_detect_read,
.phy_energy_detect_write = mv88e6390_phy_energy_detect_write,
.port_set_link = mv88e6xxx_port_set_link,
.port_set_duplex = mv88e6xxx_port_set_duplex,
.port_set_rgmii_delay = mv88e6390_port_set_rgmii_delay,
......@@ -2895,8 +2845,6 @@ static const struct mv88e6xxx_ops mv88e6240_ops = {
.set_switch_mac = mv88e6xxx_g2_set_switch_mac,
.phy_read = mv88e6xxx_g2_smi_phy_read,
.phy_write = mv88e6xxx_g2_smi_phy_write,
.phy_energy_detect_read = mv88e6352_phy_energy_detect_read,
.phy_energy_detect_write = mv88e6352_phy_energy_detect_write,
.port_set_link = mv88e6xxx_port_set_link,
.port_set_duplex = mv88e6xxx_port_set_duplex,
.port_set_rgmii_delay = mv88e6352_port_set_rgmii_delay,
......@@ -2933,8 +2881,6 @@ static const struct mv88e6xxx_ops mv88e6290_ops = {
.set_switch_mac = mv88e6xxx_g2_set_switch_mac,
.phy_read = mv88e6xxx_g2_smi_phy_read,
.phy_write = mv88e6xxx_g2_smi_phy_write,
.phy_energy_detect_read = mv88e6390_phy_energy_detect_read,
.phy_energy_detect_write = mv88e6390_phy_energy_detect_write,
.port_set_link = mv88e6xxx_port_set_link,
.port_set_duplex = mv88e6xxx_port_set_duplex,
.port_set_rgmii_delay = mv88e6390_port_set_rgmii_delay,
......@@ -2971,8 +2917,6 @@ static const struct mv88e6xxx_ops mv88e6320_ops = {
.set_switch_mac = mv88e6xxx_g2_set_switch_mac,
.phy_read = mv88e6xxx_g2_smi_phy_read,
.phy_write = mv88e6xxx_g2_smi_phy_write,
.phy_energy_detect_read = mv88e6352_phy_energy_detect_read,
.phy_energy_detect_write = mv88e6352_phy_energy_detect_write,
.port_set_link = mv88e6xxx_port_set_link,
.port_set_duplex = mv88e6xxx_port_set_duplex,
.port_set_speed = mv88e6185_port_set_speed,
......@@ -3006,8 +2950,6 @@ static const struct mv88e6xxx_ops mv88e6321_ops = {
.set_switch_mac = mv88e6xxx_g2_set_switch_mac,
.phy_read = mv88e6xxx_g2_smi_phy_read,
.phy_write = mv88e6xxx_g2_smi_phy_write,
.phy_energy_detect_read = mv88e6352_phy_energy_detect_read,
.phy_energy_detect_write = mv88e6352_phy_energy_detect_write,
.port_set_link = mv88e6xxx_port_set_link,
.port_set_duplex = mv88e6xxx_port_set_duplex,
.port_set_speed = mv88e6185_port_set_speed,
......@@ -3039,8 +2981,6 @@ static const struct mv88e6xxx_ops mv88e6341_ops = {
.set_switch_mac = mv88e6xxx_g2_set_switch_mac,
.phy_read = mv88e6xxx_g2_smi_phy_read,
.phy_write = mv88e6xxx_g2_smi_phy_write,
.phy_energy_detect_read = mv88e6352_phy_energy_detect_read,
.phy_energy_detect_write = mv88e6352_phy_energy_detect_write,
.port_set_link = mv88e6xxx_port_set_link,
.port_set_duplex = mv88e6xxx_port_set_duplex,
.port_set_rgmii_delay = mv88e6390_port_set_rgmii_delay,
......@@ -3142,8 +3082,6 @@ static const struct mv88e6xxx_ops mv88e6352_ops = {
.set_switch_mac = mv88e6xxx_g2_set_switch_mac,
.phy_read = mv88e6xxx_g2_smi_phy_read,
.phy_write = mv88e6xxx_g2_smi_phy_write,
.phy_energy_detect_read = mv88e6352_phy_energy_detect_read,
.phy_energy_detect_write = mv88e6352_phy_energy_detect_write,
.port_set_link = mv88e6xxx_port_set_link,
.port_set_duplex = mv88e6xxx_port_set_duplex,
.port_set_rgmii_delay = mv88e6352_port_set_rgmii_delay,
......@@ -3180,8 +3118,6 @@ static const struct mv88e6xxx_ops mv88e6390_ops = {
.set_switch_mac = mv88e6xxx_g2_set_switch_mac,
.phy_read = mv88e6xxx_g2_smi_phy_read,
.phy_write = mv88e6xxx_g2_smi_phy_write,
.phy_energy_detect_read = mv88e6390_phy_energy_detect_read,
.phy_energy_detect_write = mv88e6390_phy_energy_detect_write,
.port_set_link = mv88e6xxx_port_set_link,
.port_set_duplex = mv88e6xxx_port_set_duplex,
.port_set_rgmii_delay = mv88e6390_port_set_rgmii_delay,
......@@ -3220,8 +3156,6 @@ static const struct mv88e6xxx_ops mv88e6390x_ops = {
.set_switch_mac = mv88e6xxx_g2_set_switch_mac,
.phy_read = mv88e6xxx_g2_smi_phy_read,
.phy_write = mv88e6xxx_g2_smi_phy_write,
.phy_energy_detect_read = mv88e6390_phy_energy_detect_read,
.phy_energy_detect_write = mv88e6390_phy_energy_detect_write,
.port_set_link = mv88e6xxx_port_set_link,
.port_set_duplex = mv88e6xxx_port_set_duplex,
.port_set_rgmii_delay = mv88e6390_port_set_rgmii_delay,
......@@ -3956,8 +3890,8 @@ static const struct dsa_switch_ops mv88e6xxx_switch_ops = {
.get_sset_count = mv88e6xxx_get_sset_count,
.port_enable = mv88e6xxx_port_enable,
.port_disable = mv88e6xxx_port_disable,
.set_eee = mv88e6xxx_set_eee,
.get_eee = mv88e6xxx_get_eee,
.get_mac_eee = mv88e6xxx_get_mac_eee,
.set_mac_eee = mv88e6xxx_set_mac_eee,
.get_eeprom_len = mv88e6xxx_get_eeprom_len,
.get_eeprom = mv88e6xxx_get_eeprom,
.set_eeprom = mv88e6xxx_set_eeprom,
......
......@@ -239,12 +239,6 @@ struct mv88e6xxx_ops {
struct mii_bus *bus,
int addr, int reg, u16 val);
/* Copper Energy Detect operations */
int (*phy_energy_detect_read)(struct mv88e6xxx_chip *chip, int phy,
struct ethtool_eee *eee);
int (*phy_energy_detect_write)(struct mv88e6xxx_chip *chip, int phy,
struct ethtool_eee *eee);
/* Priority Override Table operations */
int (*pot_clear)(struct mv88e6xxx_chip *chip);
......
......@@ -246,99 +246,3 @@ int mv88e6xxx_phy_setup(struct mv88e6xxx_chip *chip)
{
return mv88e6xxx_phy_ppu_enable(chip);
}
/* Page 0, Register 16: Copper Specific Control Register 1 */
int mv88e6352_phy_energy_detect_read(struct mv88e6xxx_chip *chip, int phy,
struct ethtool_eee *eee)
{
u16 val;
int err;
err = mv88e6xxx_phy_read(chip, phy, MV88E6XXX_PHY_CSCTL1, &val);
if (err)
return err;
val &= MV88E6352_PHY_CSCTL1_ENERGY_DETECT_MASK;
eee->eee_enabled = false;
eee->tx_lpi_enabled = false;
switch (val) {
case MV88E6352_PHY_CSCTL1_ENERGY_DETECT_SENSE_NLP:
eee->tx_lpi_enabled = true;
/* fall through... */
case MV88E6352_PHY_CSCTL1_ENERGY_DETECT_SENSE_RCV:
eee->eee_enabled = true;
}
return 0;
}
int mv88e6352_phy_energy_detect_write(struct mv88e6xxx_chip *chip, int phy,
struct ethtool_eee *eee)
{
u16 val;
int err;
err = mv88e6xxx_phy_read(chip, phy, MV88E6XXX_PHY_CSCTL1, &val);
if (err)
return err;
val &= ~MV88E6352_PHY_CSCTL1_ENERGY_DETECT_MASK;
if (eee->eee_enabled)
val |= MV88E6352_PHY_CSCTL1_ENERGY_DETECT_SENSE_RCV;
if (eee->tx_lpi_enabled)
val |= MV88E6352_PHY_CSCTL1_ENERGY_DETECT_SENSE_NLP;
return mv88e6xxx_phy_write(chip, phy, MV88E6XXX_PHY_CSCTL1, val);
}
int mv88e6390_phy_energy_detect_read(struct mv88e6xxx_chip *chip, int phy,
struct ethtool_eee *eee)
{
u16 val;
int err;
err = mv88e6xxx_phy_read(chip, phy, MV88E6XXX_PHY_CSCTL1, &val);
if (err)
return err;
val &= MV88E6390_PHY_CSCTL1_ENERGY_DETECT_MASK;
eee->eee_enabled = false;
eee->tx_lpi_enabled = false;
switch (val) {
case MV88E6390_PHY_CSCTL1_ENERGY_DETECT_SENSE_NLP_AUTO:
case MV88E6390_PHY_CSCTL1_ENERGY_DETECT_SENSE_NLP_SW:
eee->tx_lpi_enabled = true;
/* fall through... */
case MV88E6390_PHY_CSCTL1_ENERGY_DETECT_SENSE_RCV_AUTO:
case MV88E6390_PHY_CSCTL1_ENERGY_DETECT_SENSE_RCV_SW:
eee->eee_enabled = true;
}
return 0;
}
int mv88e6390_phy_energy_detect_write(struct mv88e6xxx_chip *chip, int phy,
struct ethtool_eee *eee)
{
u16 val;
int err;
err = mv88e6xxx_phy_read(chip, phy, MV88E6XXX_PHY_CSCTL1, &val);
if (err)
return err;
val &= ~MV88E6390_PHY_CSCTL1_ENERGY_DETECT_MASK;
if (eee->eee_enabled)
val |= MV88E6390_PHY_CSCTL1_ENERGY_DETECT_SENSE_RCV_AUTO;
if (eee->tx_lpi_enabled)
val |= MV88E6390_PHY_CSCTL1_ENERGY_DETECT_SENSE_NLP_AUTO;
return mv88e6xxx_phy_write(chip, phy, MV88E6XXX_PHY_CSCTL1, val);
}
......@@ -17,19 +17,6 @@
#define MV88E6XXX_PHY_PAGE 0x16
#define MV88E6XXX_PHY_PAGE_COPPER 0x00
/* Page 0, Register 16: Copper Specific Control Register 1 */
#define MV88E6XXX_PHY_CSCTL1 16
#define MV88E6352_PHY_CSCTL1_ENERGY_DETECT_MASK 0x0300
#define MV88E6352_PHY_CSCTL1_ENERGY_DETECT_OFF_MASK 0x0100 /* 0x */
#define MV88E6352_PHY_CSCTL1_ENERGY_DETECT_SENSE_RCV 0x0200
#define MV88E6352_PHY_CSCTL1_ENERGY_DETECT_SENSE_NLP 0x0300
#define MV88E6390_PHY_CSCTL1_ENERGY_DETECT_MASK 0x0380
#define MV88E6390_PHY_CSCTL1_ENERGY_DETECT_OFF_MASK 0x0180 /* 0xx */
#define MV88E6390_PHY_CSCTL1_ENERGY_DETECT_SENSE_RCV_AUTO 0x0200
#define MV88E6390_PHY_CSCTL1_ENERGY_DETECT_SENSE_RCV_SW 0x0280
#define MV88E6390_PHY_CSCTL1_ENERGY_DETECT_SENSE_NLP_AUTO 0x0300
#define MV88E6390_PHY_CSCTL1_ENERGY_DETECT_SENSE_NLP_SW 0x0380
/* PHY Registers accesses implementations */
int mv88e6165_phy_read(struct mv88e6xxx_chip *chip, struct mii_bus *bus,
int addr, int reg, u16 *val);
......@@ -53,13 +40,4 @@ void mv88e6xxx_phy_init(struct mv88e6xxx_chip *chip);
void mv88e6xxx_phy_destroy(struct mv88e6xxx_chip *chip);
int mv88e6xxx_phy_setup(struct mv88e6xxx_chip *chip);
int mv88e6352_phy_energy_detect_read(struct mv88e6xxx_chip *chip, int phy,
struct ethtool_eee *eee);
int mv88e6352_phy_energy_detect_write(struct mv88e6xxx_chip *chip, int phy,
struct ethtool_eee *eee);
int mv88e6390_phy_energy_detect_read(struct mv88e6xxx_chip *chip, int phy,
struct ethtool_eee *eee);
int mv88e6390_phy_energy_detect_write(struct mv88e6xxx_chip *chip, int phy,
struct ethtool_eee *eee);
#endif /*_MV88E6XXX_PHY_H */
......@@ -35,23 +35,6 @@ int mv88e6xxx_port_write(struct mv88e6xxx_chip *chip, int port, int reg,
return mv88e6xxx_write(chip, addr, reg, val);
}
/* Offset 0x00: Port Status Register */
int mv88e6xxx_port_status_eee(struct mv88e6xxx_chip *chip, int port,
struct ethtool_eee *eee)
{
u16 val;
int err;
err = mv88e6xxx_port_read(chip, port, MV88E6XXX_PORT_STS, &val);
if (err)
return err;
eee->eee_active = !!(val & MV88E6352_PORT_STS_EEE);
return 0;
}
/* Offset 0x01: MAC (or PCS or Physical) Control Register
*
* Link, Duplex and Flow Control have one force bit, one value bit.
......
......@@ -241,9 +241,6 @@ int mv88e6xxx_port_read(struct mv88e6xxx_chip *chip, int port, int reg,
int mv88e6xxx_port_write(struct mv88e6xxx_chip *chip, int port, int reg,
u16 val);
int mv88e6xxx_port_status_eee(struct mv88e6xxx_chip *chip, int port,
struct ethtool_eee *eee);
int mv88e6352_port_set_rgmii_delay(struct mv88e6xxx_chip *chip, int port,
phy_interface_t mode);
int mv88e6390_port_set_rgmii_delay(struct mv88e6xxx_chip *chip, int port,
......
......@@ -637,8 +637,8 @@ qca8k_get_sset_count(struct dsa_switch *ds)
return ARRAY_SIZE(ar8327_mib);
}
static void
qca8k_eee_enable_set(struct dsa_switch *ds, int port, bool enable)
static int
qca8k_set_mac_eee(struct dsa_switch *ds, int port, struct ethtool_eee *eee)
{
struct qca8k_priv *priv = (struct qca8k_priv *)ds->priv;
u32 lpi_en = QCA8K_REG_EEE_CTRL_LPI_EN(port);
......@@ -646,73 +646,21 @@ qca8k_eee_enable_set(struct dsa_switch *ds, int port, bool enable)
mutex_lock(&priv->reg_mutex);
reg = qca8k_read(priv, QCA8K_REG_EEE_CTRL);
if (enable)
if (eee->eee_enabled)
reg |= lpi_en;
else
reg &= ~lpi_en;
qca8k_write(priv, QCA8K_REG_EEE_CTRL, reg);
mutex_unlock(&priv->reg_mutex);
}
static int
qca8k_eee_init(struct dsa_switch *ds, int port,
struct phy_device *phy)
{
struct qca8k_priv *priv = (struct qca8k_priv *)ds->priv;
struct ethtool_eee *p = &priv->port_sts[port].eee;
int ret;
p->supported = (SUPPORTED_1000baseT_Full | SUPPORTED_100baseT_Full);
ret = phy_init_eee(phy, 0);
if (ret)
return ret;
qca8k_eee_enable_set(ds, port, true);
return 0;
}
static int
qca8k_set_eee(struct dsa_switch *ds, int port,
struct phy_device *phydev,
struct ethtool_eee *e)
{
struct qca8k_priv *priv = (struct qca8k_priv *)ds->priv;
struct ethtool_eee *p = &priv->port_sts[port].eee;
int ret = 0;
p->eee_enabled = e->eee_enabled;
if (e->eee_enabled) {
p->eee_enabled = qca8k_eee_init(ds, port, phydev);
if (!p->eee_enabled)
ret = -EOPNOTSUPP;
}
qca8k_eee_enable_set(ds, port, p->eee_enabled);
return ret;
}
static int
qca8k_get_eee(struct dsa_switch *ds, int port,
struct ethtool_eee *e)
qca8k_get_mac_eee(struct dsa_switch *ds, int port, struct ethtool_eee *e)
{
struct qca8k_priv *priv = (struct qca8k_priv *)ds->priv;
struct ethtool_eee *p = &priv->port_sts[port].eee;
struct net_device *netdev = ds->ports[port].netdev;
int ret;
ret = phy_ethtool_get_eee(netdev->phydev, p);
if (!ret)
e->eee_active =
!!(p->supported & p->advertised & p->lp_advertised);
else
e->eee_active = 0;
e->eee_enabled = p->eee_enabled;
return ret;
/* Nothing to do on the port's MAC */
return 0;
}
static void
......@@ -914,8 +862,8 @@ static const struct dsa_switch_ops qca8k_switch_ops = {
.phy_write = qca8k_phy_write,
.get_ethtool_stats = qca8k_get_ethtool_stats,
.get_sset_count = qca8k_get_sset_count,
.get_eee = qca8k_get_eee,
.set_eee = qca8k_set_eee,
.get_mac_eee = qca8k_get_mac_eee,
.set_mac_eee = qca8k_set_mac_eee,
.port_enable = qca8k_port_enable,
.port_disable = qca8k_port_disable,
.port_stp_state_set = qca8k_port_stp_state_set,
......
......@@ -156,7 +156,6 @@ enum qca8k_fdb_cmd {
};
struct ar8xxx_port_status {
struct ethtool_eee eee;
int enabled;
};
......
......@@ -332,13 +332,12 @@ struct dsa_switch_ops {
struct phy_device *phy);
/*
* EEE setttings
* Port's MAC EEE settings
*/
int (*set_eee)(struct dsa_switch *ds, int port,
struct phy_device *phydev,
struct ethtool_eee *e);
int (*get_eee)(struct dsa_switch *ds, int port,
struct ethtool_eee *e);
int (*set_mac_eee)(struct dsa_switch *ds, int port,
struct ethtool_eee *e);
int (*get_mac_eee)(struct dsa_switch *ds, int port,
struct ethtool_eee *e);
/* EEPROM access */
int (*get_eeprom_len)(struct dsa_switch *ds);
......
......@@ -648,17 +648,24 @@ static int dsa_slave_set_eee(struct net_device *dev, struct ethtool_eee *e)
struct dsa_switch *ds = p->dp->ds;
int ret;
if (!ds->ops->set_eee)
/* Port's PHY and MAC both need to be EEE capable */
if (!p->phy)
return -ENODEV;
if (!ds->ops->set_mac_eee)
return -EOPNOTSUPP;
ret = ds->ops->set_eee(ds, p->dp->index, p->phy, e);
ret = ds->ops->set_mac_eee(ds, p->dp->index, e);
if (ret)
return ret;
if (p->phy)
ret = phy_ethtool_set_eee(p->phy, e);
if (e->eee_enabled) {
ret = phy_init_eee(p->phy, 0);
if (ret)
return ret;
}
return ret;
return phy_ethtool_set_eee(p->phy, e);
}
static int dsa_slave_get_eee(struct net_device *dev, struct ethtool_eee *e)
......@@ -667,17 +674,18 @@ static int dsa_slave_get_eee(struct net_device *dev, struct ethtool_eee *e)
struct dsa_switch *ds = p->dp->ds;
int ret;
if (!ds->ops->get_eee)
/* Port's PHY and MAC both need to be EEE capable */
if (!p->phy)
return -ENODEV;
if (!ds->ops->get_mac_eee)
return -EOPNOTSUPP;
ret = ds->ops->get_eee(ds, p->dp->index, e);
ret = ds->ops->get_mac_eee(ds, p->dp->index, e);
if (ret)
return ret;
if (p->phy)
ret = phy_ethtool_get_eee(p->phy, e);
return ret;
return phy_ethtool_get_eee(p->phy, e);
}
#ifdef CONFIG_NET_POLL_CONTROLLER
......
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