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

net: dsa: mv88e6xxx: simplify .serdes_get_lane



Because the mapping between a SERDES interface and its lane is static,
we don't need to stick with negative error codes actually and we can
simply return 0 if there is no lane, just like the IRQ mapping.

This way we can keep a simple and intuitive API using unsigned lane
numbers while simplifying the implementations with single return
statements. Last but not least, fix the reverse chrismas tree in
mv88e6390x_serdes_get_lane.

Signed-off-by: default avatarVivien Didelot <vivien.didelot@gmail.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 4241ef52
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -444,7 +444,7 @@ struct mv88e6xxx_ops {
	int (*serdes_power)(struct mv88e6xxx_chip *chip, int port, bool on);

	/* SERDES lane mapping */
	int (*serdes_get_lane)(struct mv88e6xxx_chip *chip, int port, u8 *lane);
	u8 (*serdes_get_lane)(struct mv88e6xxx_chip *chip, int port);

	/* SERDES interrupt handling */
	unsigned int (*serdes_irq_mapping)(struct mv88e6xxx_chip *chip,
+5 −8
Original line number Diff line number Diff line
@@ -431,11 +431,8 @@ static int mv88e6xxx_port_set_cmode(struct mv88e6xxx_chip *chip, int port,
	if (cmode == chip->ports[port].cmode)
		return 0;

	err = mv88e6xxx_serdes_get_lane(chip, port, &lane);
	if (err && err != -ENODEV)
		return err;

	if (err != -ENODEV) {
	lane = mv88e6xxx_serdes_get_lane(chip, port);
	if (lane) {
		if (chip->ports[port].serdes_irq) {
			err = mv88e6390_serdes_irq_disable(chip, port, lane);
			if (err)
@@ -463,9 +460,9 @@ static int mv88e6xxx_port_set_cmode(struct mv88e6xxx_chip *chip, int port,

		chip->ports[port].cmode = cmode;

		err = mv88e6xxx_serdes_get_lane(chip, port, &lane);
		if (err)
			return err;
		lane = mv88e6xxx_serdes_get_lane(chip, port);
		if (!lane)
			return -ENODEV;

		err = mv88e6390_serdes_power(chip, port, true);
		if (err)
+55 −97
Original line number Diff line number Diff line
@@ -295,149 +295,119 @@ void mv88e6352_serdes_irq_free(struct mv88e6xxx_chip *chip, int port)
	chip->ports[port].serdes_irq = 0;
}

int mv88e6341_serdes_get_lane(struct mv88e6xxx_chip *chip, int port, u8 *lane)
u8 mv88e6341_serdes_get_lane(struct mv88e6xxx_chip *chip, int port)
{
	u8 cmode = chip->ports[port].cmode;
	u8 lane = 0;

	if (port != 5)
		return -ENODEV;

	switch (port) {
	case 5:
		if (cmode == MV88E6XXX_PORT_STS_CMODE_1000BASEX ||
		    cmode == MV88E6XXX_PORT_STS_CMODE_SGMII ||
	    cmode == MV88E6XXX_PORT_STS_CMODE_2500BASEX) {
		*lane = MV88E6341_PORT5_LANE;
		return 0;
		    cmode == MV88E6XXX_PORT_STS_CMODE_2500BASEX)
			lane = MV88E6341_PORT5_LANE;
		break;
	}

	return -ENODEV;
	return lane;
}

int mv88e6390_serdes_get_lane(struct mv88e6xxx_chip *chip, int port, u8 *lane)
u8 mv88e6390_serdes_get_lane(struct mv88e6xxx_chip *chip, int port)
{
	u8 cmode = chip->ports[port].cmode;
	u8 lane = 0;

	switch (port) {
	case 9:
		if (cmode == MV88E6XXX_PORT_STS_CMODE_1000BASEX ||
		    cmode == MV88E6XXX_PORT_STS_CMODE_SGMII ||
		    cmode == MV88E6XXX_PORT_STS_CMODE_2500BASEX) {
			*lane = MV88E6390_PORT9_LANE0;
			return 0;
		}
		    cmode == MV88E6XXX_PORT_STS_CMODE_2500BASEX)
			lane = MV88E6390_PORT9_LANE0;
		break;
	case 10:
		if (cmode == MV88E6XXX_PORT_STS_CMODE_1000BASEX ||
		    cmode == MV88E6XXX_PORT_STS_CMODE_SGMII ||
		    cmode == MV88E6XXX_PORT_STS_CMODE_2500BASEX) {
			*lane = MV88E6390_PORT10_LANE0;
			return 0;
		}
		break;
	default:
		    cmode == MV88E6XXX_PORT_STS_CMODE_2500BASEX)
			lane = MV88E6390_PORT10_LANE0;
		break;
	}

	return -ENODEV;
	return lane;
}

int mv88e6390x_serdes_get_lane(struct mv88e6xxx_chip *chip, int port, u8 *lane)
u8 mv88e6390x_serdes_get_lane(struct mv88e6xxx_chip *chip, int port)
{
	u8 cmode_port9, cmode_port10, cmode_port;

	cmode_port9 = chip->ports[9].cmode;
	cmode_port10 = chip->ports[10].cmode;
	cmode_port = chip->ports[port].cmode;
	u8 cmode_port = chip->ports[port].cmode;
	u8 cmode_port10 = chip->ports[10].cmode;
	u8 cmode_port9 = chip->ports[9].cmode;
	u8 lane = 0;

	switch (port) {
	case 2:
		if (cmode_port9 == MV88E6XXX_PORT_STS_CMODE_1000BASEX ||
		    cmode_port9 == MV88E6XXX_PORT_STS_CMODE_SGMII ||
		    cmode_port9 == MV88E6XXX_PORT_STS_CMODE_2500BASEX) {
			if (cmode_port == MV88E6XXX_PORT_STS_CMODE_1000BASEX) {
				*lane = MV88E6390_PORT9_LANE1;
				return 0;
			}
		}
		    cmode_port9 == MV88E6XXX_PORT_STS_CMODE_2500BASEX)
			if (cmode_port == MV88E6XXX_PORT_STS_CMODE_1000BASEX)
				lane = MV88E6390_PORT9_LANE1;
		break;
	case 3:
		if (cmode_port9 == MV88E6XXX_PORT_STS_CMODE_1000BASEX ||
		    cmode_port9 == MV88E6XXX_PORT_STS_CMODE_SGMII ||
		    cmode_port9 == MV88E6XXX_PORT_STS_CMODE_2500BASEX ||
		    cmode_port9 == MV88E6XXX_PORT_STS_CMODE_RXAUI) {
			if (cmode_port == MV88E6XXX_PORT_STS_CMODE_1000BASEX) {
				*lane = MV88E6390_PORT9_LANE2;
				return 0;
			}
		}
		    cmode_port9 == MV88E6XXX_PORT_STS_CMODE_RXAUI)
			if (cmode_port == MV88E6XXX_PORT_STS_CMODE_1000BASEX)
				lane = MV88E6390_PORT9_LANE2;
		break;
	case 4:
		if (cmode_port9 == MV88E6XXX_PORT_STS_CMODE_1000BASEX ||
		    cmode_port9 == MV88E6XXX_PORT_STS_CMODE_SGMII ||
		    cmode_port9 == MV88E6XXX_PORT_STS_CMODE_2500BASEX ||
		    cmode_port9 == MV88E6XXX_PORT_STS_CMODE_RXAUI) {
			if (cmode_port == MV88E6XXX_PORT_STS_CMODE_1000BASEX) {
				*lane = MV88E6390_PORT9_LANE3;
				return 0;
			}
		}
		    cmode_port9 == MV88E6XXX_PORT_STS_CMODE_RXAUI)
			if (cmode_port == MV88E6XXX_PORT_STS_CMODE_1000BASEX)
				lane = MV88E6390_PORT9_LANE3;
		break;
	case 5:
		if (cmode_port10 == MV88E6XXX_PORT_STS_CMODE_1000BASEX ||
		    cmode_port10 == MV88E6XXX_PORT_STS_CMODE_SGMII ||
		    cmode_port10 == MV88E6XXX_PORT_STS_CMODE_2500BASEX) {
			if (cmode_port == MV88E6XXX_PORT_STS_CMODE_1000BASEX) {
				*lane = MV88E6390_PORT10_LANE1;
				return 0;
			}
		}
		    cmode_port10 == MV88E6XXX_PORT_STS_CMODE_2500BASEX)
			if (cmode_port == MV88E6XXX_PORT_STS_CMODE_1000BASEX)
				lane = MV88E6390_PORT10_LANE1;
		break;
	case 6:
		if (cmode_port10 == MV88E6XXX_PORT_STS_CMODE_1000BASEX ||
		    cmode_port10 == MV88E6XXX_PORT_STS_CMODE_SGMII ||
		    cmode_port10 == MV88E6XXX_PORT_STS_CMODE_2500BASEX ||
		    cmode_port10 == MV88E6XXX_PORT_STS_CMODE_RXAUI) {
			if (cmode_port == MV88E6XXX_PORT_STS_CMODE_1000BASEX) {
				*lane = MV88E6390_PORT10_LANE2;
				return 0;
			}
		}
		    cmode_port10 == MV88E6XXX_PORT_STS_CMODE_RXAUI)
			if (cmode_port == MV88E6XXX_PORT_STS_CMODE_1000BASEX)
				lane = MV88E6390_PORT10_LANE2;
		break;
	case 7:
		if (cmode_port10 == MV88E6XXX_PORT_STS_CMODE_1000BASEX ||
		    cmode_port10 == MV88E6XXX_PORT_STS_CMODE_SGMII ||
		    cmode_port10 == MV88E6XXX_PORT_STS_CMODE_2500BASEX ||
		    cmode_port10 == MV88E6XXX_PORT_STS_CMODE_RXAUI) {
			if (cmode_port == MV88E6XXX_PORT_STS_CMODE_1000BASEX) {
				*lane = MV88E6390_PORT10_LANE3;
				return 0;
			}
		}
		    cmode_port10 == MV88E6XXX_PORT_STS_CMODE_RXAUI)
			if (cmode_port == MV88E6XXX_PORT_STS_CMODE_1000BASEX)
				lane = MV88E6390_PORT10_LANE3;
		break;
	case 9:
		if (cmode_port9 == MV88E6XXX_PORT_STS_CMODE_1000BASEX ||
		    cmode_port9 == MV88E6XXX_PORT_STS_CMODE_SGMII ||
		    cmode_port9 == MV88E6XXX_PORT_STS_CMODE_2500BASEX ||
		    cmode_port9 == MV88E6XXX_PORT_STS_CMODE_XAUI ||
		    cmode_port9 == MV88E6XXX_PORT_STS_CMODE_RXAUI) {
			*lane = MV88E6390_PORT9_LANE0;
			return 0;
		}
		    cmode_port9 == MV88E6XXX_PORT_STS_CMODE_RXAUI)
			lane = MV88E6390_PORT9_LANE0;
		break;
	case 10:
		if (cmode_port10 == MV88E6XXX_PORT_STS_CMODE_1000BASEX ||
		    cmode_port10 == MV88E6XXX_PORT_STS_CMODE_SGMII ||
		    cmode_port10 == MV88E6XXX_PORT_STS_CMODE_2500BASEX ||
		    cmode_port10 == MV88E6XXX_PORT_STS_CMODE_XAUI ||
		    cmode_port10 == MV88E6XXX_PORT_STS_CMODE_RXAUI) {
			*lane = MV88E6390_PORT10_LANE0;
			return 0;
		}
		break;
	default:
		    cmode_port10 == MV88E6XXX_PORT_STS_CMODE_RXAUI)
			lane = MV88E6390_PORT10_LANE0;
		break;
	}

	return -ENODEV;
	return lane;
}

/* Set the power on/off for 10GBASE-R and 10GBASE-X4/X2 */
@@ -497,14 +467,10 @@ int mv88e6390_serdes_power(struct mv88e6xxx_chip *chip, int port, bool on)
{
	u8 cmode = chip->ports[port].cmode;
	u8 lane;
	int err;

	err = mv88e6xxx_serdes_get_lane(chip, port, &lane);
	if (err) {
		if (err == -ENODEV)
			err = 0;
		return err;
	}
	lane = mv88e6xxx_serdes_get_lane(chip, port);
	if (!lane)
		return 0;

	switch (cmode) {
	case MV88E6XXX_PORT_STS_CMODE_SGMII:
@@ -657,8 +623,8 @@ static irqreturn_t mv88e6390_serdes_thread_fn(int irq, void *dev_id)

	mv88e6xxx_reg_lock(chip);

	err = mv88e6xxx_serdes_get_lane(chip, port->port, &lane);
	if (err)
	lane = mv88e6xxx_serdes_get_lane(chip, port->port);
	if (!lane)
		goto out;

	switch (cmode) {
@@ -691,12 +657,9 @@ int mv88e6390_serdes_irq_setup(struct mv88e6xxx_chip *chip, int port)
	int err;
	u8 lane;

	err = mv88e6xxx_serdes_get_lane(chip, port, &lane);
	if (err) {
		if (err == -ENODEV)
			err = 0;
		return err;
	}
	lane = mv88e6xxx_serdes_get_lane(chip, port);
	if (!lane)
		return 0;

	irq = mv88e6xxx_serdes_irq_mapping(chip, port);
	if (!irq)
@@ -725,16 +688,11 @@ int mv88e6390_serdes_irq_setup(struct mv88e6xxx_chip *chip, int port)

void mv88e6390_serdes_irq_free(struct mv88e6xxx_chip *chip, int port)
{
	int err;
	u8 lane;

	err = mv88e6xxx_serdes_get_lane(chip, port, &lane);
	if (err) {
		if (err != -ENODEV)
			dev_err(chip->dev, "Unable to free SERDES irq: %d\n",
				err);
	lane = mv88e6xxx_serdes_get_lane(chip, port);
	if (!lane)
		return;
	}

	mv88e6390_serdes_irq_disable(chip, port, lane);

+13 −16
Original line number Diff line number Diff line
@@ -74,22 +74,9 @@
#define MV88E6390_SGMII_PHY_STATUS_SPD_DPL_VALID BIT(11)
#define MV88E6390_SGMII_PHY_STATUS_LINK		BIT(10)

/* Put the SERDES lane address a port is using into *lane. If a port has
 * multiple lanes, should put the first lane the port is using. If a port does
 * not have a lane, return -ENODEV.
 */
static inline int mv88e6xxx_serdes_get_lane(struct mv88e6xxx_chip *chip,
					    int port, u8 *lane)
{
	if (!chip->info->ops->serdes_get_lane)
		return -EOPNOTSUPP;

	return chip->info->ops->serdes_get_lane(chip, port, lane);
}

int mv88e6341_serdes_get_lane(struct mv88e6xxx_chip *chip, int port, u8 *lane);
int mv88e6390_serdes_get_lane(struct mv88e6xxx_chip *chip, int port, u8 *lane);
int mv88e6390x_serdes_get_lane(struct mv88e6xxx_chip *chip, int port, u8 *lane);
u8 mv88e6341_serdes_get_lane(struct mv88e6xxx_chip *chip, int port);
u8 mv88e6390_serdes_get_lane(struct mv88e6xxx_chip *chip, int port);
u8 mv88e6390x_serdes_get_lane(struct mv88e6xxx_chip *chip, int port);
unsigned int mv88e6352_serdes_irq_mapping(struct mv88e6xxx_chip *chip,
					  int port);
unsigned int mv88e6390_serdes_irq_mapping(struct mv88e6xxx_chip *chip,
@@ -110,6 +97,16 @@ int mv88e6390_serdes_irq_disable(struct mv88e6xxx_chip *chip, int port,
int mv88e6352_serdes_irq_setup(struct mv88e6xxx_chip *chip, int port);
void mv88e6352_serdes_irq_free(struct mv88e6xxx_chip *chip, int port);

/* Return the (first) SERDES lane address a port is using, 0 otherwise. */
static inline u8 mv88e6xxx_serdes_get_lane(struct mv88e6xxx_chip *chip,
					   int port)
{
	if (!chip->info->ops->serdes_get_lane)
		return 0;

	return chip->info->ops->serdes_get_lane(chip, port);
}

static inline unsigned int
mv88e6xxx_serdes_irq_mapping(struct mv88e6xxx_chip *chip, int port)
{