Commit dc272f60 authored by Vivien Didelot's avatar Vivien Didelot Committed by David S. Miller

net: dsa: mv88e6xxx: pass lane to .serdes_power

Now the first step of all .serdes_power implementations is getting
the lane mapping. Since we have an operation for that, call it in
the wrapper and pass the lane down to the .serdes_power operation.

This also allows to avoid querying the SERDES lane twice in
mv88e6xxx_port_set_cmode.

At the same time provide mv88e6xxx_serdes_power_{up,down} helpers
and prefer up/down instead of on/off as in the documentation.
Signed-off-by: default avatarVivien Didelot <vivien.didelot@gmail.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 6600d8e5
...@@ -2057,13 +2057,15 @@ static int mv88e6xxx_setup_egress_floods(struct mv88e6xxx_chip *chip, int port) ...@@ -2057,13 +2057,15 @@ static int mv88e6xxx_setup_egress_floods(struct mv88e6xxx_chip *chip, int port)
static int mv88e6xxx_serdes_power(struct mv88e6xxx_chip *chip, int port, static int mv88e6xxx_serdes_power(struct mv88e6xxx_chip *chip, int port,
bool on) bool on)
{ {
u8 lane;
int err; int err;
if (!chip->info->ops->serdes_power) lane = mv88e6xxx_serdes_get_lane(chip, port);
if (!lane)
return 0; return 0;
if (on) { if (on) {
err = chip->info->ops->serdes_power(chip, port, true); err = mv88e6xxx_serdes_power_up(chip, port, lane);
if (err) if (err)
return err; return err;
...@@ -2074,7 +2076,7 @@ static int mv88e6xxx_serdes_power(struct mv88e6xxx_chip *chip, int port, ...@@ -2074,7 +2076,7 @@ static int mv88e6xxx_serdes_power(struct mv88e6xxx_chip *chip, int port,
chip->ports[port].serdes_irq) chip->ports[port].serdes_irq)
chip->info->ops->serdes_irq_free(chip, port); chip->info->ops->serdes_irq_free(chip, port);
err = chip->info->ops->serdes_power(chip, port, false); err = mv88e6xxx_serdes_power_down(chip, port, lane);
} }
return err; return err;
......
...@@ -441,7 +441,8 @@ struct mv88e6xxx_ops { ...@@ -441,7 +441,8 @@ struct mv88e6xxx_ops {
int (*mgmt_rsvd2cpu)(struct mv88e6xxx_chip *chip); int (*mgmt_rsvd2cpu)(struct mv88e6xxx_chip *chip);
/* Power on/off a SERDES interface */ /* Power on/off a SERDES interface */
int (*serdes_power)(struct mv88e6xxx_chip *chip, int port, bool on); int (*serdes_power)(struct mv88e6xxx_chip *chip, int port, u8 lane,
bool up);
/* SERDES lane mapping */ /* SERDES lane mapping */
u8 (*serdes_get_lane)(struct mv88e6xxx_chip *chip, int port); u8 (*serdes_get_lane)(struct mv88e6xxx_chip *chip, int port);
......
...@@ -439,7 +439,7 @@ static int mv88e6xxx_port_set_cmode(struct mv88e6xxx_chip *chip, int port, ...@@ -439,7 +439,7 @@ static int mv88e6xxx_port_set_cmode(struct mv88e6xxx_chip *chip, int port,
return err; return err;
} }
err = mv88e6390_serdes_power(chip, port, false); err = mv88e6xxx_serdes_power_down(chip, port, lane);
if (err) if (err)
return err; return err;
} }
...@@ -464,7 +464,7 @@ static int mv88e6xxx_port_set_cmode(struct mv88e6xxx_chip *chip, int port, ...@@ -464,7 +464,7 @@ static int mv88e6xxx_port_set_cmode(struct mv88e6xxx_chip *chip, int port,
if (!lane) if (!lane)
return -ENODEV; return -ENODEV;
err = mv88e6390_serdes_power(chip, port, true); err = mv88e6xxx_serdes_power_up(chip, port, lane);
if (err) if (err)
return err; return err;
......
...@@ -49,19 +49,17 @@ static int mv88e6390_serdes_write(struct mv88e6xxx_chip *chip, ...@@ -49,19 +49,17 @@ static int mv88e6390_serdes_write(struct mv88e6xxx_chip *chip,
return mv88e6xxx_phy_write(chip, lane, reg_c45, val); return mv88e6xxx_phy_write(chip, lane, reg_c45, val);
} }
int mv88e6352_serdes_power(struct mv88e6xxx_chip *chip, int port, bool on) int mv88e6352_serdes_power(struct mv88e6xxx_chip *chip, int port, u8 lane,
bool up)
{ {
u16 val, new_val; u16 val, new_val;
int err; int err;
if (!mv88e6xxx_serdes_get_lane(chip, port))
return 0;
err = mv88e6352_serdes_read(chip, MII_BMCR, &val); err = mv88e6352_serdes_read(chip, MII_BMCR, &val);
if (err) if (err)
return err; return err;
if (on) if (up)
new_val = val & ~BMCR_PDOWN; new_val = val & ~BMCR_PDOWN;
else else
new_val = val | BMCR_PDOWN; new_val = val | BMCR_PDOWN;
...@@ -409,9 +407,9 @@ u8 mv88e6390x_serdes_get_lane(struct mv88e6xxx_chip *chip, int port) ...@@ -409,9 +407,9 @@ u8 mv88e6390x_serdes_get_lane(struct mv88e6xxx_chip *chip, int port)
return lane; return lane;
} }
/* Set the power on/off for 10GBASE-R and 10GBASE-X4/X2 */ /* Set power up/down for 10GBASE-R and 10GBASE-X4/X2 */
static int mv88e6390_serdes_power_10g(struct mv88e6xxx_chip *chip, u8 lane, static int mv88e6390_serdes_power_10g(struct mv88e6xxx_chip *chip, u8 lane,
bool on) bool up)
{ {
u16 val, new_val; u16 val, new_val;
int err; int err;
...@@ -422,7 +420,7 @@ static int mv88e6390_serdes_power_10g(struct mv88e6xxx_chip *chip, u8 lane, ...@@ -422,7 +420,7 @@ static int mv88e6390_serdes_power_10g(struct mv88e6xxx_chip *chip, u8 lane,
if (err) if (err)
return err; return err;
if (on) if (up)
new_val = val & ~(MV88E6390_PCS_CONTROL_1_RESET | new_val = val & ~(MV88E6390_PCS_CONTROL_1_RESET |
MV88E6390_PCS_CONTROL_1_LOOPBACK | MV88E6390_PCS_CONTROL_1_LOOPBACK |
MV88E6390_PCS_CONTROL_1_PDOWN); MV88E6390_PCS_CONTROL_1_PDOWN);
...@@ -436,9 +434,9 @@ static int mv88e6390_serdes_power_10g(struct mv88e6xxx_chip *chip, u8 lane, ...@@ -436,9 +434,9 @@ static int mv88e6390_serdes_power_10g(struct mv88e6xxx_chip *chip, u8 lane,
return err; return err;
} }
/* Set the power on/off for SGMII and 1000Base-X */ /* Set power up/down for SGMII and 1000Base-X */
static int mv88e6390_serdes_power_sgmii(struct mv88e6xxx_chip *chip, u8 lane, static int mv88e6390_serdes_power_sgmii(struct mv88e6xxx_chip *chip, u8 lane,
bool on) bool up)
{ {
u16 val, new_val; u16 val, new_val;
int err; int err;
...@@ -448,7 +446,7 @@ static int mv88e6390_serdes_power_sgmii(struct mv88e6xxx_chip *chip, u8 lane, ...@@ -448,7 +446,7 @@ static int mv88e6390_serdes_power_sgmii(struct mv88e6xxx_chip *chip, u8 lane,
if (err) if (err)
return err; return err;
if (on) if (up)
new_val = val & ~(MV88E6390_SGMII_CONTROL_RESET | new_val = val & ~(MV88E6390_SGMII_CONTROL_RESET |
MV88E6390_SGMII_CONTROL_LOOPBACK | MV88E6390_SGMII_CONTROL_LOOPBACK |
MV88E6390_SGMII_CONTROL_PDOWN); MV88E6390_SGMII_CONTROL_PDOWN);
...@@ -462,23 +460,19 @@ static int mv88e6390_serdes_power_sgmii(struct mv88e6xxx_chip *chip, u8 lane, ...@@ -462,23 +460,19 @@ static int mv88e6390_serdes_power_sgmii(struct mv88e6xxx_chip *chip, u8 lane,
return err; return err;
} }
int mv88e6390_serdes_power(struct mv88e6xxx_chip *chip, int port, bool on) int mv88e6390_serdes_power(struct mv88e6xxx_chip *chip, int port, u8 lane,
bool up)
{ {
u8 cmode = chip->ports[port].cmode; u8 cmode = chip->ports[port].cmode;
u8 lane;
lane = mv88e6xxx_serdes_get_lane(chip, port);
if (!lane)
return 0;
switch (cmode) { switch (cmode) {
case MV88E6XXX_PORT_STS_CMODE_SGMII: case MV88E6XXX_PORT_STS_CMODE_SGMII:
case MV88E6XXX_PORT_STS_CMODE_1000BASEX: case MV88E6XXX_PORT_STS_CMODE_1000BASEX:
case MV88E6XXX_PORT_STS_CMODE_2500BASEX: case MV88E6XXX_PORT_STS_CMODE_2500BASEX:
return mv88e6390_serdes_power_sgmii(chip, lane, on); return mv88e6390_serdes_power_sgmii(chip, lane, up);
case MV88E6XXX_PORT_STS_CMODE_XAUI: case MV88E6XXX_PORT_STS_CMODE_XAUI:
case MV88E6XXX_PORT_STS_CMODE_RXAUI: case MV88E6XXX_PORT_STS_CMODE_RXAUI:
return mv88e6390_serdes_power_10g(chip, lane, on); return mv88e6390_serdes_power_10g(chip, lane, up);
} }
return 0; return 0;
......
...@@ -82,8 +82,10 @@ unsigned int mv88e6352_serdes_irq_mapping(struct mv88e6xxx_chip *chip, ...@@ -82,8 +82,10 @@ unsigned int mv88e6352_serdes_irq_mapping(struct mv88e6xxx_chip *chip,
int port); int port);
unsigned int mv88e6390_serdes_irq_mapping(struct mv88e6xxx_chip *chip, unsigned int mv88e6390_serdes_irq_mapping(struct mv88e6xxx_chip *chip,
int port); int port);
int mv88e6352_serdes_power(struct mv88e6xxx_chip *chip, int port, bool on); int mv88e6352_serdes_power(struct mv88e6xxx_chip *chip, int port, u8 lane,
int mv88e6390_serdes_power(struct mv88e6xxx_chip *chip, int port, bool on); bool on);
int mv88e6390_serdes_power(struct mv88e6xxx_chip *chip, int port, u8 lane,
bool on);
int mv88e6390_serdes_irq_setup(struct mv88e6xxx_chip *chip, int port); int mv88e6390_serdes_irq_setup(struct mv88e6xxx_chip *chip, int port);
void mv88e6390_serdes_irq_free(struct mv88e6xxx_chip *chip, int port); void mv88e6390_serdes_irq_free(struct mv88e6xxx_chip *chip, int port);
int mv88e6352_serdes_get_sset_count(struct mv88e6xxx_chip *chip, int port); int mv88e6352_serdes_get_sset_count(struct mv88e6xxx_chip *chip, int port);
...@@ -108,6 +110,24 @@ static inline u8 mv88e6xxx_serdes_get_lane(struct mv88e6xxx_chip *chip, ...@@ -108,6 +110,24 @@ static inline u8 mv88e6xxx_serdes_get_lane(struct mv88e6xxx_chip *chip,
return chip->info->ops->serdes_get_lane(chip, port); return chip->info->ops->serdes_get_lane(chip, port);
} }
static inline int mv88e6xxx_serdes_power_up(struct mv88e6xxx_chip *chip,
int port, u8 lane)
{
if (!chip->info->ops->serdes_power)
return -EOPNOTSUPP;
return chip->info->ops->serdes_power(chip, port, lane, true);
}
static inline int mv88e6xxx_serdes_power_down(struct mv88e6xxx_chip *chip,
int port, u8 lane)
{
if (!chip->info->ops->serdes_power)
return -EOPNOTSUPP;
return chip->info->ops->serdes_power(chip, port, lane, false);
}
static inline unsigned int static inline unsigned int
mv88e6xxx_serdes_irq_mapping(struct mv88e6xxx_chip *chip, int port) mv88e6xxx_serdes_irq_mapping(struct mv88e6xxx_chip *chip, int port)
{ {
......
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