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

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
......@@ -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,
......
......@@ -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)
......
......@@ -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;
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;
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;
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);
......
......@@ -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)
{
......
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