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

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
Loading
Loading
Loading
Loading
+5 −3
Original line number Diff line number Diff line
@@ -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;
+2 −1
Original line number Diff line number Diff line
@@ -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);
+2 −2
Original line number Diff line number Diff line
@@ -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;

+13 −19
Original line number Diff line number Diff line
@@ -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;
+22 −2
Original line number Diff line number Diff line
@@ -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)
{