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: Vivien Didelot <vivien.didelot@gmail.com> Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
Родитель
6600d8e582
Коммит
dc272f600e
|
@ -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,
|
||||
bool on)
|
||||
{
|
||||
u8 lane;
|
||||
int err;
|
||||
|
||||
if (!chip->info->ops->serdes_power)
|
||||
lane = mv88e6xxx_serdes_get_lane(chip, port);
|
||||
if (!lane)
|
||||
return 0;
|
||||
|
||||
if (on) {
|
||||
err = chip->info->ops->serdes_power(chip, port, true);
|
||||
err = mv88e6xxx_serdes_power_up(chip, port, lane);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
|
@ -2074,7 +2076,7 @@ static int mv88e6xxx_serdes_power(struct mv88e6xxx_chip *chip, int port,
|
|||
chip->ports[port].serdes_irq)
|
||||
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;
|
||||
|
|
|
@ -441,7 +441,8 @@ struct mv88e6xxx_ops {
|
|||
int (*mgmt_rsvd2cpu)(struct mv88e6xxx_chip *chip);
|
||||
|
||||
/* 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 */
|
||||
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,
|
|||
return err;
|
||||
}
|
||||
|
||||
err = mv88e6390_serdes_power(chip, port, false);
|
||||
err = mv88e6xxx_serdes_power_down(chip, port, lane);
|
||||
if (err)
|
||||
return err;
|
||||
}
|
||||
|
@ -464,7 +464,7 @@ static int mv88e6xxx_port_set_cmode(struct mv88e6xxx_chip *chip, int port,
|
|||
if (!lane)
|
||||
return -ENODEV;
|
||||
|
||||
err = mv88e6390_serdes_power(chip, port, true);
|
||||
err = mv88e6xxx_serdes_power_up(chip, port, lane);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
|
|
|
@ -49,19 +49,17 @@ static int mv88e6390_serdes_write(struct mv88e6xxx_chip *chip,
|
|||
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;
|
||||
int err;
|
||||
|
||||
if (!mv88e6xxx_serdes_get_lane(chip, port))
|
||||
return 0;
|
||||
|
||||
err = mv88e6352_serdes_read(chip, MII_BMCR, &val);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
if (on)
|
||||
if (up)
|
||||
new_val = val & ~BMCR_PDOWN;
|
||||
else
|
||||
new_val = val | BMCR_PDOWN;
|
||||
|
@ -409,9 +407,9 @@ u8 mv88e6390x_serdes_get_lane(struct mv88e6xxx_chip *chip, int port)
|
|||
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,
|
||||
bool on)
|
||||
bool up)
|
||||
{
|
||||
u16 val, new_val;
|
||||
int err;
|
||||
|
@ -422,7 +420,7 @@ static int mv88e6390_serdes_power_10g(struct mv88e6xxx_chip *chip, u8 lane,
|
|||
if (err)
|
||||
return err;
|
||||
|
||||
if (on)
|
||||
if (up)
|
||||
new_val = val & ~(MV88E6390_PCS_CONTROL_1_RESET |
|
||||
MV88E6390_PCS_CONTROL_1_LOOPBACK |
|
||||
MV88E6390_PCS_CONTROL_1_PDOWN);
|
||||
|
@ -436,9 +434,9 @@ static int mv88e6390_serdes_power_10g(struct mv88e6xxx_chip *chip, u8 lane,
|
|||
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,
|
||||
bool on)
|
||||
bool up)
|
||||
{
|
||||
u16 val, new_val;
|
||||
int err;
|
||||
|
@ -448,7 +446,7 @@ static int mv88e6390_serdes_power_sgmii(struct mv88e6xxx_chip *chip, u8 lane,
|
|||
if (err)
|
||||
return err;
|
||||
|
||||
if (on)
|
||||
if (up)
|
||||
new_val = val & ~(MV88E6390_SGMII_CONTROL_RESET |
|
||||
MV88E6390_SGMII_CONTROL_LOOPBACK |
|
||||
MV88E6390_SGMII_CONTROL_PDOWN);
|
||||
|
@ -462,23 +460,19 @@ static int mv88e6390_serdes_power_sgmii(struct mv88e6xxx_chip *chip, u8 lane,
|
|||
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 lane;
|
||||
|
||||
lane = mv88e6xxx_serdes_get_lane(chip, port);
|
||||
if (!lane)
|
||||
return 0;
|
||||
|
||||
switch (cmode) {
|
||||
case MV88E6XXX_PORT_STS_CMODE_SGMII:
|
||||
case MV88E6XXX_PORT_STS_CMODE_1000BASEX:
|
||||
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_RXAUI:
|
||||
return mv88e6390_serdes_power_10g(chip, lane, on);
|
||||
return mv88e6390_serdes_power_10g(chip, lane, up);
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
|
|
@ -82,8 +82,10 @@ unsigned int mv88e6352_serdes_irq_mapping(struct mv88e6xxx_chip *chip,
|
|||
int port);
|
||||
unsigned int mv88e6390_serdes_irq_mapping(struct mv88e6xxx_chip *chip,
|
||||
int port);
|
||||
int mv88e6352_serdes_power(struct mv88e6xxx_chip *chip, int port, bool on);
|
||||
int mv88e6390_serdes_power(struct mv88e6xxx_chip *chip, int port, bool on);
|
||||
int mv88e6352_serdes_power(struct mv88e6xxx_chip *chip, int port, u8 lane,
|
||||
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);
|
||||
void mv88e6390_serdes_irq_free(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,
|
|||
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
|
||||
mv88e6xxx_serdes_irq_mapping(struct mv88e6xxx_chip *chip, int port)
|
||||
{
|
||||
|
|
Загрузка…
Ссылка в новой задаче