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: Vivien Didelot <vivien.didelot@gmail.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
Vivien Didelot 2019-08-31 16:18:30 -04:00 committed by David S. Miller
parent 4241ef5237
commit 5122d4ec9e
4 changed files with 74 additions and 122 deletions

View File

@ -444,7 +444,7 @@ struct mv88e6xxx_ops {
int (*serdes_power)(struct mv88e6xxx_chip *chip, int port, bool on); int (*serdes_power)(struct mv88e6xxx_chip *chip, int port, bool on);
/* SERDES lane mapping */ /* 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 */ /* SERDES interrupt handling */
unsigned int (*serdes_irq_mapping)(struct mv88e6xxx_chip *chip, unsigned int (*serdes_irq_mapping)(struct mv88e6xxx_chip *chip,

View File

@ -431,11 +431,8 @@ static int mv88e6xxx_port_set_cmode(struct mv88e6xxx_chip *chip, int port,
if (cmode == chip->ports[port].cmode) if (cmode == chip->ports[port].cmode)
return 0; return 0;
err = mv88e6xxx_serdes_get_lane(chip, port, &lane); lane = mv88e6xxx_serdes_get_lane(chip, port);
if (err && err != -ENODEV) if (lane) {
return err;
if (err != -ENODEV) {
if (chip->ports[port].serdes_irq) { if (chip->ports[port].serdes_irq) {
err = mv88e6390_serdes_irq_disable(chip, port, lane); err = mv88e6390_serdes_irq_disable(chip, port, lane);
if (err) if (err)
@ -463,9 +460,9 @@ static int mv88e6xxx_port_set_cmode(struct mv88e6xxx_chip *chip, int port,
chip->ports[port].cmode = cmode; chip->ports[port].cmode = cmode;
err = mv88e6xxx_serdes_get_lane(chip, port, &lane); lane = mv88e6xxx_serdes_get_lane(chip, port);
if (err) if (!lane)
return err; return -ENODEV;
err = mv88e6390_serdes_power(chip, port, true); err = mv88e6390_serdes_power(chip, port, true);
if (err) if (err)

View File

@ -295,149 +295,119 @@ void mv88e6352_serdes_irq_free(struct mv88e6xxx_chip *chip, int port)
chip->ports[port].serdes_irq = 0; 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 cmode = chip->ports[port].cmode;
u8 lane = 0;
if (port != 5) switch (port) {
return -ENODEV; case 5:
if (cmode == MV88E6XXX_PORT_STS_CMODE_1000BASEX ||
if (cmode == MV88E6XXX_PORT_STS_CMODE_1000BASEX || cmode == MV88E6XXX_PORT_STS_CMODE_SGMII ||
cmode == MV88E6XXX_PORT_STS_CMODE_SGMII || cmode == MV88E6XXX_PORT_STS_CMODE_2500BASEX)
cmode == MV88E6XXX_PORT_STS_CMODE_2500BASEX) { lane = MV88E6341_PORT5_LANE;
*lane = MV88E6341_PORT5_LANE; break;
return 0;
} }
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 cmode = chip->ports[port].cmode;
u8 lane = 0;
switch (port) { switch (port) {
case 9: case 9:
if (cmode == MV88E6XXX_PORT_STS_CMODE_1000BASEX || if (cmode == MV88E6XXX_PORT_STS_CMODE_1000BASEX ||
cmode == MV88E6XXX_PORT_STS_CMODE_SGMII || cmode == MV88E6XXX_PORT_STS_CMODE_SGMII ||
cmode == MV88E6XXX_PORT_STS_CMODE_2500BASEX) { cmode == MV88E6XXX_PORT_STS_CMODE_2500BASEX)
*lane = MV88E6390_PORT9_LANE0; lane = MV88E6390_PORT9_LANE0;
return 0;
}
break; break;
case 10: case 10:
if (cmode == MV88E6XXX_PORT_STS_CMODE_1000BASEX || if (cmode == MV88E6XXX_PORT_STS_CMODE_1000BASEX ||
cmode == MV88E6XXX_PORT_STS_CMODE_SGMII || cmode == MV88E6XXX_PORT_STS_CMODE_SGMII ||
cmode == MV88E6XXX_PORT_STS_CMODE_2500BASEX) { cmode == MV88E6XXX_PORT_STS_CMODE_2500BASEX)
*lane = MV88E6390_PORT10_LANE0; lane = MV88E6390_PORT10_LANE0;
return 0;
}
break;
default:
break; 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; u8 cmode_port = chip->ports[port].cmode;
u8 cmode_port10 = chip->ports[10].cmode;
cmode_port9 = chip->ports[9].cmode; u8 cmode_port9 = chip->ports[9].cmode;
cmode_port10 = chip->ports[10].cmode; u8 lane = 0;
cmode_port = chip->ports[port].cmode;
switch (port) { switch (port) {
case 2: case 2:
if (cmode_port9 == MV88E6XXX_PORT_STS_CMODE_1000BASEX || if (cmode_port9 == MV88E6XXX_PORT_STS_CMODE_1000BASEX ||
cmode_port9 == MV88E6XXX_PORT_STS_CMODE_SGMII || cmode_port9 == MV88E6XXX_PORT_STS_CMODE_SGMII ||
cmode_port9 == MV88E6XXX_PORT_STS_CMODE_2500BASEX) { cmode_port9 == MV88E6XXX_PORT_STS_CMODE_2500BASEX)
if (cmode_port == MV88E6XXX_PORT_STS_CMODE_1000BASEX) { if (cmode_port == MV88E6XXX_PORT_STS_CMODE_1000BASEX)
*lane = MV88E6390_PORT9_LANE1; lane = MV88E6390_PORT9_LANE1;
return 0;
}
}
break; break;
case 3: case 3:
if (cmode_port9 == MV88E6XXX_PORT_STS_CMODE_1000BASEX || if (cmode_port9 == MV88E6XXX_PORT_STS_CMODE_1000BASEX ||
cmode_port9 == MV88E6XXX_PORT_STS_CMODE_SGMII || cmode_port9 == MV88E6XXX_PORT_STS_CMODE_SGMII ||
cmode_port9 == MV88E6XXX_PORT_STS_CMODE_2500BASEX || cmode_port9 == MV88E6XXX_PORT_STS_CMODE_2500BASEX ||
cmode_port9 == MV88E6XXX_PORT_STS_CMODE_RXAUI) { cmode_port9 == MV88E6XXX_PORT_STS_CMODE_RXAUI)
if (cmode_port == MV88E6XXX_PORT_STS_CMODE_1000BASEX) { if (cmode_port == MV88E6XXX_PORT_STS_CMODE_1000BASEX)
*lane = MV88E6390_PORT9_LANE2; lane = MV88E6390_PORT9_LANE2;
return 0;
}
}
break; break;
case 4: case 4:
if (cmode_port9 == MV88E6XXX_PORT_STS_CMODE_1000BASEX || if (cmode_port9 == MV88E6XXX_PORT_STS_CMODE_1000BASEX ||
cmode_port9 == MV88E6XXX_PORT_STS_CMODE_SGMII || cmode_port9 == MV88E6XXX_PORT_STS_CMODE_SGMII ||
cmode_port9 == MV88E6XXX_PORT_STS_CMODE_2500BASEX || cmode_port9 == MV88E6XXX_PORT_STS_CMODE_2500BASEX ||
cmode_port9 == MV88E6XXX_PORT_STS_CMODE_RXAUI) { cmode_port9 == MV88E6XXX_PORT_STS_CMODE_RXAUI)
if (cmode_port == MV88E6XXX_PORT_STS_CMODE_1000BASEX) { if (cmode_port == MV88E6XXX_PORT_STS_CMODE_1000BASEX)
*lane = MV88E6390_PORT9_LANE3; lane = MV88E6390_PORT9_LANE3;
return 0;
}
}
break; break;
case 5: case 5:
if (cmode_port10 == MV88E6XXX_PORT_STS_CMODE_1000BASEX || if (cmode_port10 == MV88E6XXX_PORT_STS_CMODE_1000BASEX ||
cmode_port10 == MV88E6XXX_PORT_STS_CMODE_SGMII || cmode_port10 == MV88E6XXX_PORT_STS_CMODE_SGMII ||
cmode_port10 == MV88E6XXX_PORT_STS_CMODE_2500BASEX) { cmode_port10 == MV88E6XXX_PORT_STS_CMODE_2500BASEX)
if (cmode_port == MV88E6XXX_PORT_STS_CMODE_1000BASEX) { if (cmode_port == MV88E6XXX_PORT_STS_CMODE_1000BASEX)
*lane = MV88E6390_PORT10_LANE1; lane = MV88E6390_PORT10_LANE1;
return 0;
}
}
break; break;
case 6: case 6:
if (cmode_port10 == MV88E6XXX_PORT_STS_CMODE_1000BASEX || if (cmode_port10 == MV88E6XXX_PORT_STS_CMODE_1000BASEX ||
cmode_port10 == MV88E6XXX_PORT_STS_CMODE_SGMII || cmode_port10 == MV88E6XXX_PORT_STS_CMODE_SGMII ||
cmode_port10 == MV88E6XXX_PORT_STS_CMODE_2500BASEX || cmode_port10 == MV88E6XXX_PORT_STS_CMODE_2500BASEX ||
cmode_port10 == MV88E6XXX_PORT_STS_CMODE_RXAUI) { cmode_port10 == MV88E6XXX_PORT_STS_CMODE_RXAUI)
if (cmode_port == MV88E6XXX_PORT_STS_CMODE_1000BASEX) { if (cmode_port == MV88E6XXX_PORT_STS_CMODE_1000BASEX)
*lane = MV88E6390_PORT10_LANE2; lane = MV88E6390_PORT10_LANE2;
return 0;
}
}
break; break;
case 7: case 7:
if (cmode_port10 == MV88E6XXX_PORT_STS_CMODE_1000BASEX || if (cmode_port10 == MV88E6XXX_PORT_STS_CMODE_1000BASEX ||
cmode_port10 == MV88E6XXX_PORT_STS_CMODE_SGMII || cmode_port10 == MV88E6XXX_PORT_STS_CMODE_SGMII ||
cmode_port10 == MV88E6XXX_PORT_STS_CMODE_2500BASEX || cmode_port10 == MV88E6XXX_PORT_STS_CMODE_2500BASEX ||
cmode_port10 == MV88E6XXX_PORT_STS_CMODE_RXAUI) { cmode_port10 == MV88E6XXX_PORT_STS_CMODE_RXAUI)
if (cmode_port == MV88E6XXX_PORT_STS_CMODE_1000BASEX) { if (cmode_port == MV88E6XXX_PORT_STS_CMODE_1000BASEX)
*lane = MV88E6390_PORT10_LANE3; lane = MV88E6390_PORT10_LANE3;
return 0;
}
}
break; break;
case 9: case 9:
if (cmode_port9 == MV88E6XXX_PORT_STS_CMODE_1000BASEX || if (cmode_port9 == MV88E6XXX_PORT_STS_CMODE_1000BASEX ||
cmode_port9 == MV88E6XXX_PORT_STS_CMODE_SGMII || cmode_port9 == MV88E6XXX_PORT_STS_CMODE_SGMII ||
cmode_port9 == MV88E6XXX_PORT_STS_CMODE_2500BASEX || cmode_port9 == MV88E6XXX_PORT_STS_CMODE_2500BASEX ||
cmode_port9 == MV88E6XXX_PORT_STS_CMODE_XAUI || cmode_port9 == MV88E6XXX_PORT_STS_CMODE_XAUI ||
cmode_port9 == MV88E6XXX_PORT_STS_CMODE_RXAUI) { cmode_port9 == MV88E6XXX_PORT_STS_CMODE_RXAUI)
*lane = MV88E6390_PORT9_LANE0; lane = MV88E6390_PORT9_LANE0;
return 0;
}
break; break;
case 10: case 10:
if (cmode_port10 == MV88E6XXX_PORT_STS_CMODE_1000BASEX || if (cmode_port10 == MV88E6XXX_PORT_STS_CMODE_1000BASEX ||
cmode_port10 == MV88E6XXX_PORT_STS_CMODE_SGMII || cmode_port10 == MV88E6XXX_PORT_STS_CMODE_SGMII ||
cmode_port10 == MV88E6XXX_PORT_STS_CMODE_2500BASEX || cmode_port10 == MV88E6XXX_PORT_STS_CMODE_2500BASEX ||
cmode_port10 == MV88E6XXX_PORT_STS_CMODE_XAUI || cmode_port10 == MV88E6XXX_PORT_STS_CMODE_XAUI ||
cmode_port10 == MV88E6XXX_PORT_STS_CMODE_RXAUI) { cmode_port10 == MV88E6XXX_PORT_STS_CMODE_RXAUI)
*lane = MV88E6390_PORT10_LANE0; lane = MV88E6390_PORT10_LANE0;
return 0;
}
break;
default:
break; break;
} }
return -ENODEV; return lane;
} }
/* Set the power on/off for 10GBASE-R and 10GBASE-X4/X2 */ /* 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 cmode = chip->ports[port].cmode;
u8 lane; u8 lane;
int err;
err = mv88e6xxx_serdes_get_lane(chip, port, &lane); lane = mv88e6xxx_serdes_get_lane(chip, port);
if (err) { if (!lane)
if (err == -ENODEV) return 0;
err = 0;
return err;
}
switch (cmode) { switch (cmode) {
case MV88E6XXX_PORT_STS_CMODE_SGMII: 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); mv88e6xxx_reg_lock(chip);
err = mv88e6xxx_serdes_get_lane(chip, port->port, &lane); lane = mv88e6xxx_serdes_get_lane(chip, port->port);
if (err) if (!lane)
goto out; goto out;
switch (cmode) { switch (cmode) {
@ -691,12 +657,9 @@ int mv88e6390_serdes_irq_setup(struct mv88e6xxx_chip *chip, int port)
int err; int err;
u8 lane; u8 lane;
err = mv88e6xxx_serdes_get_lane(chip, port, &lane); lane = mv88e6xxx_serdes_get_lane(chip, port);
if (err) { if (!lane)
if (err == -ENODEV) return 0;
err = 0;
return err;
}
irq = mv88e6xxx_serdes_irq_mapping(chip, port); irq = mv88e6xxx_serdes_irq_mapping(chip, port);
if (!irq) 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) void mv88e6390_serdes_irq_free(struct mv88e6xxx_chip *chip, int port)
{ {
int err;
u8 lane; u8 lane;
err = mv88e6xxx_serdes_get_lane(chip, port, &lane); lane = mv88e6xxx_serdes_get_lane(chip, port);
if (err) { if (!lane)
if (err != -ENODEV)
dev_err(chip->dev, "Unable to free SERDES irq: %d\n",
err);
return; return;
}
mv88e6390_serdes_irq_disable(chip, port, lane); mv88e6390_serdes_irq_disable(chip, port, lane);

View File

@ -74,22 +74,9 @@
#define MV88E6390_SGMII_PHY_STATUS_SPD_DPL_VALID BIT(11) #define MV88E6390_SGMII_PHY_STATUS_SPD_DPL_VALID BIT(11)
#define MV88E6390_SGMII_PHY_STATUS_LINK BIT(10) #define MV88E6390_SGMII_PHY_STATUS_LINK BIT(10)
/* Put the SERDES lane address a port is using into *lane. If a port has u8 mv88e6341_serdes_get_lane(struct mv88e6xxx_chip *chip, int port);
* multiple lanes, should put the first lane the port is using. If a port does u8 mv88e6390_serdes_get_lane(struct mv88e6xxx_chip *chip, int port);
* not have a lane, return -ENODEV. u8 mv88e6390x_serdes_get_lane(struct mv88e6xxx_chip *chip, int port);
*/
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);
unsigned int mv88e6352_serdes_irq_mapping(struct mv88e6xxx_chip *chip, 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,
@ -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); int mv88e6352_serdes_irq_setup(struct mv88e6xxx_chip *chip, int port);
void mv88e6352_serdes_irq_free(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 static inline unsigned int
mv88e6xxx_serdes_irq_mapping(struct mv88e6xxx_chip *chip, int port) mv88e6xxx_serdes_irq_mapping(struct mv88e6xxx_chip *chip, int port)
{ {